Skip to content

Commit 2115b33

Browse files
committed
Port Aeron 1.51.0
- Bumped version to 1.51.0; added GIT_SHA to AeronVersion, updated SBE schema to v16 - Ported PersistentSubscription and associated tests, including loss generator tests - Ported Archive integration tests - Added ArchiveEvent, SimpleAuthenticator, SimpleAuthorisationService - Ported Java's async archive client - Added a few more changes from Java that were missing: - Added "{CATEGORY} - " prefix to AeronException messages to match Java format - Misc. other bug fixes: consistent use of same clock when getting timestamps, etc.
1 parent 37d675d commit 2115b33

186 files changed

Lines changed: 10001 additions & 359 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

driver/Aeron.Driver.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package >
33
<metadata>
44
<id>Aeron.Driver</id>
5-
<version>1.49.0</version>
5+
<version>1.51.0</version>
66
<title>Aeron Driver</title>
77
<authors>Adaptive Financial Consulting Ltd.</authors>
88
<owners>Adaptive Financial Consulting Ltd.</owners>
15.7 KB
Binary file not shown.

driver/media-driver.jar

75.7 KB
Binary file not shown.

scripts/update-version.sh

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
#!/bin/sh
2-
BASEDIR=$(readlink -f $(dirname "$0"))
3-
cd $BASEDIR/..
2+
BASEDIR=$(cd "$(dirname "$0")" && pwd)
3+
cd "$BASEDIR/.."
44

55
if [ "$#" -ne 2 ]; then
66
echo "usage: $0 <FROM_VERSION> <TO_VERSION>"
7-
exit -1
7+
exit 1
88
fi
99

1010
FROM_VERSION=$1
1111
TO_VERSION=$2
1212

13-
sed -i s/$FROM_VERSION/$TO_VERSION/ driver/Aeron.Driver.nuspec src/Adaptive.Aeron/Adaptive.Aeron.csproj src/Adaptive.Agrona/Adaptive.Agrona.csproj src/Adaptive.Archiver/Adaptive.Archiver.csproj src/Adaptive.Cluster/Adaptive.Cluster.csproj
13+
FROM_MINOR=$(echo "$FROM_VERSION" | cut -d. -f2)
14+
TO_MINOR=$(echo "$TO_VERSION" | cut -d. -f2)
15+
16+
# GNU sed uses `-i ''` differently than BSD sed; use a portable form via -i.bak then remove backups.
17+
sed -i.bak "s/$FROM_VERSION/$TO_VERSION/g" \
18+
driver/Aeron.Driver.nuspec \
19+
src/Adaptive.Aeron/Adaptive.Aeron.csproj \
20+
src/Adaptive.Agrona/Adaptive.Agrona.csproj \
21+
src/Adaptive.Archiver/Adaptive.Archiver.csproj \
22+
src/Adaptive.Cluster/Adaptive.Cluster.csproj \
23+
src/Adaptive.Aeron/AeronVersion.cs
24+
25+
sed -i.bak "s/MINOR_VERSION = $FROM_MINOR/MINOR_VERSION = $TO_MINOR/g" \
26+
src/Adaptive.Aeron/AeronVersion.cs
27+
28+
find driver src -name '*.bak' -delete

src/Adaptive.Aeron.Tests/SubscriptionTest.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using Adaptive.Aeron.LogBuffer;
1818
using Adaptive.Aeron.Protocol;
19+
using Adaptive.Aeron.Status;
1920
using Adaptive.Agrona.Concurrent;
2021
using Adaptive.Agrona.Concurrent.Status;
2122
using FakeItEasy;
@@ -155,5 +156,51 @@ public void ShouldReadDataFromMultipleSources()
155156

