Skip to content

Commit 70c34f3

Browse files
authored
Merge pull request #1304 from ably/fix/delta-compression
[ECO-4285] Fix delta compression
2 parents 58dbf02 + 269da8e commit 70c34f3

File tree

8 files changed

+172
-21
lines changed

8 files changed

+172
-21
lines changed

cake-build/helpers/test-execution.cake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public class TestExecutionHelper
106106
public FilePathCollection FindTestAssemblies(string projectRelativePath, string pattern = "IO.Ably.Tests.*.dll")
107107
{
108108
var projectPath = _paths.Src.Combine(projectRelativePath);
109-
var searchPath = projectPath.Combine("bin/Release").FullPath + "/" + pattern;
109+
var searchPath = projectPath.Combine("bin/Release").Combine(pattern).FullPath;
110110
var testAssemblies = _context.GetFiles(searchPath);
111111

112112
if (!testAssemblies.Any())

cake-build/helpers/tools.cake

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ public class ILRepackHelper
3030
var exitCode = _context.StartProcess(ilRepackPath.FullPath, new ProcessSettings
3131
{
3232
Arguments = new ProcessArgumentBuilder()
33-
.Append($"/lib:{sourcePath.FullPath}")
33+
.Append($"/lib:\"{sourcePath.FullPath}\"")
3434
.Append("/targetplatform:v4")
3535
.Append("/internalize")
36-
.Append($"/attr:{targetDll.FullPath}")
37-
.Append($"/keyfile:{rootDir.CombineWithFilePath("IO.Ably.snk").FullPath}")
36+
.Append($"/attr:\"{targetDll.FullPath}\"")
37+
.Append($"/keyfile:\"{rootDir.CombineWithFilePath("IO.Ably.snk").FullPath}\"")
3838
.Append("/parallel")
39-
.Append($"/out:{outputDll.FullPath}")
40-
.Append(targetDll.FullPath)
41-
.Append(jsonNetDll.FullPath)
39+
.Append($"/out:\"{outputDll.FullPath}\"")
40+
.Append($"\"{targetDll.FullPath}\"")
41+
.Append($"\"{jsonNetDll.FullPath}\"")
4242
});
4343

4444
if (exitCode != 0)
@@ -54,6 +54,101 @@ public class ILRepackHelper
5454

5555
_context.Information($"✓ Merged assembly created at {outputDll}");
5656
}
57+
58+
public void MergeDeltaCodec(DirectoryPath sourcePath, DirectoryPath outputPath)
59+
{
60+
var targetDll = outputPath.CombineWithFilePath("IO.Ably.dll");
61+
var docsFile = outputPath.CombineWithFilePath("IO.Ably.xml");
62+
var deltaCodecDll = sourcePath.CombineWithFilePath("IO.Ably.DeltaCodec.dll");
63+
var tempInputDll = outputPath.CombineWithFilePath("IO.Ably.temp.dll");
64+
65+
if (!_context.FileExists(deltaCodecDll))
66+
{
67+
_context.Warning($"DeltaCodec DLL not found at {deltaCodecDll}, skipping merge...");
68+
return;
69+
}
70+
71+
if (!_context.FileExists(targetDll))
72+
{
73+
_context.Warning($"Target DLL not found at {targetDll}, skipping merge...");
74+
return;
75+
}
76+
77+
_context.Information($"Merging {deltaCodecDll.GetFilename()} into {targetDll.GetFilename()}...");
78+
79+
// Get the root directory (parent of cake-build)
80+
var rootDir = _context.MakeAbsolute(_context.Directory("../"));
81+
var ilRepackPath = rootDir.CombineWithFilePath("tools/ilrepack.exe");
82+
83+
// Copy target DLL to temp location to avoid input/output conflict
84+
_context.CopyFile(targetDll, tempInputDll);
85+
86+
// Backup PDB and config files
87+
var targetPdb = outputPath.CombineWithFilePath("IO.Ably.pdb");
88+
var tempInputPdb = outputPath.CombineWithFilePath("IO.Ably.temp.pdb");
89+
if (_context.FileExists(targetPdb))
90+
{
91+
_context.CopyFile(targetPdb, tempInputPdb);
92+
}
93+
94+
var targetConfig = outputPath.CombineWithFilePath("IO.Ably.dll.config");
95+
var tempInputConfig = outputPath.CombineWithFilePath("IO.Ably.temp.dll.config");
96+
if (_context.FileExists(targetConfig))
97+
{
98+
_context.CopyFile(targetConfig, tempInputConfig);
99+
}
100+
101+
try
102+
{
103+
// Merge DeltaCodec into IO.Ably.dll (output directly with correct name)
104+
var exitCode = _context.StartProcess(ilRepackPath.FullPath, new ProcessSettings
105+
{
106+
Arguments = new ProcessArgumentBuilder()
107+
.Append($"/lib:\"{sourcePath.FullPath}\"")
108+
.Append($"/lib:\"{outputPath.FullPath}\"")
109+
.Append("/targetplatform:v4")
110+
.Append("/internalize")
111+
.Append($"/attr:\"{tempInputDll.FullPath}\"")
112+
.Append($"/keyfile:\"{rootDir.CombineWithFilePath("IO.Ably.snk").FullPath}\"")
113+
.Append("/parallel")
114+
.Append($"/out:\"{targetDll.FullPath}\"")
115+
.Append($"\"{tempInputDll.FullPath}\"")
116+
.Append($"\"{deltaCodecDll.FullPath}\"")
117+
});
118+
119+
if (exitCode != 0)
120+
{
121+
throw new Exception($"ILRepack failed with exit code {exitCode}");
122+
}
123+
}
124+
finally
125+
{
126+
// Clean up temp files
127+
if (_context.FileExists(tempInputDll))
128+
{
129+
_context.DeleteFile(tempInputDll);
130+
}
131+
if (_context.FileExists(tempInputPdb))
132+
{
133+
_context.DeleteFile(tempInputPdb);
134+
}
135+
if (_context.FileExists(tempInputConfig))
136+
{
137+
_context.DeleteFile(tempInputConfig);
138+
}
139+
}
140+
141+
// Clean up DeltaCodec files from output path since they're now merged
142+
var deltaCodecFiles = _context.GetFiles(outputPath.Combine("IO.Ably.DeltaCodec.*").FullPath);
143+
144+
foreach (var file in deltaCodecFiles)
145+
{
146+
_context.DeleteFile(file);
147+
_context.Information($"Cleaned up: {file.GetFilename()}");
148+
}
149+
150+
_context.Information($"✓ DeltaCodec merged into {targetDll}");
151+
}
57152
}
58153

