diff --git a/src/contrib/cluster/Akka.Cluster.Sharding/Shard.cs b/src/contrib/cluster/Akka.Cluster.Sharding/Shard.cs index 44611eb2a3a..352866a505d 100644 --- a/src/contrib/cluster/Akka.Cluster.Sharding/Shard.cs +++ b/src/contrib/cluster/Akka.Cluster.Sharding/Shard.cs @@ -10,6 +10,7 @@ using System.Collections.Immutable; using System.Linq; using Akka.Actor; +using Akka.Annotations; using Akka.Cluster.Sharding.Internal; using Akka.Coordination; using Akka.Event; @@ -23,6 +24,13 @@ namespace Akka.Cluster.Sharding using EntityId = String; using ShardId = String; + /// + /// INTERNAL API + /// + /// This actor creates children entity actors on demand that it is told to be + /// responsible for. + /// + [InternalStableApi] internal sealed class Shard : ActorBase, IWithTimers, IWithUnboundedStash { #region messages diff --git a/src/contrib/cluster/Akka.Cluster.Sharding/ShardRegion.cs b/src/contrib/cluster/Akka.Cluster.Sharding/ShardRegion.cs index 9540cf03e45..a0b3bc2f255 100644 --- a/src/contrib/cluster/Akka.Cluster.Sharding/ShardRegion.cs +++ b/src/contrib/cluster/Akka.Cluster.Sharding/ShardRegion.cs @@ -11,12 +11,12 @@ using System.Linq; using System.Threading.Tasks; using Akka.Actor; +using Akka.Annotations; using Akka.Cluster.Sharding.Internal; using Akka.Event; using Akka.Pattern; using Akka.Util; using Akka.Util.Internal; -using Get = Akka.DistributedData.Get; namespace Akka.Cluster.Sharding { @@ -25,11 +25,14 @@ namespace Akka.Cluster.Sharding using ShardId = String; /// + /// INTERNAL API + /// /// This actor creates children shard actors on demand that it is told to be responsible for. /// The shard actors in turn create entity actors on demand. /// It delegates messages targeted to other shards to the responsible /// actor on other nodes. /// + [InternalStableApi] public sealed class ShardRegion : ActorBase, IWithTimers { #region messages diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.DotNet.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.DotNet.verified.txt index aedc47946f3..19325ac0b86 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.DotNet.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.DotNet.verified.txt @@ -200,6 +200,7 @@ namespace Akka.Cluster.Sharding { public static Akka.Cluster.Sharding.IShardAllocationStrategy LeastShardAllocationStrategy(int absoluteLimit, double relativeLimit) { } } + [Akka.Annotations.InternalStableApiAttribute()] public sealed class ShardRegion : Akka.Actor.ActorBase, Akka.Actor.IWithTimers { public ShardRegion(string typeName, System.Func entityProps, Akka.Cluster.Sharding.ClusterShardingSettings settings, string coordinatorPath, Akka.Cluster.Sharding.ExtractEntityId extractEntityId, Akka.Cluster.Sharding.ExtractShardId extractShardId, object handOffStopMessage, Akka.Cluster.Sharding.Internal.IRememberEntitiesProvider rememberEntitiesProvider) { } diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.Net.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.Net.verified.txt index 8f4f60322f5..133e6d1a3aa 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.Net.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveClusterSharding.Net.verified.txt @@ -200,6 +200,7 @@ namespace Akka.Cluster.Sharding { public static Akka.Cluster.Sharding.IShardAllocationStrategy LeastShardAllocationStrategy(int absoluteLimit, double relativeLimit) { } } + [Akka.Annotations.InternalStableApiAttribute()] public sealed class ShardRegion : Akka.Actor.ActorBase, Akka.Actor.IWithTimers { public ShardRegion(string typeName, System.Func entityProps, Akka.Cluster.Sharding.ClusterShardingSettings settings, string coordinatorPath, Akka.Cluster.Sharding.ExtractEntityId extractEntityId, Akka.Cluster.Sharding.ExtractShardId extractShardId, object handOffStopMessage, Akka.Cluster.Sharding.Internal.IRememberEntitiesProvider rememberEntitiesProvider) { } diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt index cfc5130e2be..6f64e6b7071 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt @@ -2197,6 +2197,11 @@ namespace Akka.Annotations { public InternalApiAttribute() { } } + [System.AttributeUsageAttribute(System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.All, AllowMultiple=false, Inherited=true)] + public sealed class InternalStableApiAttribute : System.Attribute + { + public InternalStableApiAttribute() { } + } } namespace Akka.Configuration { @@ -3204,7 +3209,7 @@ namespace Akka.Dispatch.SysMsg public Suspend() { } public override string ToString() { } } - [Akka.Annotations.InternalApiAttribute()] + [Akka.Annotations.InternalStableApiAttribute()] public abstract class SystemMessage : Akka.Actor.INoSerializationVerificationNeeded, Akka.Dispatch.SysMsg.ISystemMessage { protected SystemMessage() { } @@ -5342,6 +5347,7 @@ namespace Akka.Util public static int StringHash(string s) { } public static int SymmetricHash(System.Collections.Generic.IEnumerable xs, uint seed) { } } + [Akka.Annotations.InternalStableApiAttribute()] [System.Runtime.CompilerServices.IsReadOnlyAttribute()] public struct Option { diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt index fb317ce392f..bddbd49935b 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt @@ -2195,6 +2195,11 @@ namespace Akka.Annotations { public InternalApiAttribute() { } } + [System.AttributeUsageAttribute(System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.All, AllowMultiple=false, Inherited=true)] + public sealed class InternalStableApiAttribute : System.Attribute + { + public InternalStableApiAttribute() { } + } } namespace Akka.Configuration { @@ -3196,7 +3201,7 @@ namespace Akka.Dispatch.SysMsg public Suspend() { } public override string ToString() { } } - [Akka.Annotations.InternalApiAttribute()] + [Akka.Annotations.InternalStableApiAttribute()] public abstract class SystemMessage : Akka.Actor.INoSerializationVerificationNeeded, Akka.Dispatch.SysMsg.ISystemMessage { protected SystemMessage() { } @@ -5332,6 +5337,7 @@ namespace Akka.Util public static int StringHash(string s) { } public static int SymmetricHash(System.Collections.Generic.IEnumerable xs, uint seed) { } } + [Akka.Annotations.InternalStableApiAttribute()] public struct Option { public static readonly Akka.Util.Option None; diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.DotNet.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.DotNet.verified.txt index 3b781e905ca..e231291dc65 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.DotNet.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.DotNet.verified.txt @@ -377,8 +377,10 @@ namespace Akka.Persistence public Akka.Persistence.IStashOverflowStrategy DefaultInternalStashOverflowStrategy { get; } public Akka.Persistence.PersistenceSettings Settings { get; } public Akka.Persistence.Journal.EventAdapters AdaptersFor(string journalPluginId) { } + [Akka.Annotations.InternalStableApiAttribute()] public Akka.Actor.IActorRef JournalFor(string journalPluginId) { } public string PersistenceId(Akka.Actor.IActorRef actor) { } + [Akka.Annotations.InternalStableApiAttribute()] public Akka.Actor.IActorRef SnapshotStoreFor(string snapshotPluginId) { } } public sealed class PersistenceSettings : Akka.Actor.Settings diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.Net.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.Net.verified.txt index 6b52d35037c..4708abc85da 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.Net.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApprovePersistence.Net.verified.txt @@ -377,8 +377,10 @@ namespace Akka.Persistence public Akka.Persistence.IStashOverflowStrategy DefaultInternalStashOverflowStrategy { get; } public Akka.Persistence.PersistenceSettings Settings { get; } public Akka.Persistence.Journal.EventAdapters AdaptersFor(string journalPluginId) { } + [Akka.Annotations.InternalStableApiAttribute()] public Akka.Actor.IActorRef JournalFor(string journalPluginId) { } public string PersistenceId(Akka.Actor.IActorRef actor) { } + [Akka.Annotations.InternalStableApiAttribute()] public Akka.Actor.IActorRef SnapshotStoreFor(string snapshotPluginId) { } } public sealed class PersistenceSettings : Akka.Actor.Settings diff --git a/src/core/Akka.Persistence/Persistence.cs b/src/core/Akka.Persistence/Persistence.cs index 204fd982365..1100b5d0f79 100644 --- a/src/core/Akka.Persistence/Persistence.cs +++ b/src/core/Akka.Persistence/Persistence.cs @@ -11,6 +11,7 @@ using System.Reflection; using System.Threading; using Akka.Actor; +using Akka.Annotations; using Akka.Configuration; using Akka.Event; using Akka.Persistence.Journal; @@ -231,6 +232,7 @@ internal Config ConfigFor(IActorRef journalPluginActor) /// This exception is thrown when either the plugin class name is undefined or the configuration path is missing. /// /// TBD + [InternalStableApi] public IActorRef JournalFor(string journalPluginId) { var configPath = string.IsNullOrEmpty(journalPluginId) ? _defaultJournalPluginId.Value : journalPluginId; @@ -249,6 +251,7 @@ public IActorRef JournalFor(string journalPluginId) /// This exception is thrown when either the plugin class name is undefined or the configuration path is missing. /// /// TBD + [InternalStableApi] public IActorRef SnapshotStoreFor(string snapshotPluginId) { var configPath = string.IsNullOrEmpty(snapshotPluginId) ? _defaultSnapshotPluginId.Value : snapshotPluginId; diff --git a/src/core/Akka/Annotations/Attributes.cs b/src/core/Akka/Annotations/Attributes.cs index 7f190883852..55c538ddcd5 100644 --- a/src/core/Akka/Annotations/Attributes.cs +++ b/src/core/Akka/Annotations/Attributes.cs @@ -11,34 +11,51 @@ namespace Akka.Annotations { /// /// Marks APIs that are considered internal to Akka and may change at any point in time without any warning. - /// + /// /// For example, this annotation should be used for code that should be inherently internal, but it cannot be /// due to limitations of .NET encapsulation in areas such as inheritance or serialization. - /// + /// + /// /// If a method/class annotated with this method has a xdoc comment, the first line MUST include /// in order to be easily identifiable from generated documentation. Additional information /// may be put on the same line as the INTERNAL API comment in order to clarify further. + /// /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Module, Inherited = true, AllowMultiple = false)] public sealed class InternalApiAttribute : Attribute { } + /// + /// Marks APIs that are considered internal to Akka and should not be accessed by user code but that are used + /// across Akka project boundaries and therefore shouldn't be changed without considering possible usage + /// outside of the Akka core modules. + /// + /// If a method/class annotated with this annotation is part of a public API there should be a xdoc comment + /// where the first line MUST include INTERNAL API in order to be easily identifiable from generated documentation. + /// Additional information may be put on the same line as the INTERNAL API comment in order to clarify further. + /// + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Module, Inherited = true, AllowMultiple = false)] + public sealed class InternalStableApiAttribute : Attribute + { + } + /// /// Marks APIs that are meant to evolve towards becoming stable APIs, but are not stable APIs yet. - /// + /// /// Evolving interfaces MAY change from one patch release to another (i.e. 1.3.0 to 1.3.1) without up-front notice. /// A best-effort approach is taken to not cause more breakage than really neccessary, and usual deprecation techniques /// are utilised while evolving these APIs, however there is NO strong guarantee regarding the source or binary /// compatibility of APIs marked using this annotation. - /// + /// + /// /// It MAY also change when promoting the API to stable, for example such changes may include removal of deprecated /// methods that were introduced during the evolution and final refactoring that were deferred because they would /// have introduced to much breaking changes during the evolution phase. - /// - /// Promoting the API to stable MAY happen in a patch release. - /// - /// It is encouraged to document in xmldoc how exactly this API is expected to evolve. + /// + /// Promoting the API to stable MAY happen in a patch release. + /// It is encouraged to document in xmldoc how exactly this API is expected to evolve. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Module, Inherited = true, AllowMultiple = false)] public sealed class ApiMayChangeAttribute : Attribute diff --git a/src/core/Akka/Dispatch/SysMsg/ISystemMessage.cs b/src/core/Akka/Dispatch/SysMsg/ISystemMessage.cs index fcec943c974..78512e63aa3 100644 --- a/src/core/Akka/Dispatch/SysMsg/ISystemMessage.cs +++ b/src/core/Akka/Dispatch/SysMsg/ISystemMessage.cs @@ -278,11 +278,12 @@ public interface ISystemMessage : INoSerializationVerificationNeeded /// is an interface and too basic to express /// all of the capabilities needed to express a full-fledged system message. /// - [InternalApi] + [InternalStableApi] public abstract class SystemMessage : ISystemMessage { /// /// The next in the linked list. + /// Next fields are only modifiable via the class. /// [NonSerialized] internal SystemMessage Next; @@ -290,15 +291,12 @@ public abstract class SystemMessage : ISystemMessage /// /// Unlinks this message from the linked list. /// - public void Unlink() - { - Next = null; - } + public void Unlink() => Next = null; /// /// Returns true if we are unlinked. /// - public bool Unlinked { get { return Next == null; } } + public bool Unlinked => Next == null; } /// diff --git a/src/core/Akka/Util/Option.cs b/src/core/Akka/Util/Option.cs index 5eb5c24d8d4..d321043ae46 100644 --- a/src/core/Akka/Util/Option.cs +++ b/src/core/Akka/Util/Option.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using Akka.Annotations; namespace Akka.Util { @@ -17,6 +18,7 @@ namespace Akka.Util /// Useful where distinguishing between null (or zero, or false) and uninitialized is significant. /// /// TBD + [InternalStableApi] public readonly struct Option { [MethodImpl(MethodImplOptions.AggressiveInlining)]