private void QueryLatestOffset(ConsumerLeaseKey key, long correlationId) { while (!IsClosed() && !leaseRef.ReadFullFence().Expired) { Endpoint endpoint = EndpointManager.GetEndpoint(Context.Topic.Name, PartitionId); if (endpoint == null) { log.Warn(string.Format("No endpoint found for topic {0} partition {1}, will retry later", Context.Topic.Name, PartitionId)); noEndpointSchedulePolicy.Fail(true); continue; } else { noEndpointSchedulePolicy.Succeess(); } SettableFuture<QueryOffsetResultCommand> future = SettableFuture<QueryOffsetResultCommand>.Create(); QueryOffsetCommand cmd = new QueryOffsetCommand(Context.Topic.Name, PartitionId, Context.GroupId); cmd.Header.CorrelationId = correlationId; cmd.Future = future; QueryOffsetResultCommand offsetRes = null; int timeout = Config.QueryOffsetTimeoutMillis; queryOffsetResultMonitor.Monitor(cmd); EndpointClient.WriteCommand(endpoint, cmd, timeout); try { offsetRes = future.Get(timeout); } catch (Exception e) { } finally { queryOffsetResultMonitor.Remove(cmd); } if (offsetRes != null && offsetRes.Offset != null) { offset.WriteFullFence(offsetRes.Offset); return; } else { noEndpointSchedulePolicy.Fail(true); } } }
protected override void DoBeforeConsuming(ConsumerLeaseKey key, long correlationId) { noEndpointSchedulePolicy = new ExponentialSchedulePolicy(Config.NoEndpointWaitBaseMillis, Config.NoEndpointWaitMaxMillis); QueryLatestOffset(key, correlationId); // reset policy noEndpointSchedulePolicy.Succeess(); pullMessagesTask.WriteFullFence(new PullMessagesTask(correlationId, noEndpointSchedulePolicy, this)); }
protected override void DoAfterConsuming(ConsumerLeaseKey key, long correlationId) { pullMessagesTask.WriteFullFence(null); }
protected override void DoBeforeConsuming(ConsumerLeaseKey key, long correlationId) { ISchedulePolicy noEndpointSchedulePolicy = new ExponentialSchedulePolicy(Config.NoEndpointWaitBaseMillis, Config.NoEndpointWaitMaxMillis); pullMessagesTask.WriteFullFence(new DefaultPullMessagesTask(correlationId, noEndpointSchedulePolicy, this)); }
public RenewLeaseTask(ConsumerLeaseKey key, long delay) { Key = key; Delay = delay; }
protected abstract void DoAfterConsuming(ConsumerLeaseKey key, long correlationId);
private void AcquireLease(ConsumerLeaseKey key) { long nextTryTime = SystemClockService.Now(); while (!IsClosed()) { try { WaitForNextTryTime(nextTryTime); if (IsClosed()) { return; } LeaseAcquireResponse response = LeaseManager.TryAcquireLease(key); if (response != null && response.Acquired && !response.Lease.Expired) { leaseRef.WriteFullFence(response.Lease); ScheduleRenewLeaseTask(key, leaseRef.ReadFullFence().RemainingTime - Config.RenewLeaseTimeMillisBeforeExpired); return; } else { if (response != null && response.NextTryTime > 0) { nextTryTime = response.NextTryTime; } else { nextTryTime = SystemClockService.Now() + Config.DefaultLeaseAcquireDelayMillis; } } } catch (Exception e) { log.Error(string.Format("Exception occurred while acquiring lease(topic={0}, partition={1}, groupId={2}, sessionId={3})", Context.Topic.Name, PartitionId, Context.GroupId, Context.SessionId), e); } } }
protected void ScheduleRenewLeaseTask(ConsumerLeaseKey key, long delay) { int sKey = scheduleKey.AtomicAddAndGet(1); renewLeaseTaskExecutor.Produce(sKey, new RenewLeaseTask(key, delay), (int)delay); }
private void StartConsuming(ConsumerLeaseKey key, long correlationId) { ConsumerNotifier.Register(correlationId, Context); DoBeforeConsuming(key, correlationId); msgs.Clear(); ISchedulePolicy noMessageSchedulePolicy = new ExponentialSchedulePolicy(Config.NoMessageWaitBaseMillis, Config.NoMessageWaitMaxMillis); while (!IsClosed() && !leaseRef.ReadFullFence().Expired) { try { // if leaseRemainingTime < stopConsumerTimeMillsBeforLeaseExpired, stop if (leaseRef.ReadFullFence().RemainingTime <= Config.StopConsumerTimeMillsBeforLeaseExpired) { break; } if (msgs.Count == 0) { SchedulePullMessagesTask(); } if (msgs.Count != 0) { ConsumeMessages(correlationId); noMessageSchedulePolicy.Succeess(); } else { noMessageSchedulePolicy.Fail(true); } } catch (Exception e) { log.Error(string.Format("Exception occurred while consuming message(topic={0}, partition={1}, groupId={2}, sessionId={3})", Context.Topic.Name, PartitionId, Context.GroupId, Context.SessionId), e); } } ConsumerNotifier.Deregister(correlationId); leaseRef.WriteFullFence(null); DoAfterConsuming(key, correlationId); }
public void Start() { log.Info(string.Format("Consumer started(mode={0}, topic={1}, partition={2}, groupId={3}, sessionId={4})", Context.ConsumerType, Context.Topic.Name, PartitionId, Context.GroupId, Context.SessionId)); ConsumerLeaseKey key = new ConsumerLeaseKey(new Tpg(Context.Topic.Name, PartitionId, Context.GroupId), Context.SessionId); while (!IsClosed()) { try { AcquireLease(key); if (!IsClosed() && leaseRef.ReadFullFence() != null && !leaseRef.ReadFullFence().Expired) { long correlationId = CorrelationIdGenerator.generateCorrelationId(); log.Info(string.Format( "Consumer continue consuming(mode={0}, topic={1}, partition={2}, groupId={3}, correlationId={4}, sessionId={5}), since lease acquired", Context.ConsumerType, Context.Topic.Name, PartitionId, Context.GroupId, correlationId, Context.SessionId)); StartConsuming(key, correlationId); log.Info(string.Format( "Consumer pause consuming(mode={0}, topic={1}, partition={2}, groupId={3}, correlationId={4}, sessionId={5}), since lease expired", Context.ConsumerType, Context.Topic.Name, PartitionId, Context.GroupId, correlationId, Context.SessionId)); } } catch (Exception e) { log.Error(string.Format("Exception occurred in consumer's run method(topic={0}, partition={1}, groupId={2}, sessionId={3})", Context.Topic.Name, PartitionId, Context.GroupId, Context.SessionId), e); } } pullMessageTaskExecutor.Shutdown(); renewLeaseTaskExecutor.Shutdown(); log.Info(string.Format("Consumer stopped(mode={0}, topic={1}, partition={2}, groupId={3}, sessionId={4})", Context.ConsumerType, Context.Topic.Name, PartitionId, Context.GroupId, Context.SessionId)); }