59154
var ilRepackHelper = new ILRepackHelper(Context);

cake-build/helpers/utils.cake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void RestoreSolution(FilePath solutionPath)
3636
// On macOS/Linux, use nuget command (installed via mono)
3737
StartProcess("nuget", new ProcessSettings
3838
{
39-
Arguments = $"restore {solutionPath.FullPath} -Verbosity quiet"
39+
Arguments = $"restore \"{solutionPath.FullPath}\" -Verbosity quiet"
4040
});
4141
}
4242
}

cake-build/tasks/package.cake

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Task("_Package_Merge_JsonNet")
5151
}
5252

5353
var binPath = projectPath.Combine("bin/Release");
54-
var packagedPath = binPath.Combine("packaged");
54+
var packagedPath = binPath.Combine("Packaged");
5555

5656
if (!DirectoryExists(binPath))
5757
{
@@ -61,8 +61,8 @@ Task("_Package_Merge_JsonNet")
6161

6262
Information($"Processing {project}...");
6363

64-
// Copy all IO.Ably* files to packaged folder
65-
var ablyFiles = GetFiles(binPath.FullPath + "/IO.Ably*");
64+
// Copy all IO.Ably* files to Packaged folder
65+
var ablyFiles = GetFiles(binPath.Combine("IO.Ably*").FullPath);
6666
EnsureDirectoryExists(packagedPath);
6767
CopyFiles(ablyFiles, packagedPath);
6868

@@ -71,8 +71,46 @@ Task("_Package_Merge_JsonNet")
7171
}
7272
});
7373

