Skip to content

Commit 2f92a5a

Browse files
Merge pull request #5294 from akkadotnet/dev
Akka.NET v1.4.26 Release
2 parents 42061a3 + 46604f0 commit 2f92a5a

File tree

26 files changed

+182
-92
lines changed

26 files changed

+182
-92
lines changed

RELEASE_NOTES.md

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
#### 1.4.26 September 28 2021 ####
2+
**Maintenance Release for Akka.NET 1.4**
3+
Akka.NET v1.4.26 is a very small release that addresses one wire format regression introduced in Akka.NET v1.4.20.
4+
5+
**Bug Fixes and Improvements**
6+
* [Akka.Remote / Akka.Persistence: PrimitiveSerializers manifest backwards compatibility problem](https://github.com/akkadotnet/akka.net/issues/5279) - this could cause regressions when upgrading to Akka.NET v1.4.20 and later. We have resolved this issue in Akka.NET v1.4.26. [Please see our Akka.NET v1.4.26 upgrade advisory for details](https://getakka.net/community/whats-new/akkadotnet-v1.4-upgrade-advisories.html#upgrading-to-akkanet-v1426-from-older-versions).
7+
* [Akka.DistributedData.LightningDb: Revert #5180, switching back to original LightningDB packages](https://github.com/akkadotnet/akka.net/pull/5286)
8+
9+
You can [see the full set of changes introduced in Akka.NET v1.4.26 here](https://github.com/akkadotnet/akka.net/milestone/57?closed=1)
10+
11+
| COMMITS | LOC+ | LOC- | AUTHOR |
12+
| --- | --- | --- | --- |
13+
| 4 | 99 | 96 | Gregorius Soedharmo |
14+
| 3 | 79 | 5 | Aaron Stannard |
15+
| 1 | 1 | 1 | dependabot[bot] |
16+
117
#### 1.4.25 September 08 2021 ####
218
**Maintenance Release for Akka.NET 1.4**
319
Akka.NET v1.4.25 includes some _significant_ performance improvements for Akka.Remote and a number of important bug fixes and improvements.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
uid: akkadotnet-v14-upgrade-advisories
3+
title: Akka.NET v1.4 Upgrade Advisories
4+
---
5+
6+
# Akka.NET v1.4 Upgrade Advisories
7+
This document contains specific upgrade suggestions, warnings, and notices that you will want to pay attention to when upgrading between versions within the Akka.NET v1.4 roadmap.
8+
9+
## Upgrading to Akka.NET v1.4.20 from Older Versions
10+
11+
> [!NOTE]
12+
> This is an edge-case issue that only affects users who are sending primitive data types (i.e. `int`, `long`, `string`) directly over Akka.Remote or Akka.Persistence.
13+
14+
Between Akka.NET v1.4.19 and [v1.4.20](https://github.com/akkadotnet/akka.net/releases/tag/1.4.20) we introduced a regression in the wire format of the "primitive" serializer in Akka.NET v1.4.20 - the serializer responsible for transmitting `int`, `long`, and `string` as stand-alone messages in Akka.Remote and Akka.Persistence.
15+
16+
The error message would look like this in clusters that are running a combination of v1.4.20 and any previous versions of Akka.NET:
17+
18+
> `Serializer not defined for message with serializer id [6] and manifest []. Transient association error (association remains live). Cannot find manifest class [S] for serializer with id [17].`
19+
20+
You can see the PR that introduced this regression here: https://github.com/akkadotnet/akka.net/issues/4986
21+
22+
This change was originally introduced to assist with cross-platform wire compatibility between .NET Framework and .NET Core, because Microsoft changed the names of all primitive types between the two runtimes when .NET Core was originally introduced.
23+
24+
**Workarounds**:
25+
26+
To work around this issue, if you're affected by it (most users are not:)
27+
28+
* Upgrade all of the nodes to v1.4.20 or later at once;
29+
* Or upgrade directly to Akka.NET v1.4.26 or later, which resolves this issue and prevents the regression from occurring.
30+
31+
## Upgrading to Akka.NET v1.4.26 from Older Versions
32+
33+
> [!NOTE]
34+
> This is an edge-case issue that only affects users who are sending primitive data types (i.e. `int`, `long`, `string`) directly over Akka.Remote or Akka.Persistence.
35+
36+
In Akka.NET v1.4.26 we have introduced a new setting:
37+
38+
```
39+
akka.actor.serialization-settings.primitive.use-legacy-behavior = on
40+
```
41+
42+
This setting is set of `on` by default and it resolves the backwards compatibility issue introduced in the "primitives" serializer described in our [v1.4.20 upgrade advisory](#upgrading-to-akkanet-v1420-from-older-versions).
43+
44+
> [!IMPORTANT]
45+
> If you have:
46+
> * Previously upgraded to Akka.NET v1.4.20+ and you have not run into any issues;
47+
> * You have not yet upgraded to Akka.NET v1.4.20+; and
48+
> * You _do not_ plan on running both .NET Framework and .NET Core in the same cluster
49+
> Then you can safely upgrade to v1.4.26 using your normal deployment process.
50+
51+
If you are running a mixed .NET Core and .NET Framework cluster, see the process below.
52+
53+
### Deploying v1.4.26 into Mixed .NET Core and .NET Framework Environments
54+
*However*, if you are attempting to run a mixed-mode cluster - i.e. some services running on .NET Framework and some running on .NET Core, you will eventually want to turn this setting to `off` in order to faciliate smooth operation between both platforms.
55+
56+
#### Already Deployed v1.4.20 or Later
57+
If you've already deployed v1.4.20 and you have not had any issues with the primitives serializer, do the following:
58+
59+
1. Before you upgrade to v1.4.26 or later set `akka.actor.serialization-settings.primitive.use-legacy-behavior = off` - so any future serialization of primitives will be handled correctly in a cross-platform way;
60+
2. Run your normal deployment process.
61+
62+
#### Have Not Deployed v1.4.20 or Later
63+
If you have not previously deployed to v1.4.20 or later, then do the following:
64+
65+
1. Deploy once with `akka.actor.serialization-settings.primitive.use-legacy-behavior = on` (the default);
66+
2. Once all nodes are completely upgraded to v1.4.26 and later, prepare a second deployment with `akka.actor.serialization-settings.primitive.use-legacy-behavior = off`;
67+
3. Complete the second deployment - you will be fine with all rolling upgrades moving forward.

docs/community/whats-new/toc.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
- name: New in Akka.NET v1.4
2-
href: akkadotnet-v1.4.md
2+
href: akkadotnet-v1.4.md
3+
- name: Upgrade Advisories (v1.4)
4+
href: akkadotnet-v1.4-upgrade-advisories.md

src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/Akka.Cluster.Sharding.Tests.MultiNode.csproj

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="..\..\..\common.props" />
33

4-
<!-- Needed to resolve https://github.com/akkadotnet/akka.net/pull/5180 and https://github.com/akkadotnet/akka.net/issues/5174 -->
5-
<Import Project="../lib-hack/LightningDB.targets" />
6-
74
<PropertyGroup>
85
<AssemblyTitle>Akka.Cluster.Sharding.Tests.MultiNode</AssemblyTitle>
96
<TargetFrameworks>$(NetFrameworkTestVersion);$(NetTestVersion);$(NetCoreTestVersion)</TargetFrameworks>

src/contrib/cluster/Akka.DistributedData.LightningDB/Akka.DistributedData.LightningDB.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<PropertyGroup>
55
<AssemblyTitle>Akka.DistributedData.LightningDB</AssemblyTitle>
66
<Description>Replicated data using CRDT structures</Description>
7-
<TargetFrameworks>$(NetStandardLibVersion)</TargetFrameworks>
7+
<TargetFramework>$(NetStandardLibVersion)</TargetFramework>
88
<PackageTags>$(AkkaPackageTags);network;cluster;crdt;replication;lightningdb;lmdb</PackageTags>
99
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1010
</PropertyGroup>
@@ -15,7 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="LightningDB.Vendored.Akka" Version="0.14.0" />
18+
<PackageReference Include="LightningDB" Version="0.14.0" />
1919
</ItemGroup>
2020

2121
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

src/contrib/cluster/Akka.DistributedData.Tests.MultiNode/Akka.DistributedData.Tests.MultiNode.csproj

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="..\..\..\common.props" />
33

4-
<!-- Needed to resolve https://github.com/akkadotnet/akka.net/pull/5180 and https://github.com/akkadotnet/akka.net/issues/5174 -->
5-
<Import Project="../lib-hack/LightningDB.targets" />
6-
74
<PropertyGroup>
85
<AssemblyTitle>Akka.DistributedData.Tests.MultiNode</AssemblyTitle>
96
<TargetFrameworks>$(NetFrameworkTestVersion);$(NetTestVersion);$(NetCoreTestVersion)</TargetFrameworks>

src/contrib/cluster/lib-hack/LightningDB.targets

-59
This file was deleted.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

src/contrib/persistence/Akka.Persistence.Sqlite/Akka.Persistence.Sqlite.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</ItemGroup>
1717

1818
<ItemGroup>
19-
<PackageReference Include="Microsoft.Data.SQLite" Version="5.0.9" />
19+
<PackageReference Include="Microsoft.Data.SQLite" Version="5.0.10" />
2020
</ItemGroup>
2121

2222
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

src/core/Akka.API.Tests/CoreAPISpec.ApproveRemote.approved.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ namespace Akka.Remote.Serialization
440440
}
441441
public sealed class PrimitiveSerializers : Akka.Serialization.SerializerWithStringManifest
442442
{
443-
public PrimitiveSerializers(Akka.Actor.ExtendedActorSystem system) { }
443+
public PrimitiveSerializers(Akka.Actor.ExtendedActorSystem system, Akka.Configuration.Config config) { }
444444
public override object FromBinary(byte[] bytes, string manifest) { }
445445
public override string Manifest(object obj) { }
446446
public override byte[] ToBinary(object obj) { }

src/core/Akka.MultiNodeTestRunner.Shared.Tests/MultiNodeTestRunnerDiscovery/DiscoverySpec.cs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using System.Linq;
1111
using System.Reflection;
12+
using Akka.Remote.TestKit;
1213
using Akka.TestKit;
1314
using Xunit;
1415
using FluentAssertions;
@@ -62,6 +63,7 @@ public void Only_MultiNodeConfig_role_count_used()
6263

6364
private static Dictionary<string, List<NodeTest>> DiscoverSpecs()
6465
{
66+
Environment.SetEnvironmentVariable(MultiNodeFactAttribute.MultiNodeTestEnvironmentName, "1");
6567
using (var controller = new XunitFrontController(AppDomainSupport.IfAvailable, new System.Uri(typeof(DiscoveryCases).GetTypeInfo().Assembly.CodeBase).LocalPath))
6668
{
6769
using (var discovery = new Discovery())

src/core/Akka.MultiNodeTestRunner/Program.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ class Program
135135
/// </summary>
136136
static void Main(string[] args)
137137
{
138-
// Force load the args
139-
CommandLine.GetPropertyOrDefault("force load", null);
138+
CommandLine.Initialize(args);
139+
140140
if (CommandLine.ShowHelp)
141141
{
142142
PrintHelp();
@@ -242,6 +242,7 @@ static void Main(string[] args)
242242
}
243243
#endif
244244

245+
Environment.SetEnvironmentVariable(MultiNodeFactAttribute.MultiNodeTestEnvironmentName, "1");
245246
using (var controller = new XunitFrontController(AppDomainSupport.IfAvailable, assemblyPath))
246247
{
247248
using (var discovery = new Discovery())

src/core/Akka.NodeTestRunner/Program.cs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class Program
3636

3737
static int Main(string[] args)
3838
{
39+
CommandLine.Initialize(args);
40+
3941
var nodeIndex = CommandLine.GetInt32("multinode.index");
4042
var nodeRole = CommandLine.GetProperty("multinode.role");
4143
var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
@@ -64,6 +66,7 @@ static int Main(string[] args)
6466
#endif
6567

6668
Thread.Sleep(TimeSpan.FromSeconds(10));
69+
Environment.SetEnvironmentVariable(MultiNodeFactAttribute.MultiNodeTestEnvironmentName, "1");
6770
using (var controller = new XunitFrontController(AppDomainSupport.IfAvailable, assemblyFileName))
6871
{
6972
/* need to pass in just the assembly name to Discovery, not the full path

src/core/Akka.Remote.TestKit/CommandLine.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,19 @@ namespace Akka.Remote.TestKit
2626
/// var testName = CommandLine.GetProperty("multinode.test-method");
2727
/// </code>
2828
/// </summary>
29-
public class CommandLine
29+
public static class CommandLine
3030
{
31-
private static readonly StringDictionary Values;
31+
private static readonly StringDictionary Values = new StringDictionary();
3232

3333
static CommandLine()
3434
{
35-
Values = new StringDictionary();
35+
Initialize(Environment.GetCommandLineArgs());
36+
}
3637

38+
public static void Initialize(string[] args)
39+
{
3740
// Detect and fix PowerShell command line input.
3841
// PowerShell splits command line arguments on '.'
39-
var args = Environment.GetCommandLineArgs();
4042
var fixedArgs = new List<string>();
4143
for (var i = 1; i < args.Length - 1; ++i)
4244
{
@@ -71,7 +73,7 @@ static CommandLine()
7173

7274
if (tokens.Length == 2)
7375
{
74-
Values.Add(tokens[0], tokens[1]);
76+
Values[tokens[0]] = tokens[1].Trim().Trim('"');
7577
}
7678
else
7779
{

src/core/Akka.Remote.TestKit/MultiNodeFact.cs

+6-12
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,17 @@ public class MultiNodeFactAttribute : FactAttribute
1616
/// Set by MultiNodeTestRunner when running multi-node tests
1717
/// </summary>
1818
public const string MultiNodeTestEnvironmentName = "__AKKA_MULTI_NODE_ENVIRONMENT";
19-
20-
public static Lazy<bool> ExecutedByMultiNodeRunner =
21-
new Lazy<bool>(() =>
22-
{
23-
var args = Environment.GetCommandLineArgs();
24-
if (args.Length == 0) return false;
25-
var firstArg = args[0];
26-
return firstArg.Contains("Akka.MultiNodeTestRunner")
27-
|| firstArg.Contains("Akka.NodeTestRunner")
28-
|| Environment.GetEnvironmentVariable(MultiNodeTestEnvironmentName) != null;
29-
});
19+
20+
private bool? _executedByMultiNodeRunner;
3021

3122
public override string Skip
3223
{
3324
get
3425
{
35-
return ExecutedByMultiNodeRunner.Value
26+
if (_executedByMultiNodeRunner == null)
27+
_executedByMultiNodeRunner =
28+
Environment.GetEnvironmentVariable(MultiNodeTestEnvironmentName) != null;
29+
return _executedByMultiNodeRunner != null && _executedByMultiNodeRunner.Value
3630
? base.Skip
3731
: "Must be executed by multi-node test runner";
3832
}

src/core/Akka.Remote.Tests/RemoteConfigSpec.cs

+8
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ public void Remoting_should_contain_correct_BatchWriter_settings_in_ReferenceCon
176176
s.BatchWriterSettings.EnableBatching.Should().BeTrue();
177177
s.BatchWriterSettings.MaxExplicitFlushes.Should().Be(BatchWriterSettings.DefaultMaxPendingWrites);
178178
}
179+
180+
[Fact]
181+
public void Remoting_should_contain_correct_PrimitiveSerializer_settings_in_ReferenceConf()
182+
{
183+
var c = RARP.For(Sys).Provider.RemoteSettings.Config.GetConfig("akka.actor.serialization-settings.primitive");
184+
c.Should().NotBeNull();
185+
c.GetBoolean("use-legacy-behavior").Should().BeTrue();
186+
}
179187
}
180188
}
181189

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// //-----------------------------------------------------------------------
2+
// // <copyright file="BugFix5279Spec.cs" company="Akka.NET Project">
3+
// // Copyright (C) 2009-2021 Lightbend Inc. <http://www.lightbend.com>
4+
// // Copyright (C) 2013-2021 .NET Foundation <https://github.com/akkadotnet/akka.net>
5+
// // </copyright>
6+
// //-----------------------------------------------------------------------
7+
8+
using Akka.Actor;
9+
using Akka.Configuration;
10+
using Akka.Remote.Serialization;
11+
using Akka.TestKit;
12+
using Akka.Util;
13+
using Xunit;
14+
using FluentAssertions;
15+
16+
namespace Akka.Remote.Tests.Serialization
17+
{
18+
public class BugFix5279Spec: AkkaSpec
19+
{
20+
[Theory]
21+
[InlineData(1, "I")]
22+
[InlineData(1L, "L")]
23+
[InlineData("1", "S")]
24+
public void PrimitiveSerializer_without_useNeutralPrimitives_should_return_custom_manifest(object data, string manifest)
25+
{
26+
var config = ConfigurationFactory.ParseString("use-legacy-behavior = off");
27+
var serializer = new PrimitiveSerializers((ExtendedActorSystem)Sys, config);
28+
serializer.Manifest(data).Should().Be(manifest);
29+
}
30+
31+
[Theory]
32+
[InlineData(1)]
33+
[InlineData(1L)]
34+
[InlineData("1")]
35+
public void PrimitiveSerializer_without_useNeutralPrimitives_should_return_type_manifest(object data)
36+
{
37+
var config = ConfigurationFactory.ParseString("use-legacy-behavior = on");
38+
var serializer = new PrimitiveSerializers((ExtendedActorSystem)Sys, config);
39+
serializer.Manifest(data).Should().Be(data.GetType().TypeQualifiedName());
40+
}
41+
42+
}
43+
}

0 commit comments

Comments
 (0)