public Task RemoveLock(SpawnLock spawnLock, CancellationToken ct) => _asyncSemaphore.WaitAsync(() => { Logger.LogInformation("[MongoIdentityStorage] DeleteManyAsync"); if (ct.IsCancellationRequested) { Logger.LogInformation("[MongoIdentityStorage] DeleteManyAsync, resetting cancellation token."); ct = CancellationTokens.WithTimeout(TimeSpan.FromSeconds(5)); } Logger.LogInformation("[MongoIdentityStorage] DeleteManyAsync, LockId {LockId}.", spawnLock.LockId); return(_pids.DeleteManyAsync(p => p.LockedBy == spawnLock.LockId, ct)); });
public Task RemoveMember(string memberId, CancellationToken ct) => _asyncSemaphore.WaitAsync(() => { Logger.LogInformation("[MongoIdentityStorage] RemoveMember"); if (ct.IsCancellationRequested) { Logger.LogInformation("[MongoIdentityStorage] RemoveMember, resetting cancellation token."); ct = CancellationTokens.WithTimeout(TimeSpan.FromSeconds(5)); } Logger.LogInformation("[MongoIdentityStorage] RemoveMember, Pid {MemberId}.", memberId); return(_pids.DeleteManyAsync(p => p.MemberId == memberId, ct)); });
public async Task RemoveActivation(PID pid, CancellationToken ct) { Logger.LogDebug("Removing activation: {@PID}", pid); await _asyncSemaphore.WaitAsync(() => { Logger.LogInformation("[MongoIdentityStorage] RemoveActivation"); if (ct.IsCancellationRequested) { Logger.LogInformation("[MongoIdentityStorage] RemoveActivation, resetting cancellation token."); ct = CancellationTokens.WithTimeout(TimeSpan.FromSeconds(5)); } Logger.LogInformation("[MongoIdentityStorage] RemoveActivation, Pid {PidIs}.", pid.Id); return(_pids.DeleteManyAsync(p => p.UniqueIdentity == pid.Id, ct)); }); }
public async Task <PID?> GetAsync(ClusterIdentity clusterIdentity, CancellationToken ct) { ct = CancellationTokens.WithTimeout(_getPidTimeout); //Get address to node owning this ID var identityOwner = _partitionManager.Selector.GetIdentityOwner(clusterIdentity.Identity); Logger.LogDebug("Identity belongs to {address}", identityOwner); if (string.IsNullOrEmpty(identityOwner)) { return(null); } var remotePid = PartitionManager.RemotePartitionIdentityActor(identityOwner); var req = new ActivationRequest { ClusterIdentity = clusterIdentity }; Logger.LogDebug("Requesting remote PID from {Partition}:{Remote} {@Request}", identityOwner, remotePid, req ); try { var resp = await _cluster.System.Root.RequestAsync <ActivationResponse>(remotePid, req, ct); return(resp.Pid); } //TODO: decide if we throw or return null catch (DeadLetterException) { Logger.LogInformation("Remote PID request deadletter {@Request}, identity Owner {Owner}", req, identityOwner); return(null); } catch (TimeoutException) { Logger.LogInformation("Remote PID request timeout {@Request}, identity Owner {Owner}", req, identityOwner); return(null); } catch (Exception e) { Logger.LogError(e, "Error occured requesting remote PID {@Request}, identity Owner {Owner}", req, identityOwner); return(null); } }
public async Task CanWaitForActivation() { var activator = GetFakeActivator(); var timeout = CancellationTokens.WithTimeout(15 * 1000); var identity = new ClusterIdentity { Kind = "thing", Identity = NextId().ToString() }; var spawnLock = await _storage.TryAcquireLock(identity, timeout); var pid = Activate(activator, identity); _ = SafeTask.Run(async() => { await Task.Delay(500, timeout); await _storage.StoreActivation(activator.Id, spawnLock !, pid, timeout); }, timeout ); var activation = await _storage.WaitForActivation(identity, timeout); activation.Should().NotBeNull(); activation !.MemberId.Should().Be(activator.Id); activation !.Pid.Should().BeEquivalentTo(pid); }
private static async Task RunKafkaConsumeLoop(Cluster cluster) { while (true) { var sw = Stopwatch.StartNew(); //get the messages from Kafka or other log/queue var messages = GetBatchFromKafka(); var tasks = new List <Task>(); //forward each message to their actors foreach (var message in messages) { object m = message.MessageCase switch { MyEnvelope.MessageOneofCase.SomeMessage => message.SomeMessage, MyEnvelope.MessageOneofCase.SomeOtherMessage => message.SomeOtherMessage, _ => throw new ArgumentOutOfRangeException(nameof(message), "Unknown message case") }; var task = cluster .RequestAsync <Ack>(message.DeviceId, "device", m, CancellationTokens.WithTimeout(5000)); tasks.Add(task); } //await response form all actors await Task.WhenAll(tasks); //TODO: commit back to Kafka that all messages succeeded sw.Stop(); var tps = 1000.0 / sw.Elapsed.TotalMilliseconds * tasks.Count; //show throughput, messages per second Console.WriteLine(tps.ToString("n0")); } }
public void DumpState(ClusterIdentity clusterIdentity) { Console.WriteLine("Memberlist members:"); _cluster.MemberList.DumpState(); Console.WriteLine("Partition manager selector:"); _partitionManager.Selector.DumpState(); //Get address to node owning this ID var identityOwner = _partitionManager.Selector.GetIdentityOwner(clusterIdentity.Identity); Console.WriteLine("Identity owner for ID:"); Console.WriteLine(identityOwner); var remotePid = PartitionManager.RemotePartitionIdentityActor(identityOwner); var req = new ActivationRequest { ClusterIdentity = clusterIdentity }; var resp = _cluster.System.Root.RequestAsync <ActivationResponse>(remotePid, req, CancellationTokens.WithTimeout(5000)).Result; Console.WriteLine("Target Pid:"); if (resp == null) { Console.WriteLine("Null response"); } else if (resp.Pid == null) { Console.WriteLine("Null PID"); } else { Console.WriteLine(resp.Pid); } }
public static void Run() { var l = LoggerFactory.Create(x => x.AddConsole().SetMinimumLevel(LogLevel.Information)); Log.SetLoggerFactory(l); var config = ActorSystemConfig.Setup().WithMetricsProviders(new PrometheusConfigurator()); var remoteConfig = GrpcCoreRemoteConfig .BindToLocalhost() .WithProtoMessages(MessagesReflection.Descriptor); var clusterConfig = ClusterConfig .Setup("MyCluster", new ConsulProvider(new ConsulProviderConfig(), c => c.Address = new Uri("http://127.0.0.1:8500/")), new PartitionIdentityLookup() ); var system = new ActorSystem(config) .WithRemote(remoteConfig) .WithCluster(clusterConfig); system .Cluster() .StartMemberAsync(); var props = Props.FromProducer(() => new MyActor()); var config2 = ActorSystemConfig.Setup().WithMetricsProviders(new PrometheusConfigurator()); var remoteConfig2 = GrpcCoreRemoteConfig .BindToLocalhost() .WithProtoMessages(MessagesReflection.Descriptor); var clusterConfig2 = ClusterConfig .Setup("MyCluster", new ConsulProvider(new ConsulProviderConfig(), c => c.Address = new Uri("http://127.0.0.1:8500/")), new PartitionIdentityLookup() ) .WithClusterKind("somekind", props); var system2 = new ActorSystem(config2) .WithRemote(remoteConfig2) .WithCluster(clusterConfig2); system2 .Cluster() .StartMemberAsync(); _ = SafeTask.Run(async() => { var r = new Random(); while (true) { await Task.Delay(r.Next(1, 2000)); await system.Cluster().RequestAsync <SomeResponse>($"someactor{r.Next(1, 100)}", "somekind", new SomeRequest(), CancellationTokens.WithTimeout(5000) ); } } ); }