/// <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); } }
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(); }
/// <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); }
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); }
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; }
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); }
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(); }
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; }
private bool IsLocalGet(IReadConsistency consistency) { if (consistency is ReadLocal) { return(true); } if (consistency is ReadAll || consistency is ReadMajority) { return(_nodes.Count == 0); } return(false); }
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; }
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(); }
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)); }
/// <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);
public Get(IKey key, IReadConsistency consistency, object request = null) { Key = key; Consistency = consistency; Request = request; }
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); }
/// <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);
/// <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);