Repository navigation
AOT: module serializer tables for the Cluster contrib family (#8626, part 3b) - #8669
Merged
Aaronontheweb merged 5 commits intoSep 30, 2026
Conversation
…net#8626, part 3b) Adds ToolsSerializers (Akka.Cluster.Tools, covering all three of Client, PublishSubscribe and Singleton), ShardingSerializers (Akka.Cluster.Sharding), DistributedDataSerializers (Akka.DistributedData) and MetricsSerializers (Akka.Cluster.Metrics) to core's module map. Every serializer in these four modules has a single (system) constructor and no serialization-settings block in its shipped config, so each factory calls that constructor directly. Akka.Cluster.Metrics gets a new InternalsVisibleTo grant from Akka core, needed for its table to subclass the internal ModuleSerializers; the API approval snapshots are updated to match. Akka.Cluster.Tools.Tests and Akka.DistributedData.Tests have no InternalsVisibleTo grant from Akka core, so their specs skip the reflection-only baseline and keep a hand-written mirror of each table's serializer-type list instead of reading it live.
…im reflection baselines
- Grant Akka core InternalsVisibleTo to Akka.Cluster.Tools.Tests and
Akka.DistributedData.Tests so their specs can see the internal
ModuleSerializer record and Serialization.GetSerializerById. Update
both CoreAPISpec.ApproveCore.{DotNet,Net}.verified.txt.
- ToolsSerializersSpec and DistributedDataSerializersSpec now feed the
real table (table.Serializers.Select(s => s.Type)) into the parity
helper instead of a hand-kept mirror list, and check wire ids (15, 9,
14, 11, 12) the way the other specs do. Verified with a mutation: an
extra bogus serializer row in either table fails the parity check,
then reverted.
- Drop the reflection-only baseline from ShardingSerializersSpec and
MetricsSerializersSpec, and their now-unused Build/NoModules/
SwitchName helpers; the switch-off id test already covers these
single-constructor, settings-free factories.
- Remove the redundant Akka.Tests.Shared.Internals.Xunit3
ProjectReference from Akka.Cluster.Metrics.Tests.csproj; it already
arrives transitively through Akka.Cluster.Tests.
- Ledger: drop the InternalsVisibleTo aside (not breaking) and the
unmeasured versioned-name claim from the row.
…cluster-contrib-serializers # Conflicts: # BREAKING_CHANGES_V1.6.md # src/core/Akka/Serialization/ModuleSerializers.cs
…1.6.md edit (batch PR will update the ledger)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 3b of #8626. Follows #8658 and part 3a (#8666)'s module-table pattern for the four Cluster contrib modules: Tools, Sharding, DistributedData and Metrics. Split from 3a to keep each PR reviewable.
Note: this PR and #8666 both add lines to
ModuleSerializerTable.Default's map insrc/core/Akka/Serialization/ModuleSerializers.cs. They'll conflict trivially on merge -- whichever lands second just needs to keep both sets of map entries.Changes
ToolsSerializers(Akka.Cluster.Tools) covers all three of Tools' reference.conf files in one table:ClusterClientMessageSerializer(Client, id 15),DistributedPubSubMessageSerializer(PublishSubscribe, id 9),ClusterSingletonMessageSerializer(Singleton, id 14). It lives at the topAkka.Cluster.Toolsnamespace, not under a feature's ownSerializationsub-namespace, since it spans all three.ShardingSerializers(Akka.Cluster.Sharding.Serialization) coversClusterShardingMessageSerializer(id 13).DistributedDataSerializers(Akka.DistributedData.Serialization) coversReplicatedDataSerializer(id 11) andReplicatorMessageSerializer(id 12).MetricsSerializers(Akka.Cluster.Metrics.Serialization) coversClusterMetricsMessageSerializer(id 10) and its five bound types."Akka.Cluster.Tools","Akka.Cluster.Sharding","Akka.DistributedData","Akka.Cluster.Metrics", each passing a type-name literal toLoad.Constructor choices
All seven serializers here have exactly one constructor, and none of the four modules' shipped configs has a
serialization-settingsblock for any of these aliases, so every factory calls the class's only constructor directly:akka-cluster-client(system)akka-pubsub(system)akka-singleton(system)akka-sharding(system)akka-replicated-data(system)akka-data-replication(system)akka-cluster-metrics(system)IVT
Akka core did not grant
Akka.Cluster.Metricsaccess to its internals (every other module in this family already had it), and the table must subclass the internalModuleSerializers, sosrc/core/Akka/Properties/AssemblyInfo.csgets one newInternalsVisibleTo("Akka.Cluster.Metrics").CoreAPISpec.ApproveCore.{DotNet,Net}.verified.txtare updated to match (one line each). No other IVT changes -- Tools, Sharding and DistributedData already had core access, as did their ownTestsprojects; Tools' own assembly already grants itsTestsproject access toToolsSerializers, and likewise for Sharding/DistributedData/Metrics.Behavior with the switch on (recorded in this PR's Breaking changes section below)
Same shape as #8658 and 3a, measured against these four modules:
serialization-settings.<alias>block for any of these seven serializers now builds it instead of throwingMissingMethodException.TargetInvocationException.ConfigurationException.Tests
One short spec per module, each in a
DynamicTypeLoadingCollection(non-parallel), reusingModuleSerializerSpecs(Akka.Tests.Shared.Internals.Xunit3):InternalsVisibleTogrant from Akka core, so these specs are the full shape -- table-matches-config (both directions), Akka.Hosting AQN spelling, an application.conf override, a reflection-only baseline (needs the internalModuleSerializerTableconstructor), and switch-off ids/classes.Serialization.GetSerializerByIdis internal too, so these two specs check bound types by class via the publicFindSerializerForTypeinstead of by wire id, and keep a hand-written mirror of each table's serializer-type list (SerializerTypes) rather than readingtable.Serializerslive, since the internalModuleSerializerrecord itself isn't visible without that grant. Both still exercise the real production table throughAssertBuildsWithoutWarning, which builds an actualSerializationfrom the default module map.Akka.Tests.Shared.Internals.Xunit3already except Akka.Cluster.Metrics.Tests, which gets thatProjectReferenceadded.Mutation check (reverted before this PR)
Removing
ClusterSingletonMessageSerializerfromToolsSerializers.Serializersfails 3 ofToolsSerializersSpec's 4 facts (the AQN check and the switch-off build/class checks -- constructingSerializationfor that config now throwsConfigurationExceptionfor theakka-singletonalias).Validation
dotnet build -c Release -warnaserror: Akka, Akka.Cluster.Tools, Akka.Cluster.Sharding, Akka.DistributedData, Akka.Cluster.Metrics, and their four test projects -- 0 warnings.dotnet test src/core/Akka.Tests -c Release -f net10.0 --filter "FullyQualifiedName~Serialization": 128 passed.Akka.API.Tests: 23 passed, with the two verified-file updates above.Breaking changes
Akka.Cluster.Tools/Akka.Cluster.Sharding/Akka.DistributedData/Akka.Cluster.Metrics(serialization)ClusterClientMessageSerializer,DistributedPubSubMessageSerializer,ClusterSingletonMessageSerializeracross its three feature configs; Sharding:ClusterShardingMessageSerializer; DistributedData:ReplicatedDataSerializer,ReplicatorMessageSerializer; Metrics:ClusterMetricsMessageSerializer) are now built from an internal module table ahead of reflection, withAkka.DynamicTypeLoadingon as well as off. Every one of these seven classes has a single(system)constructor and noserialization-settingsblock in its shipped config, so each factory calls that constructor directly. With the switch on, two things differ: (1) aserialization-settings.<alias>block for any of these seven serializers now builds it instead of throwingMissingMethodException; (2) an exception from one of these constructors is no longer wrapped inTargetInvocationException. With the switch off, every row here now resolves instead of throwingConfigurationException. Same mechanism as #8658.MissingMethodExceptionorTargetInvocationExceptionaroundActorSystem.Createfor these serializers should catch the inner exception type instead.(The shared
BREAKING_CHANGES_V1.6.mdledger itself is not touched by this PR -- it is updated in a separate batch PR.)