Exemplo n.º 1
0
        private static IRequest JoinGroupRequest(IRequestContext context, ArraySegment <byte> payload)
        {
            using (var reader = ReadHeader(payload)) {
                var      groupId          = reader.ReadString();
                var      sessionTimeout   = TimeSpan.FromMilliseconds(reader.ReadInt32());
                TimeSpan?rebalanceTimeout = null;
                if (context.ApiVersion >= 1)
                {
                    rebalanceTimeout = TimeSpan.FromMilliseconds(reader.ReadInt32());
                }
                var memberId       = reader.ReadString();
                var protocolType   = reader.ReadString();
                var groupProtocols = new JoinGroupRequest.GroupProtocol[reader.ReadInt32()];

                var encoder = context.GetEncoder(protocolType);
                for (var g = 0; g < groupProtocols.Length; g++)
                {
                    var protocolName = reader.ReadString();
                    var metadata     = encoder.DecodeMetadata(protocolName, reader);
                    groupProtocols[g] = new JoinGroupRequest.GroupProtocol(metadata);
                }

                return(new JoinGroupRequest(groupId, sessionTimeout, memberId, protocolType, groupProtocols, rebalanceTimeout));
            }
        }
Exemplo n.º 2
0
        public async Task ConsumerSyncsGroupAfterJoining()
        {
            var protocol = new JoinGroupRequest.GroupProtocol(new ConsumerProtocolMetadata("mine"));
            var router   = Substitute.For <IRouter>();
            var conn     = Substitute.For <IConnection>();

            router.GetGroupConnectionAsync(Arg.Any <string>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(new GroupConnection(_.Arg <string>(), 0, conn)));
            router.SyncGroupAsync(Arg.Any <SyncGroupRequest>(), Arg.Any <IRequestContext>(), Arg.Any <IRetry>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(new SyncGroupResponse(ErrorCode.NONE, new ConsumerMemberAssignment(new [] { new TopicPartition("name", 0) }))));

            var request  = new JoinGroupRequest(TestConfig.GroupId(), TimeSpan.FromSeconds(30), "", ConsumerEncoder.Protocol, new [] { protocol });
            var memberId = Guid.NewGuid().ToString("N");
            var response = new JoinGroupResponse(ErrorCode.NONE, 1, protocol.protocol_name, memberId, memberId, new [] { new JoinGroupResponse.Member(memberId, new ConsumerProtocolMetadata("mine")) });

            using (new GroupConsumer(router, request.group_id, request.protocol_type, response)) {
                await Task.Delay(300);
            }

#pragma warning disable 4014
            router.Received().SyncGroupAsync(
                Arg.Is((SyncGroupRequest s) => s.group_id == request.group_id && s.member_id == memberId),
                Arg.Any <IRequestContext>(),
                Arg.Any <IRetry>(),
                Arg.Any <CancellationToken>());
            conn.DidNotReceive().SendAsync(
                Arg.Is((HeartbeatRequest s) => s.group_id == request.group_id && s.member_id == memberId),
                Arg.Any <CancellationToken>(),
                Arg.Any <IRequestContext>());
#pragma warning restore 4014
        }
Exemplo n.º 3
0
        public async Task ConsumerHeartbeatsWithinTimeLimit(int heartbeatMilliseconds, int totalMilliseconds)
        {
            var protocol = new JoinGroupRequest.GroupProtocol(new ConsumerProtocolMetadata("mine"));
            var router   = Substitute.For <IRouter>();
            var conn     = Substitute.For <IConnection>();

            router.GetGroupConnectionAsync(Arg.Any <string>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(new GroupConnection(_.Arg <string>(), 0, conn)));

            var lastHeartbeat      = DateTimeOffset.UtcNow;
            var heartbeatIntervals = ImmutableArray <TimeSpan> .Empty;

            conn.SendAsync(Arg.Any <HeartbeatRequest>(), Arg.Any <CancellationToken>(), Arg.Any <IRequestContext>())
            .Returns(_ => {
                heartbeatIntervals = heartbeatIntervals.Add(DateTimeOffset.UtcNow - lastHeartbeat);
                lastHeartbeat      = DateTimeOffset.UtcNow;
                return(Task.FromResult(new HeartbeatResponse(ErrorCode.NONE)));
            });
            var request  = new JoinGroupRequest(TestConfig.GroupId(), TimeSpan.FromMilliseconds(heartbeatMilliseconds), "", ConsumerEncoder.Protocol, new [] { protocol });
            var memberId = Guid.NewGuid().ToString("N");
            var response = new JoinGroupResponse(ErrorCode.NONE, 1, protocol.protocol_name, memberId, memberId, new [] { new JoinGroupResponse.Member(memberId, new ConsumerProtocolMetadata("mine")) });

            lastHeartbeat = DateTimeOffset.UtcNow;

            using (new GroupConsumer(router, request.group_id, request.protocol_type, response)) {
                await Task.Delay(totalMilliseconds);
            }

            foreach (var interval in heartbeatIntervals)
            {
                Assert.That((int)interval.TotalMilliseconds, Is.AtMost(heartbeatMilliseconds));
            }
        }