74-
Task("_Package_Create_NuGet")
74+
Task("_Package_Merge_DeltaCodec")
7575
.IsDependentOn("_Package_Merge_JsonNet")
76+
.Does(() =>
77+
{
78+
Information("Merging DeltaCodec into Ably assemblies for all platforms...");
79+
80+
// Legacy platforms (already in packaged folder after JsonNet merge)
81+
var legacyProjects = new[]
82+
{
83+
"IO.Ably.Android",
84+
"IO.Ably.iOS",
85+
"IO.Ably.NETFramework"
86+
};
87+
88+
foreach (var project in legacyProjects)
89+
{
90+
var projectPath = paths.Src.Combine(project);
91+
92+
if (!DirectoryExists(projectPath))
93+
{
94+
Warning($"Project directory not found: {project}, skipping...");
95+
continue;
96+
}
97+
98+
var binPath = projectPath.Combine("bin/Release");
99+
var packagedPath = binPath.Combine("Packaged");
100+
101+
if (!DirectoryExists(packagedPath))
102+
{
103+
Warning($"Packaged directory not found for {project}, skipping...");
104+
continue;
105+
}
106+
107+
Information($"Merging DeltaCodec for {project}...");
108+
ilRepackHelper.MergeDeltaCodec(binPath, packagedPath);
109+
}
110+
});
111+
112+
Task("_Package_Create_NuGet")
113+
.IsDependentOn("_Package_Merge_DeltaCodec")
76114
.WithCriteria(() => !string.IsNullOrEmpty(version))
77115
.Does(() =>
78116
{
@@ -196,7 +234,7 @@ Task("_Package_Unity")
196234
Information("Cloning unity-packager repository...");
197235
StartProcess("git", new ProcessSettings
198236
{
199-
Arguments = "clone https://github.com/ably-forks/unity-packager.git -b v1.0.0 unity-packager",
237+
Arguments = $"clone https://github.com/ably-forks/unity-packager.git -b v1.0.0 \"{unityPackagerPath.FullPath}\"",
200238
WorkingDirectory = paths.Root
201239
});
202240
}
@@ -212,8 +250,8 @@ Task("_Package_Unity")
212250
Information("Building Unity package...");
213251
StartProcess("dotnet", new ProcessSettings
214252
{
215-
Arguments = $"run --project {unityPackagerProject.FullPath} " +
216-
$"-project unity -output {outputPath.FullPath} -dir Assets/Ably",
253+
Arguments = $"run --project \"{unityPackagerProject.FullPath}\" " +
254+
$"-project \"{paths.Root.Combine("unity").FullPath}\" -output \"{outputPath.FullPath}\" -dir Assets/Ably",
217255
WorkingDirectory = paths.Root
218256
});
219257

nuget/io.ably.nuspec

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,28 @@
1414
<copyright>©2022 Ably</copyright>
1515
<language />
1616
<dependencies>
17-
<group>
17+
<group targetFramework="net46">
18+
<dependency id="System.Threading.Channels" version="4.6.0" />
19+
</group>
20+
<group targetFramework="monoandroid">
21+
<dependency id="System.Threading.Channels" version="4.6.0" />
22+
</group>
23+
<group targetFramework="Xamarin.iOS">
24+
<dependency id="System.Threading.Channels" version="4.6.0" />
25+
</group>
26+
<group targetFramework="monotouch">
1827
<dependency id="System.Threading.Channels" version="4.6.0" />
1928
</group>
2029
<group targetFramework="netstandard2.0">
30+
<dependency id="System.Threading.Channels" version="4.6.0" />
31+
<dependency id="Newtonsoft.Json" version="9.0.1" />
32+
</group>
33+
<group targetFramework="net6.0">
34+
<dependency id="System.Threading.Channels" version="4.6.0" />
35+
<dependency id="Newtonsoft.Json" version="9.0.1" />
36+
</group>
37+
<group targetFramework="net7.0">
38+
<dependency id="System.Threading.Channels" version="4.6.0" />
2139
<dependency id="Newtonsoft.Json" version="9.0.1" />
2240
</group>
2341
</dependencies>

src/IO.Ably.Shared/Realtime/ChannelMessageProcessor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ public Task<bool> MessageReceived(ProtocolMessage protocolMessage, RealtimeState
9595
break;
9696
case ProtocolMessage.MessageAction.Message:
9797

98-
if (channel.State == ChannelState.Attaching)
98+
if (channel.State != ChannelState.Attached)
9999
{
100100
Logger.Warning(
101-
$"Channel #{channel.Name} is currently in Attaching state. Messages received in this state are ignored. Ignoring ${protocolMessage.Messages?.Length ?? 0} messages");
101+
$"Channel #{channel.Name} is currently in #{channel.State} state. Messages received in this state are ignored. Ignoring {protocolMessage.Messages?.Length ?? 0} messages");
102102
return TaskConstants.BooleanTrue;
103103
}
104104

src/IO.Ably.Tests.Shared/Realtime/DeltaSandboxSpecs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ public async Task WhenDeltaDecodeFail_ShouldSetStateToAttachingLogTheErrorAndDis
227227
{
228228
string channelName = "delta-channel".AddRandomSuffix();
229229
var testSink = new TestLoggerSink();
230-
var taskAwaiter = new TaskCompletionAwaiter(5000);
231-
var firstMessageReceived = new TaskCompletionAwaiter();
230+
var taskAwaiter = new TaskCompletionAwaiter(20000);
231+
var firstMessageReceived = new TaskCompletionAwaiter(20000);
232232
using (((IInternalLogger)Logger).CreateDisposableLoggingContext(testSink))
233233
{
234234
var realtime = await GetRealtimeClient(protocol);

0 commit comments

Comments
 (0)