private void WarningIfOffsetNotContinuous(AckHandler tail, AckHandler handler) { if (tail.PullLogOffset + 1 != handler.PullLogOffset) { LOG.Warn($"Qmq.Consume.PullOffsetNotContinuous {Subject}/{Group}/{_brokerGroup}"); } }
private bool AllowSendAck(AckHandler lastAckedHandler) { if (lastAckedHandler.Next == null) { return(true); } return(lastAckedHandler.PullLogOffset - _head.PullLogOffset >= MinAckBatch); }
public void HandleAck(AckHandler handler) { bool needSendRequests = HandleNormalAckRequests(handler); if (needSendRequests) { TriggerAckSender(); } }
// TODO(keli.wang): when one ack delay and blocks many other acks, can we just make this one a nack? private bool HandleNormalAckRequests(AckHandler handler) { lock (_updateGuard) { if (handler != _beginScanPosition) { return(false); } var handlers = ContinuousCompleteHandlers(); _beginScanPosition = handlers[handlers.Count - 1].Item2.Next; if (handlers.Count == 1) { if (!AllowSendAck(handlers[0].Item2)) { return(false); } } var requests = new List <AckRequest>(handlers.Count); foreach (var segment in handlers) { var request = new AckRequest { Subject = Subject, Group = Group, IsBroadcast = _isBroadcast, ConsumerId = ClientId.CurrentClientId, PullOffsetBegin = segment.Item1.PullLogOffset, PullOffsetEnd = segment.Item2.PullLogOffset, }; requests.Add(request); } _head = _beginScanPosition; // All message is acked, need reset head and tail if (_head == null) { _tail = null; } UpdateLastAckTime(); EnqueueRequests(requests); return(true); } }
private bool HandleForceSendAckRequests() { lock (_updateGuard) { if (DateTime.Now.ToTime() - _lastAckTime < TryForceSendAckIntervalSeconds * 1000) { return(false); } if (_head == null || !_head.Completed) { EnqueueRequests(new List <AckRequest> { CreateEmptyAckRequest() }); return(true); } var handlers = ContinuousCompleteHandlers(); _beginScanPosition = handlers[handlers.Count - 1].Item2.Next; var requests = new List <AckRequest>(handlers.Count); foreach (var segment in handlers) { var request = new AckRequest { Subject = Subject, Group = Group, IsBroadcast = _isBroadcast, ConsumerId = ClientId.CurrentClientId, PullOffsetBegin = segment.Item1.PullLogOffset, PullOffsetEnd = segment.Item2.PullLogOffset, }; requests.Add(request); } _head = _beginScanPosition; // All message is acked, need reset head and tail if (_head == null) { _tail = null; } UpdateLastAckTime(); EnqueueRequests(requests); return(true); } }
private AckHandler AckquireHandler(BaseMessage message) { lock (_updateGuard) { var pullLogOffset = PullLogOffset(message); var handler = new AckHandler(pullLogOffset, message, this); if (_head == null) { _beginScanPosition = _head = handler; MinPullOffset = pullLogOffset; } if (_tail != null) { WarningIfOffsetNotContinuous(_tail, handler); _tail.Next = handler; } _tail = handler; MaxPullOffset = pullLogOffset; return(handler); } }