Exemple #1
0
        /// <summary>
        /// Asynchronously tries to get a replicated value of type <typeparamref name="T"/> stored
        /// under a given <paramref name="key"/>, while trying to achieve provided read
        /// <paramref name="consistency"/>. If no value was found under provided key, a null value will be returned.
        ///
        /// If no <paramref name="consistency"/> will be provided, a <see cref="ReadLocal"/> will be used.
        /// </summary>
        /// <exception cref="DataDeletedException">Thrown if value under provided <paramref name="key"/> was permamently deleted. That key can't be used anymore.</exception>
        /// <exception cref="TimeoutException">Thrown if get request consistency was not achieved within possible time limit attached to a provided read <paramref name="consistency"/>.</exception>
        /// <typeparam name="T">Replicated data type to get.</typeparam>
        /// <param name="key">Key under which a replicated data is stored.</param>
        /// <param name="consistency">A read consistency requested for this write.</param>
        /// <param name="cancellation">Cancellation token used to cancel request prematurelly if needed.</param>
        /// <returns>A task which may return a replicated data value or throw an exception.</returns>
        public async Task <T> GetAsync <T>(IKey <T> key, IReadConsistency consistency = null, CancellationToken cancellation = default(CancellationToken))
            where T : class, IReplicatedData <T>
        {
            var id       = Guid.NewGuid();
            var response = await Replicator.Ask(Dsl.Get(key, consistency, id), cancellation);

            switch (response)
            {
            case GetSuccess success:
                if (Equals(id, success.Request))
                {
                    return(success.Get(key));
                }
                else
                {
                    throw new NotSupportedException($"Received response id [{success.Request}] and request correlation id [{id}] are different.");
                }

            case NotFound notFound: return(null);

            case DataDeleted deleted: throw new DataDeletedException($"Cannot retrieve data under key [{key}]. It has been permanently deleted and the key cannot be reused.");

            case GetFailure failure: throw new TimeoutException($"Couldn't retrieve the data under key [{key}] within consistency constraints {consistency} and under provided timeout.");

            case Status.Failure failure:
                ExceptionDispatchInfo.Capture(failure.Cause).Throw();
                return(default(T));

            default: throw new NotSupportedException("Unknown response type: " + response);
            }
        }
Exemple #2
0
        public DDataShard(
            string typeName,
            ShardId shardId,
            Props entityProps,
            ClusterShardingSettings settings,
            ExtractEntityId extractEntityId,
            ExtractShardId extractShardId,
            object handOffStopMessage,
            IActorRef replicator,
            int majorityCap)
        {
            TypeName           = typeName;
            ShardId            = shardId;
            EntityProps        = entityProps;
            Settings           = settings;
            ExtractEntityId    = extractEntityId;
            ExtractShardId     = extractShardId;
            HandOffStopMessage = handOffStopMessage;
            Replicator         = replicator;
            MajorityCap        = majorityCap;

            RememberedEntitiesRecoveryStrategy = Settings.TunningParameters.EntityRecoveryStrategy == "constant"
                ? EntityRecoveryStrategy.ConstantStrategy(
                Context.System,
                Settings.TunningParameters.EntityRecoveryConstantRateStrategyFrequency,
                Settings.TunningParameters.EntityRecoveryConstantRateStrategyNumberOfEntities)
                : EntityRecoveryStrategy.AllStrategy;

            _readConsistency  = new ReadMajority(settings.TunningParameters.WaitingForStateTimeout, majorityCap);
            _writeConsistency = new WriteMajority(settings.TunningParameters.UpdatingStateTimeout, majorityCap);
            _stateKeys        = Enumerable.Range(0, NrOfKeys).Select(i => new ORSetKey <EntryId>($"shard-{typeName}-{shardId}-{i}")).ToImmutableArray();

            GetState();
        }
Exemple #3
0
 /// <summary>
 /// Peeks at the current state without advancing
 /// </summary>
 /// <param name="key">The Key Entry to retrieve state for</param>
 /// <param name="readConsistency">The Consistency to use for reading. if null, <see cref="ReadLocal"/> will be used</param>
 /// <returns>The current Deduplication state</returns>
 public DeduplicationState PeekCurrentState(string key, IReadConsistency readConsistency = null)
 {
     return(_receiver.Replicator
            .GetAsync(
                new LWWDictionaryKey <string, DeduplicationState>(
                    _receiver.ReplicatorKey), readConsistency).Result.FirstOrDefault(r => r.Key == key)
            .Value);
 }
Exemple #4
0
 public App(ActorSystem system)
 {
     this.system           = system;
     this.cluster          = Cluster.Get(system);
     this.ddata            = DistributedData.Get(system);
     this.timeout          = TimeSpan.FromSeconds(10);
     this.readConsistency  = new ReadMajority(timeout);
     this.writeConsistency = new WriteMajority(timeout);
 }