156157
Assert.AreEqual(2, _subscription.Poll(_fragmentHandler, FragmentCountLimit));
157158
}
159+
160+
// Cases where TryResolveChannelEndpointPort short-circuits without reading from the CountersReader.
161+
// These cover the 1.51.0 caching/MDS-manual logic added in Subscription.cs.
162+
// Tests that exercise LocalSocketAddressStatus lookups (active/errored bind addresses) are not
163+
// ported yet — they require a .NET-side Allocate helper that doesn't exist today.
164+
[TestCase("aeron:ipc")]
165+
[TestCase("aeron:udp?control-mode=response|control=localhost:5555")]
166+
[TestCase("aeron:udp?endpoint=localhost:8888")]
167+
[TestCase("aeron:udp?control-mode=manual|endpoint=localhost:0")]
168+
[TestCase("aeron:udp?control-mode=dynamic|control=localhost:7777")]
169+
public void TryResolveChannelEndpointPortReturnsOriginalUriIfEndpointDoesNotNeedResolving(string channel)
170+
{
171+
const int channelStatusId = 777;
172+
_subscription = new Subscription(
173+
_conductor,
174+
channel,
175+
StreamId1,
176+
SubscriptionCorrelationId,
177+
_availableImageHandler,
178+
_unavailableImageHandler
179+
)
180+
{
181+
ChannelStatusId = channelStatusId
182+
};
183+
A.CallTo(() => _conductor.ChannelStatus(channelStatusId)).Returns(ChannelEndpointStatus.ERRORED);
184+
185+
Assert.AreSame(channel, _subscription.TryResolveChannelEndpointPort());
186+
// Subsequent calls return the same cached result.
187+
Assert.AreSame(channel, _subscription.TryResolveChannelEndpointPort());
188+
}
189+
190+
[Test]
191+
public void ShouldAcceptBrokenChannelUriAtCreationTime()
192+
{
193+
const string channel = "broken uri";
194+
_subscription = new Subscription(
195+
_conductor,
196+
channel,
197+
StreamId1,
198+
SubscriptionCorrelationId,
199+
_availableImageHandler,
200+
_unavailableImageHandler
201+
);
202+
203+
Assert.AreEqual(channel, _subscription.Channel);
204+
}
158205
}
159206
}

src/Adaptive.Aeron.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unsealer.Fody", "Weavers\Un
6161
EndProject
6262
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adaptive.Aeron.Analyzers", "Adaptive.Aeron.Analyzers\Adaptive.Aeron.Analyzers.csproj", "{926CB849-94C6-4F3E-8B4F-1DB5157A8782}"
6363
EndProject
64+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adaptive.Archiver.IntegrationTests", "Adaptive.Archiver.IntegrationTests\Adaptive.Archiver.IntegrationTests.csproj", "{93095200-8C85-439B-BB5E-D3440BBBF334}"
65+
EndProject
6466
Global
6567
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6668
Debug|Any CPU = Debug|Any CPU
@@ -457,6 +459,22 @@ Global
457459
{926CB849-94C6-4F3E-8B4F-1DB5157A8782}.Release|x64.Build.0 = Release|Any CPU
458460
{926CB849-94C6-4F3E-8B4F-1DB5157A8782}.Release|x86.ActiveCfg = Release|Any CPU
459461
{926CB849-94C6-4F3E-8B4F-1DB5157A8782}.Release|x86.Build.0 = Release|Any CPU
462+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
463+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|Any CPU.Build.0 = Debug|Any CPU
464+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|arm64.ActiveCfg = Debug|Any CPU
465+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|arm64.Build.0 = Debug|Any CPU
466+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|x64.ActiveCfg = Debug|Any CPU
467+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|x64.Build.0 = Debug|Any CPU
468+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|x86.ActiveCfg = Debug|Any CPU
469+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Debug|x86.Build.0 = Debug|Any CPU
470+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|Any CPU.ActiveCfg = Release|Any CPU
471+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|Any CPU.Build.0 = Release|Any CPU
472+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|arm64.ActiveCfg = Release|Any CPU
473+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|arm64.Build.0 = Release|Any CPU
474+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|x64.ActiveCfg = Release|Any CPU
475+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|x64.Build.0 = Release|Any CPU
476+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|x86.ActiveCfg = Release|Any CPU
477+
{93095200-8C85-439B-BB5E-D3440BBBF334}.Release|x86.Build.0 = Release|Any CPU
460478
EndGlobalSection
461479
GlobalSection(SolutionProperties) = preSolution
462480
HideSolutionNode = FALSE

