예제 #1
0
        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");
            }
        }
예제 #2
0
        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 { }
                }
            });
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
                }
            }
        }