Exemple #5
0
 protected DurableDataSpec(DurableDataSpecConfig config, Type type) : base(config, type)
 {
     InitialParticipantsValueFactory = Roles.Count;
     cluster  = Akka.Cluster.Cluster.Get(Sys);
     writeTwo = new WriteTo(2, timeout);
     readTwo  = new ReadFrom(2, timeout);
     first    = config.First;
     second   = config.Second;
 }
Exemple #6
0
 public ReadAggregator(IKey key, IReadConsistency consistency, object req, IImmutableSet <Address> nodes, DataEnvelope localValue, IActorRef replyTo)
     : base(nodes, consistency.Timeout)
 {
     _key         = key;
     _consistency = consistency;
     _req         = req;
     _replyTo     = replyTo;
     _result      = localValue;
     _read        = new Read(key.Id);
 }
Exemple #7
0
 public ReadAggregator(IKey key, IReadConsistency consistency, object req, IImmutableList <Address> nodes, IImmutableSet <Address> unreachable, bool shuffle, DataEnvelope localValue, IActorRef replyTo)
     : base(nodes, unreachable, consistency.Timeout, shuffle)
 {
     _key                  = key;
     _consistency          = consistency;
     _req                  = req;
     _replyTo              = replyTo;
     _result               = localValue;
     _read                 = new Read(key.Id);
     DoneWhenRemainingSize = GetDoneWhenRemainingSize();
 }
Exemple #8
0
        protected DurableDataSpecBase(DurableDataSpecConfig config, Type type) : base(config, type)
        {
            cluster = Akka.Cluster.Cluster.Get(Sys);
            var timeout = Dilated(14.Seconds()); // initialization of lmdb can be very slow in CI environment

            writeTwo = new WriteTo(2, timeout);
            readTwo  = new ReadFrom(2, timeout);

            first  = config.First;
            second = config.Second;
        }
Exemple #9
0
 private bool IsLocalGet(IReadConsistency consistency)
 {
     if (consistency is ReadLocal)
     {
         return(true);
     }
     if (consistency is ReadAll || consistency is ReadMajority)
     {
         return(_nodes.Count == 0);
     }
     return(false);
 }
Exemple #10
0
        protected DurableDataPocoSpecBase(DurableDataPocoSpecConfig config, Type type) : base(config, type)
        {
            _cluster = Akka.Cluster.Cluster.Get(Sys);
            var timeout = Dilated(14.Seconds()); // initialization of lmdb can be very slow in CI environment

            _writeThree = new WriteTo(3, timeout);
            _readThree  = new ReadFrom(3, timeout);

            _first  = config.First;
            _second = config.Second;
            _third  = config.Third;
        }
Exemple #11
0
        public DDataShard(
            string typeName,
            ShardId shardId,
            Func <string, Props> entityProps,
            ClusterShardingSettings settings,
            ExtractEntityId extractEntityId,
            ExtractShardId extractShardId,
            object handOffStopMessage,
            IActorRef replicator,
            int majorityCap)
        {
            TypeName           = typeName;
            ShardId            = shardId;
            EntityProps        = entityProps;
            Settings           = settings;
            ExtractEntityId    = extractEntityId;
            ExtractShardId     = extractShardId;
            HandOffStopMessage = handOffStopMessage;
            Replicator         = replicator;
            MajorityCap        = majorityCap;

            RememberedEntitiesRecoveryStrategy = Settings.TunningParameters.EntityRecoveryStrategy == "constant"
                ? EntityRecoveryStrategy.ConstantStrategy(
                Context.System,
                Settings.TunningParameters.EntityRecoveryConstantRateStrategyFrequency,
                Settings.TunningParameters.EntityRecoveryConstantRateStrategyNumberOfEntities)
                : EntityRecoveryStrategy.AllStrategy;

            var idleInterval = TimeSpan.FromTicks(Settings.PassivateIdleEntityAfter.Ticks / 2);

            PassivateIdleTask = Settings.ShouldPassivateIdleEntities
                ? Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(idleInterval, idleInterval, Self, Shard.PassivateIdleTick.Instance, Self)
                : null;

            _readConsistency  = new ReadMajority(settings.TunningParameters.WaitingForStateTimeout, majorityCap);
            _writeConsistency = new WriteMajority(settings.TunningParameters.UpdatingStateTimeout, majorityCap);
            _stateKeys        = Enumerable.Range(0, NrOfKeys).Select(i => new ORSetKey <EntryId>($"shard-{typeName}-{shardId}-{i}")).ToImmutableArray();

            GetState();
        }