src/Adaptive.Aeron/Adaptive.Aeron.csproj

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<TargetFramework>netstandard2.0</TargetFramework>
44
<PackageId>Aeron.Client</PackageId>
5-
<VersionPrefix>1.49.0</VersionPrefix>
5+
<VersionPrefix>1.51.0</VersionPrefix>
66
<Authors>Adaptive Financial Consulting Ltd.</Authors>
77
<Company>Adaptive Financial Consulting Ltd.</Company>
88
<Product>Aeron Client</Product>
@@ -49,4 +49,43 @@
4949
<ItemGroup>
5050
<InternalsVisibleTo Include="Adaptive.Aeron.Tests" />
5151
</ItemGroup>
52+
<!--
53+
Capture the current short git SHA into AeronVersion.GIT_SHA, matching the upstream
54+
Java aeron-client's generated AeronVersion.GIT_SHA constant (which is produced by
55+
a Gradle annotation processor). If the working tree is dirty, "+guilty" is
56+
appended. If git is unavailable, the value falls back to "unknown".
57+
-->
58+
<Target Name="GenerateAeronVersionGitSha" BeforeTargets="CoreCompile">
59+
<Exec Command="git rev-parse --short=10 HEAD"
60+
ConsoleToMSBuild="true"
61+
IgnoreExitCode="true"
62+
StandardOutputImportance="Low"
63+
WorkingDirectory="$(MSBuildProjectDirectory)">
64+
<Output TaskParameter="ConsoleOutput" PropertyName="_GitShaRaw" />
65+
<Output TaskParameter="ExitCode" PropertyName="_GitShaExitCode" />
66+
</Exec>
67+
<Exec Command="git status --porcelain"
68+
ConsoleToMSBuild="true"
69+
IgnoreExitCode="true"
70+
StandardOutputImportance="Low"
71+
WorkingDirectory="$(MSBuildProjectDirectory)"
72+
Condition="'$(_GitShaExitCode)' == '0'">
73+
<Output TaskParameter="ConsoleOutput" PropertyName="_GitStatusRaw" />
74+
</Exec>
75+
<PropertyGroup>
76+
<_AeronGitSha Condition="'$(_GitShaExitCode)' == '0' and '$(_GitStatusRaw)' == ''">$(_GitShaRaw)</_AeronGitSha>
77+
<_AeronGitSha Condition="'$(_GitShaExitCode)' == '0' and '$(_GitStatusRaw)' != ''">$(_GitShaRaw)+guilty</_AeronGitSha>
78+
<_AeronGitSha Condition="'$(_GitShaExitCode)' != '0'">unknown</_AeronGitSha>
79+
<_GeneratedGitShaFile>$(IntermediateOutputPath)AeronVersion.GitSha.g.cs</_GeneratedGitShaFile>
80+
</PropertyGroup>
81+
<MakeDir Directories="$(IntermediateOutputPath)" Condition="!Exists('$(IntermediateOutputPath)')" />
82+
<WriteLinesToFile File="$(_GeneratedGitShaFile)"
83+
Lines="// &lt;auto-generated /&gt;%0Anamespace Adaptive.Aeron%0A{%0A public partial class AeronVersion%0A {%0A public static readonly string GIT_SHA = &quot;$(_AeronGitSha)&quot;%3B%0A }%0A}%0A"
84+
Overwrite="true"
85+
WriteOnlyWhenDifferent="true" />
86+
<ItemGroup>
87+
<Compile Include="$(_GeneratedGitShaFile)" />
88+
<FileWrites Include="$(_GeneratedGitShaFile)" />
89+
</ItemGroup>
90+
</Target>
5291
</Project>

src/Adaptive.Aeron/Aeron.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,8 @@ static Context()
11211121
baseDirName = Path.Combine(Path.GetTempPath(), "aeron");
11221122
}
11231123

1124-
AERON_DIR_PROP_DEFAULT = baseDirName + "-" + Environment.UserName;
1124+
var userName = Environment.UserName;
1125+
AERON_DIR_PROP_DEFAULT = baseDirName + "-" + (string.IsNullOrEmpty(userName) ? "default" : userName);
11251126
}
11261127

