public async Task SyncGroupAsync(CancellationToken cancellationToken)
        {
            if (_disposeCount > 0)
            {
                throw new ObjectDisposedException($"Consumer {{GroupId:{GroupId},MemberId:{MemberId}}} is no longer valid");
            }

            var groupAssignments = await _joinSemaphore.LockAsync(
                async() => {
                if (IsLeader)
                {
                    var encoder     = Encoders[ProtocolType];
                    var assigner    = encoder.GetAssignor(_groupProtocol);
                    var assignments = await assigner.AssignMembersAsync(Router, GroupId, GenerationId, _memberMetadata, cancellationToken).ConfigureAwait(false);
                    return(assignments.Select(pair => new SyncGroupRequest.GroupAssignment(pair.Key, pair.Value)));
                }
                return(null);
            }, _disposeToken.Token).ConfigureAwait(false);

            await Task.WhenAll(_batches.Values.Select(b => b.CommitMarkedIgnoringDisposedAsync(cancellationToken))).ConfigureAwait(false);

            SyncGroupResponse response;

            try {
                var request = new SyncGroupRequest(GroupId, GenerationId, MemberId, groupAssignments);
                response = await Router.SyncGroupAsync(request, new RequestContext(protocolType : ProtocolType), Configuration.GroupCoordinationRetry, cancellationToken).ConfigureAwait(false);
            } catch (RequestException ex) {
                switch (ex.ErrorCode)
                {
                case ErrorCode.REBALANCE_IN_PROGRESS:
                    Router.Log.Info(() => LogEvent.Create(ex.Message));
                    TriggerRejoin();
                    return;

                case ErrorCode.GROUP_AUTHORIZATION_FAILED:
                case ErrorCode.UNKNOWN_MEMBER_ID:
                    Router.Log.Warn(() => LogEvent.Create(ex));
                    _leaveOnDispose = false;     // no point in attempting to leave the group since it will fail
                    _disposeToken.Cancel();
                    break;
                }
                throw;
            }

            _syncSemaphore.Lock(() => {
                _assignment           = response.member_assignment;
                var validPartitions   = response.member_assignment.PartitionAssignments.ToImmutableHashSet();
                var invalidPartitions = _batches.Where(pair => !validPartitions.Contains(pair.Key)).ToList();
                foreach (var invalidPartition in invalidPartitions)
                {
                    invalidPartition.Value.Dispose();
                }
                _batches = _batches.RemoveRange(invalidPartitions.Select(pair => pair.Key));
            }, _disposeToken.Token);

            if (Interlocked.Increment(ref _syncCount) == 1)
            {
                _fetchSemaphore.Release();
            }
        }
        public SyncGroupResponse(ErrorCode errorCode, IMemberAssignment memberAssignment)
        {
            error_code = errorCode;
            Errors     = ImmutableList <ErrorCode> .Empty.Add(error_code);

            member_assignment = memberAssignment;
        }
 public Member(string memberId, string clientId, string clientHost, IMemberMetadata memberMetadata, IMemberAssignment memberAssignment)
 {
     MemberId         = memberId;
     ClientId         = clientId;
     ClientHost       = clientHost;
     MemberMetadata   = memberMetadata;
     MemberAssignment = memberAssignment;
 }
Exemple #4
0
 public Member(string memberId, string clientId, string clientHost, IMemberMetadata memberMetadata, IMemberAssignment memberAssignment)
 {
     member_id         = memberId;
     client_id         = clientId;
     client_host       = clientHost;
     member_metadata   = memberMetadata;
     member_assignment = memberAssignment;
 }
        public async Task DisposeAsync()
        {
            if (Interlocked.Increment(ref _disposeCount) != 1)
            {
                await _disposePromise.Task;
                return;
            }

            try {
                Router.Log.Debug(() => LogEvent.Create($"Disposing Consumer {{GroupId:{GroupId},MemberId:{MemberId}}}"));
                _disposeToken.Cancel();
                _fetchSemaphore.Dispose();
                _joinSemaphore.Dispose();
                _syncSemaphore.Dispose();

                try {
                    var batches = Interlocked.Exchange(ref _batches, ImmutableDictionary <TopicPartition, IMessageBatch> .Empty);
                    await Task.WhenAll(batches.Values.Select(b => b.CommitMarkedAsync(CancellationToken.None))).ConfigureAwait(false);

                    foreach (var batch in batches.Values)
                    {
                        batch.Dispose();
                    }
                } catch (Exception ex) {
                    Router.Log.Info(() => LogEvent.Create(ex));
                }
                _assignment = null;

                try {
                    await Task.WhenAny(_heartbeatTask, _stateChangeTask, Task.Delay(TimeSpan.FromSeconds(1), CancellationToken.None)).ConfigureAwait(false);

                    if (_leaveOnDispose)
                    {
                        var request = new LeaveGroupRequest(GroupId, MemberId);
                        await Router.SendAsync(request, GroupId, CancellationToken.None, retryPolicy : Retry.None).ConfigureAwait(false);
                    }
                } catch (Exception ex) {
                    Router.Log.Info(() => LogEvent.Create(ex));
                }

                if (!_leaveRouterOpen)
                {
                    await Router.DisposeAsync();
                }
                _disposeToken.Dispose();
            } finally {
                _disposePromise.TrySetResult(true);
            }
        }
 public MemberHandler(IMemberAssignment assignment) => _assignment = assignment;
Exemple #7
0
 /// <inheritdoc />
 public void EncodeAssignment(IKafkaWriter writer, IMemberAssignment value)
 {
     using (writer.MarkForLength()) {
         EncodeAssignment(writer, (TAssignment)value);
     }
 }
 public GroupAssignment(string memberId, IMemberAssignment memberAssignment)
 {
     member_id         = memberId;
     member_assignment = memberAssignment;
 }
Exemple #9
0
 public static IKafkaWriter Write(this IKafkaWriter writer, IMemberAssignment assignment, IProtocolTypeEncoder encoder)
 {
     encoder.EncodeAssignment(writer, assignment);
     return(writer);
 }
Exemple #10
0
 public GroupAssignment(string memberId, IMemberAssignment memberAssignment)
 {
     MemberId         = memberId;
     MemberAssignment = memberAssignment;
 }
 /// <inheritdoc />
 public void EncodeAssignment(IKafkaWriter writer, IMemberAssignment value)
 {
     EncodeAssignment(writer, (TAssignment)value);
 }