Exemple #12
0
        public DDataShardCoordinator(string typeName, ClusterShardingSettings settings, IShardAllocationStrategy allocationStrategy, IActorRef replicator, int majorityMinCap, bool rememberEntities)
        {
            _replicator        = replicator;
            _rememberEntities  = rememberEntities;
            Settings           = settings;
            AllocationStrategy = allocationStrategy;
            Log           = Context.GetLogger();
            Cluster       = Cluster.Get(Context.System);
            CurrentState  = PersistentShardCoordinator.State.Empty.WithRememberEntities(settings.RememberEntities);
            RemovalMargin = Cluster.DowningProvider.DownRemovalMargin;
            MinMembers    = string.IsNullOrEmpty(settings.Role)
                ? Cluster.Settings.MinNrOfMembers
                : (Cluster.Settings.MinNrOfMembersOfRole.TryGetValue(settings.Role, out var min) ? min : Cluster.Settings.MinNrOfMembers);
            RebalanceTask = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(Settings.TunningParameters.RebalanceInterval, Settings.TunningParameters.RebalanceInterval, Self, RebalanceTick.Instance, Self);

            _readConsistency     = new ReadMajority(settings.TunningParameters.WaitingForStateTimeout, majorityMinCap);
            _writeConsistency    = new WriteMajority(settings.TunningParameters.UpdatingStateTimeout, majorityMinCap);
            _coordinatorStateKey = new LWWRegisterKey <PersistentShardCoordinator.State>(typeName + "CoordinatorState");
            _allShardsKey        = new GSetKey <string>($"shard-{typeName}-all");
            _allKeys             = rememberEntities
                ? ImmutableHashSet.CreateRange(new IKey <IReplicatedData>[] { _coordinatorStateKey, _allShardsKey })
                : ImmutableHashSet.Create <IKey <IReplicatedData> >(_coordinatorStateKey);

            if (rememberEntities)
            {
                replicator.Tell(Dsl.Subscribe(_allShardsKey, Self));
            }

            Cluster.Subscribe(Self, ClusterEvent.SubscriptionInitialStateMode.InitialStateAsEvents, typeof(ClusterEvent.ClusterShuttingDown));

            // get state from ddata replicator, repeat until GetSuccess
            GetCoordinatorState();
            GetAllShards();

            Context.Become(WaitingForState(_allKeys));
        }
Exemple #13
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <typeparam name="T">TBD</typeparam>
 /// <param name="key">TBD</param>
 /// <param name="consistency">TBD</param>
 /// <returns>TBD</returns>
 public static Replicator.Get Get <T>(IKey <T> key, IReadConsistency consistency) where T : IReplicatedData =>
 new Replicator.Get(key, consistency);
 internal static Props Props(IKey key, IReadConsistency consistency, object req, IImmutableSet <Address> nodes, IImmutableSet <Address> unreachable, DataEnvelope localValue, IActorRef replyTo) =>
 Actor.Props.Create(() => new ReadAggregator(key, consistency, req, nodes, unreachable, localValue, replyTo)).WithDeploy(Deploy.Local);
Exemple #15
0
 public Get(IKey key, IReadConsistency consistency, object request = null)
 {
     Key         = key;
     Consistency = consistency;
     Request     = request;
 }
Exemple #16
0
        public DeduplicationState AdvanceAndGetProcessingState(string key, IWriteConsistency writeConsistency = null, IReadConsistency readConsistency = null)
        {
            var _writeconsistency = writeConsistency ?? WriteLocal.Instance;

            _receiver.Replicator.Replicator.Tell(CreateAdvanceAndGetStateCommand(key, _writeconsistency));
            return(_receiver.Replicator
                   .GetAsync(
                       new LWWDictionaryKey <string, DeduplicationState>(
                           _receiver.ReplicatorKey), readConsistency).Result
                   .FirstOrDefault(r => r.Key == key).Value);
        }
Exemple #17
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <typeparam name="T">TBD</typeparam>
 /// <param name="key">TBD</param>
 /// <param name="consistency">TBD</param>
 /// <param name="request">TBD</param>
 /// <returns>TBD</returns>
 public static Replicator.Get Get <T>(IKey <T> key, IReadConsistency consistency, object request) where T : IReplicatedData =>
 new Replicator.Get(key, consistency, request);
Exemple #18
0
 /// <summary>
 /// Constructs a message that, when send to <see cref="DistributedData.Replicator"/>,
 /// will perform a retrieve of a data structure stored under provided <paramref name="key"/>,
 /// and reply with <see cref="IGetResponse"/> message.
 ///
 /// An optional <paramref name="consistency"/> level may be supplied in order to apply
 /// certain constraints on the produced response.
 /// </summary>
 /// <typeparam name="T">Replicated data type.</typeparam>
 /// <param name="key">Key, for which a value should be retrieved.</param>
 /// <param name="consistency">A consistency level determining when/how response will be retrieved.</param>
 /// <param name="request">
 /// An object added to both generated <see cref="Akka.DistributedData.Get"/> request and
 /// <see cref="IGetResponse"/>. Can be used i.e. as correlation id.
 /// </param>
 /// <returns>TBD</returns>
 public static Get Get <T>(IKey <T> key, IReadConsistency consistency = null, object request = null) where T : IReplicatedData =>
 new Get(key, consistency ?? ReadLocal, request);