11271128
/// <summary>
@@ -1487,7 +1488,8 @@ static Context()
14871488
/// <seealso cref="PRINT_CONFIGURATION_ON_START_PROP_NAME"/>
14881489
public static bool ShouldPrintConfigurationOnStart()
14891490
{
1490-
return "true".Equals(Config.GetProperty(PRINT_CONFIGURATION_ON_START_PROP_NAME));
1491+
// Use bool.TryParse for case-insensitive parsing to match Java's parseBoolean.
1492+
return bool.TryParse(Config.GetProperty(PRINT_CONFIGURATION_ON_START_PROP_NAME), out var b) && b;
14911493
}
14921494

14931495
/// <summary>
@@ -1502,7 +1504,7 @@ public static TextWriter FallbackLogger()
15021504
case "stdout":
15031505
return Console.Out;
15041506

1505-
case "noop":
1507+
case "no_op":
15061508
return new StreamWriter(Stream.Null);
15071509

15081510
case "stderr":
@@ -1537,7 +1539,11 @@ public Context ConcludeAeronDirectory()
15371539
{
15381540
if (null == _aeronDirectory)
15391541
{
1540-
_aeronDirectory = new DirectoryInfo(_aeronDirectoryName);
1542+
// Match Java's CommonContext.concludeAeronDirectory() which calls
1543+
// new File(name).getCanonicalFile() — normalises ./.. and resolves to the
1544+
// absolute path. Two processes referencing the same dir via different
1545+
// relative paths must agree on the canonical form to share the CnC file.
1546+
_aeronDirectory = new DirectoryInfo(Path.GetFullPath(_aeronDirectoryName));
15411547
}
15421548

15431549
return this;
@@ -2569,7 +2575,6 @@ public void Dispose()
25692575
_cncMetaDataBuffer?.Dispose();
25702576
_countersMetaDataBuffer?.Dispose();
25712577
_countersValuesBuffer?.Dispose();
2572-
_cncByteBuffer?.Dispose();
25732578
}
25742579

25752580
/// <summary>
@@ -2672,7 +2677,7 @@ private void ConnectToDriver()
26722677
{
26732678
if (clock.Time() > deadlineMs)
26742679
{
2675-
throw new DriverTimeoutException("no driver heartbeat detected.");
2680+
throw new DriverTimeoutException("no driver heartbeat detected");
26762681
}
26772682

26782683
Sleep(Configuration.AWAITING_IDLE_SLEEP_MS);
@@ -2683,7 +2688,7 @@ private void ConnectToDriver()
26832688
{
26842689
if (timeMs > deadlineMs)
26852690
{
2686-
throw new DriverTimeoutException("no driver heartbeat detected.");
2691+
throw new DriverTimeoutException("no driver heartbeat detected");
26872692
}
26882693

26892694
IoUtil.Unmap(_cncByteBuffer);
@@ -2769,7 +2774,7 @@ public MappedByteBuffer MapExistingCncFile(Action<string> logProgress)
27692774
{
27702775
if (null != logProgress)
27712776
{
2772-
logProgress("INFO: Aeron CnC file " + cncFile + "exists");
2777+
logProgress("INFO: Aeron CnC file exists: " + cncFile);
27732778
}
27742779

27752780
return IoUtil.MapExistingFile(cncFile, CncFileDescriptor.CNC_FILE);
@@ -2853,7 +2858,7 @@ MappedByteBuffer cncByteBuffer
28532858
{
28542859
if (UnixTimeConverter.CurrentUnixTimeMillis() > (startTimeMs + driverTimeoutMs))
28552860
{
2856-
throw new DriverTimeoutException("CnC file is created but not initialised.");
2861+
throw new DriverTimeoutException("CnC file is created but not initialised");
28572862
}
28582863

28592864
Sleep(1);
@@ -2866,7 +2871,7 @@ MappedByteBuffer cncByteBuffer
28662871
);
28672872

28682873
long timestampMs = toDriverBuffer.ConsumerHeartbeatTime();
2869-
long nowMs = DateTime.Now.ToFileTimeUtc();
2874+
long nowMs = UnixTimeConverter.CurrentUnixTimeMillis();
28702875
long timestampAgeMs = nowMs - timestampMs;
28712876

28722877
logger("INFO: Aeron toDriver consumer heartbeat age is (ms):" + timestampAgeMs);

0 commit comments

Comments
 (0)