public async Task SendRequest(string stageId, byte[] data) { if (!_multiplexer.IsConnected) { throw new Exception("Redis not connected"); } if (String.IsNullOrEmpty(stageId)) { var stages = await _stageDirectory.GetAllStages(); //shuffle stageId = stages.OrderBy(s => Guid.NewGuid()).FirstOrDefault(); } if (String.IsNullOrEmpty(stageId)) { _logger.LogError("No live stage to connect to"); throw new Exception("No live stage to connect to"); } try { _redisPolicy.Execute(() => { var result = _subscriber.Publish(_outputChannel(stageId), data, CommandFlags.FireAndForget | CommandFlags.HighPriority); }); } catch (Exception ex) { _telemetry.Exception(ex); _logger.LogError("Client Failed to send request"); } }
private void ConnectionMonitor() { Task.Run(async() => { while (!_isDisposed) { try { await Task.Delay(2500); var stages = await _stageDirectory.GetAllStages(); var connected = false; foreach (var stage in stages) { var pingResult = await _remoteClient.PingStage(stage); if (pingResult.HasValue) { connected = true; break; } } ClientConnected = connected; } catch { } } }); }
public async ValueTask <StageAddressQueryResponse> GetAddress(string actorTypeName, string actorId) { var key = string.Join(":", actorTypeName, actorId); StageAddressQueryResponse address; if (_memoryCache.TryGetValue(key, out address)) { return(address); } else { var stageId = await _database.HashGetAsync(_actorDirectoryKey, key, CommandFlags.HighPriority); if (stageId == RedisValue.Null) { var stages = await _stageDirectory.GetAllStages(); stageId = stages.OrderBy(s => Guid.NewGuid()).FirstOrDefault(); if (stageId == RedisValue.Null) { throw new Exception("No live stage to connect to"); } var updated = await _database.HashSetAsync(_actorDirectoryKey, key, stageId, When.NotExists); if (!updated) { stageId = await _database.HashGetAsync(_actorDirectoryKey, key); } } address = new StageAddressQueryResponse() { Found = true, StageId = stageId }; _memoryCache.Set(key, address, TimeSpan.FromSeconds(5)); return(address); } }
public void SelfMonitor() { Task.Run(async() => { Dictionary <string, int> _missedPings = new Dictionary <string, int>(); while (true) { await Task.Delay(5000); try { var stages = await _stageDirectory.GetAllStages(); if (_paused > 0) { break; } if (!stages.Contains(_ownStageId)) { //others have signaled this stage as dead //clear local stage //await _localStage.Stop(); _exitSemaphore.Release(); //register again //await _stageDirectory.RegisterStage(_localStage.StageGuid); } } catch { } } }).ConfigureAwait(false); }
public async Task <ActorResponse> SendRemoteActorRequest(ActorRequest request, TimeSpan?timeout = null) { if (request.WorkerActor) { var allStages = await _stageDirectory.GetAllStages(); var stageAddress = allStages.OrderBy(a => Guid.NewGuid()).FirstOrDefault(); return(await SendRemoteActorRequest(stageAddress, request, timeout)); } else { var stageResponse = await _actorDirectory.GetAddress(request.ActorInterface, request.ActorId); if (await _stageDirectory.IsLive(stageResponse.StageId)) { return(await SendRemoteActorRequest(stageResponse.StageId, request, timeout)); } else { return(await SendRemoteActorRequest(null, request, timeout)); } } }