Exemplo n.º 4
0
        public async Task ConsumerHeartbeatsUntilDisposed(int heartbeatMilliseconds)
        {
            var protocol = new JoinGroupRequest.GroupProtocol(new ConsumerProtocolMetadata("mine"));
            var router   = Substitute.For <IRouter>();
            var conn     = Substitute.For <IConnection>();

            router.GetConnectionAsync(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(conn));
            router.SyncGroupAsync(Arg.Any <SyncGroupRequest>(), Arg.Any <IRequestContext>(), Arg.Any <IRetry>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(new SyncGroupResponse(ErrorCode.NONE, new ConsumerMemberAssignment(new [] { new TopicPartition("name", 0) }))));
            conn.SendAsync(Arg.Any <HeartbeatRequest>(), Arg.Any <CancellationToken>(), Arg.Any <IRequestContext>())
            .Returns(_ => Task.FromResult(new HeartbeatResponse(ErrorCode.NETWORK_EXCEPTION)));

            var heartbeat = TimeSpan.FromMilliseconds(heartbeatMilliseconds);
            var config    = new ConsumerConfiguration(heartbeatTimeout: heartbeat, coordinationRetry: Retry.Until(heartbeat, maximumDelay: TimeSpan.FromMilliseconds(50)));
            var request   = new JoinGroupRequest(TestConfig.GroupId(), config.GroupHeartbeat, "", ConsumerEncoder.Protocol, new [] { protocol });
            var memberId  = Guid.NewGuid().ToString("N");
            var response  = new JoinGroupResponse(ErrorCode.NONE, 1, protocol.protocol_name, memberId, memberId, new [] { new JoinGroupResponse.Member(memberId, new ConsumerProtocolMetadata("mine")) });

            using (new GroupConsumer(router, request.group_id, request.protocol_type, response, config)) {
                await Task.Delay(heartbeatMilliseconds * 3);

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                conn.DidNotReceive().SendAsync(
                    Arg.Is((LeaveGroupRequest s) => s.group_id == request.group_id && s.member_id == memberId),
                    Arg.Any <CancellationToken>(),
                    Arg.Any <IRequestContext>());
            }
            conn.Received().SendAsync(
                Arg.Is((LeaveGroupRequest s) => s.group_id == request.group_id && s.member_id == memberId),
                Arg.Any <CancellationToken>(),
                Arg.Any <IRequestContext>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

            Assert.That(conn.ReceivedCalls().Count(c => c.GetMethodInfo().Name == nameof(Connection.SendAsync) && (c.GetArguments()[0] as HeartbeatRequest) != null), Is.AtLeast(2));
        }
Exemplo n.º 5
0
        public async Task ConsumerHeartbeatsAtDesiredIntervals(int expectedHeartbeats, int heartbeatMilliseconds, int totalMilliseconds)
        {
            var protocol = new JoinGroupRequest.GroupProtocol(new ConsumerProtocolMetadata("mine"));
            var router   = Substitute.For <IRouter>();
            var conn     = Substitute.For <IConnection>();

            router.GetConnectionAsync(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(conn));
            router.SyncGroupAsync(Arg.Any <SyncGroupRequest>(), Arg.Any <IRequestContext>(), Arg.Any <IRetry>(), Arg.Any <CancellationToken>())
            .Returns(_ => Task.FromResult(new SyncGroupResponse(ErrorCode.NONE, new ConsumerMemberAssignment(new [] { new TopicPartition("name", 0) }))));
            conn.SendAsync(Arg.Any <HeartbeatRequest>(), Arg.Any <CancellationToken>(), Arg.Any <IRequestContext>())
            .Returns(_ => Task.FromResult(new HeartbeatResponse(ErrorCode.NONE)));

            var config   = new ConsumerConfiguration(heartbeatTimeout: TimeSpan.FromMilliseconds(heartbeatMilliseconds * 2));
            var request  = new JoinGroupRequest(TestConfig.GroupId(), config.GroupHeartbeat, "", ConsumerEncoder.Protocol, new [] { protocol });
            var memberId = Guid.NewGuid().ToString("N");
            var response = new JoinGroupResponse(ErrorCode.NONE, 1, protocol.protocol_name, memberId, memberId, new [] { new JoinGroupResponse.Member(memberId, new ConsumerProtocolMetadata("mine")) });

            using (new GroupConsumer(router, request.group_id, request.protocol_type, response, config)) {
                await Task.Delay(totalMilliseconds);
            }

            Assert.That(conn.ReceivedCalls()
                        .Count(c => {
                if (c.GetMethodInfo().Name != nameof(Connection.SendAsync))
                {
                    return(false);
                }
                var s = c.GetArguments()[0] as HeartbeatRequest;
                if (s == null)
                {
                    return(false);
                }
                return(s.group_id == request.group_id && s.member_id == memberId && s.generation_id == response.generation_id);
            }), Is.InRange(expectedHeartbeats - 1, expectedHeartbeats + 1));
        }