public void UnregisteredAcksCantBeTriggered() { var ackHandler = new AckHandler(completeAcksOnTimeout: false, ackThreshold: TimeSpan.Zero, ackInterval: TimeSpan.Zero); Assert.False(ackHandler.TriggerAck("foo")); }
public void UnregisteredAcksCantBeTriggered() { var ackHandler = new AckHandler(cancelAcksOnTimeout: false, ackThreshold: TimeSpan.Zero, ackInterval: TimeSpan.Zero); Assert.False(ackHandler.TriggerAck("foo")); }
/// <summary> /// Create server specific channel in order to send an ack to a single server /// </summary> /// <param name="server"></param> private void SubscribeToAckChannel(IRedisServer server) { var ackChannel = _channels.Ack(server.ServerName); server.Subscriber.Subscribe(ackChannel, (_, data) => { var ackId = _protocol.ReadAck((byte[])data); _ackHandler.TriggerAck(ackId); }); }
public void TriggeredAcksAreCompleted() { var ackHandler = new AckHandler(completeAcksOnTimeout: false, ackThreshold: TimeSpan.Zero, ackInterval: TimeSpan.Zero); Task task = ackHandler.CreateAck("foo"); Assert.True(ackHandler.TriggerAck("foo")); Assert.True(task.IsCompleted); }
public void TriggeredAcksAreCompleted() { var ackHandler = new AckHandler(cancelAcksOnTimeout: false, ackThreshold: TimeSpan.Zero, ackInterval: TimeSpan.Zero); Task task = ackHandler.CreateAck("foo"); Assert.True(ackHandler.TriggerAck("foo")); Assert.True(task.IsCompleted); }
public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger, IOptions <RedisOptions> options) { _logger = logger; _options = options.Value; _ackHandler = new AckHandler(); var writer = new LoggerTextWriter(logger); _logger.LogInformation("Connecting to redis endpoints: {endpoints}", string.Join(", ", options.Value.Options.EndPoints.Select(e => EndPointCollection.ToString(e)))); _redisServerConnection = _options.Connect(writer); if (_redisServerConnection.IsConnected) { _logger.LogInformation("Connected to redis"); } else { // TODO: We could support reconnecting, like old SignalR does. throw new InvalidOperationException("Connection to redis failed."); } _bus = _redisServerConnection.GetSubscriber(); var previousBroadcastTask = Task.CompletedTask; var channelName = _channelNamePrefix; _logger.LogInformation("Subscribing to channel: {channel}", channelName); _bus.Subscribe(channelName, async(c, data) => { await previousBroadcastTask; _logger.LogTrace("Received message from redis channel {channel}", channelName); var message = DeserializeMessage <HubMessage>(data); // TODO: This isn't going to work when we allow JsonSerializer customization or add Protobuf var tasks = new List <Task>(_connections.Count); foreach (var connection in _connections) { tasks.Add(WriteAsync(connection, message)); } previousBroadcastTask = Task.WhenAll(tasks); }); var allExceptTask = Task.CompletedTask; channelName = _channelNamePrefix + ".AllExcept"; _logger.LogInformation("Subscribing to channel: {channel}", channelName); _bus.Subscribe(channelName, async(c, data) => { await allExceptTask; _logger.LogTrace("Received message from redis channel {channel}", channelName); var message = DeserializeMessage <RedisExcludeClientsMessage>(data); var excludedIds = message.ExcludedIds; // TODO: This isn't going to work when we allow JsonSerializer customization or add Protobuf var tasks = new List <Task>(_connections.Count); foreach (var connection in _connections) { if (!excludedIds.Contains(connection.ConnectionId)) { tasks.Add(WriteAsync(connection, message)); } } allExceptTask = Task.WhenAll(tasks); }); channelName = _channelNamePrefix + ".internal.group"; _bus.Subscribe(channelName, async(c, data) => { var groupMessage = DeserializeMessage <GroupMessage>(data); if (groupMessage.Action == GroupAction.Remove) { if (!await RemoveGroupAsyncCore(groupMessage.ConnectionId, groupMessage.Group)) { // user not on this server return; } } if (groupMessage.Action == GroupAction.Add) { if (!await AddGroupAsyncCore(groupMessage.ConnectionId, groupMessage.Group)) { // user not on this server return; } } // Sending ack to server that sent the original add/remove await PublishAsync($"{_channelNamePrefix}.internal.{groupMessage.Server}", new GroupMessage { Action = GroupAction.Ack, ConnectionId = groupMessage.ConnectionId, Group = groupMessage.Group, Id = groupMessage.Id }); }); // Create server specific channel in order to send an ack to a single server var serverChannel = $"{_channelNamePrefix}.internal.{_serverName}"; _bus.Subscribe(serverChannel, (c, data) => { var groupMessage = DeserializeMessage <GroupMessage>(data); if (groupMessage.Action == GroupAction.Ack) { _ackHandler.TriggerAck(groupMessage.Id); } }); }