/// <summary> /// Take responsibility for a new queues that was assigned to me via a new range. /// We first store the new queue in our internal data structure, try to initialize it and start a pumping timer. /// ERROR HANDLING: /// The resposibility to handle initializatoion and shutdown failures is inside the INewQueueAdapterReceiver code. /// The agent will call Initialize once and log an error. It will not call initiliaze again. /// The receiver itself may attempt later to recover from this error and do initialization again. /// The agent will assume initialization has succeeded and will subsequently start calling pumping receive. /// Same applies to shutdown. /// </summary> /// <param name="qAdapter"></param> /// <param name="queueAdapterCache"></param> /// <param name="failureHandler"></param> /// <returns></returns> public async Task Initialize(Immutable<IQueueAdapter> qAdapter, Immutable<IQueueAdapterCache> queueAdapterCache, Immutable<IStreamFailureHandler> failureHandler) { if (qAdapter.Value == null) throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null"); if (failureHandler.Value == null) throw new ArgumentNullException("failureHandler", "Init: streamDeliveryFailureHandler should not be null"); logger.Info((int)ErrorCode.PersistentStreamPullingAgent_02, "Init of {0} {1} on silo {2} for queue {3}.", GetType().Name, GrainId.ToDetailedString(), Silo, QueueId.ToStringWithHashCode()); // Remove cast once we cleanup queueAdapter = qAdapter.Value; streamFailureHandler = failureHandler.Value; lastTimeCleanedPubSubCache = DateTime.UtcNow; try { receiver = queueAdapter.CreateReceiver(QueueId); } catch (Exception exc) { logger.Error((int)ErrorCode.PersistentStreamPullingAgent_02, "Exception while calling IQueueAdapter.CreateNewReceiver.", exc); return; } try { if (queueAdapterCache.Value != null) { queueCache = queueAdapterCache.Value.CreateQueueCache(QueueId); } } catch (Exception exc) { logger.Error((int)ErrorCode.PersistentStreamPullingAgent_23, "Exception while calling IQueueAdapterCache.CreateQueueCache.", exc); return; } try { var task = OrleansTaskExtentions.SafeExecute(() => receiver.Initialize(config.InitQueueTimeout)); task = task.LogException(logger, ErrorCode.PersistentStreamPullingAgent_03, String.Format("QueueAdapterReceiver {0} failed to Initialize.", QueueId.ToStringWithHashCode())); await task; } catch { // Just ignore this exception and proceed as if Initialize has succeeded. // We already logged individual exceptions for individual calls to Initialize. No need to log again. } // Setup a reader for a new receiver. // Even if the receiver failed to initialise, treat it as OK and start pumping it. It's receiver responsibility to retry initialization. var randomTimerOffset = safeRandom.NextTimeSpan(config.GetQueueMsgsTimerPeriod); timer = base.RegisterTimer(AsyncTimerCallback, QueueId, randomTimerOffset, config.GetQueueMsgsTimerPeriod); logger.Info((int) ErrorCode.PersistentStreamPullingAgent_04, "Taking queue {0} under my responsibility.", QueueId.ToStringWithHashCode()); }
private void InitializeInternal(IQueueAdapter qAdapter, IQueueAdapterCache queueAdapterCache, IStreamFailureHandler failureHandler) { logger.Info(ErrorCode.PersistentStreamPullingAgent_02, "Init of {0} {1} on silo {2} for queue {3}.", GetType().Name, GrainId.ToDetailedString(), Silo, QueueId.ToStringWithHashCode()); // Remove cast once we cleanup queueAdapter = qAdapter; streamFailureHandler = failureHandler; lastTimeCleanedPubSubCache = DateTime.UtcNow; try { receiver = queueAdapter.CreateReceiver(QueueId); } catch (Exception exc) { logger.Error(ErrorCode.PersistentStreamPullingAgent_02, "Exception while calling IQueueAdapter.CreateNewReceiver.", exc); throw; } try { if (queueAdapterCache != null) { queueCache = queueAdapterCache.CreateQueueCache(QueueId); } } catch (Exception exc) { logger.Error(ErrorCode.PersistentStreamPullingAgent_23, "Exception while calling IQueueAdapterCache.CreateQueueCache.", exc); throw; } try { receiverInitTask = OrleansTaskExtentions.SafeExecute(() => receiver.Initialize(config.InitQueueTimeout)) .LogException(logger, ErrorCode.PersistentStreamPullingAgent_03, $"QueueAdapterReceiver {QueueId.ToStringWithHashCode()} failed to Initialize."); receiverInitTask.Ignore(); } catch { // Just ignore this exception and proceed as if Initialize has succeeded. // We already logged individual exceptions for individual calls to Initialize. No need to log again. } // Setup a reader for a new receiver. // Even if the receiver failed to initialise, treat it as OK and start pumping it. It's receiver responsibility to retry initialization. var randomTimerOffset = safeRandom.NextTimeSpan(config.GetQueueMsgsTimerPeriod); timer = RegisterTimer(AsyncTimerCallback, QueueId, randomTimerOffset, config.GetQueueMsgsTimerPeriod); logger.Info((int)ErrorCode.PersistentStreamPullingAgent_04, "Taking queue {0} under my responsibility.", QueueId.ToStringWithHashCode()); }
internal PersistentStreamPullingAgent( GrainId id, string strProviderName, IStreamProviderRuntime runtime, IStreamPubSub streamPubSub, QueueId queueId, PersistentStreamProviderConfig config) : base(id, runtime.ExecutingSiloAddress, true) { if (runtime == null) { throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: runtime reference should not be null"); } if (strProviderName == null) { throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: strProviderName should not be null"); } QueueId = queueId; streamProviderName = strProviderName; providerRuntime = runtime; pubSub = streamPubSub; pubSubCache = new Dictionary <StreamId, StreamConsumerCollection>(); safeRandom = new SafeRandom(); this.config = config; numMessages = 0; logger = providerRuntime.GetLogger(GrainId + "-" + streamProviderName); logger.Info((int)ErrorCode.PersistentStreamPullingAgent_01, "Created {0} {1} for Stream Provider {2} on silo {3} for Queue {4}.", GetType().Name, GrainId.ToDetailedString(), streamProviderName, Silo, QueueId.ToStringWithHashCode()); numReadMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_READ_MESSAGES, strProviderName)); numSentMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_SENT_MESSAGES, strProviderName)); string statUniquePostfix = strProviderName + "-" + queueId; IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_PUBSUB_CACHE_SIZE, statUniquePostfix), () => pubSubCache.Count); IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_QUEUE_CACHE_SIZE, statUniquePostfix), () => queueCache != null ? queueCache.Size : 0); }
internal PersistentStreamPullingAgent( GrainId id, string strProviderName, IStreamProviderRuntime runtime, IStreamPubSub streamPubSub, QueueId queueId, TimeSpan queueGetPeriod, TimeSpan initQueueTimeout, TimeSpan maxDeliveryTime) : base(id, runtime.ExecutingSiloAddress, true) { if (runtime == null) { throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: runtime reference should not be null"); } if (strProviderName == null) { throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: strProviderName should not be null"); } QueueId = queueId; streamProviderName = strProviderName; providerRuntime = runtime; pubSub = streamPubSub; pubSubCache = new Dictionary <StreamId, StreamConsumerCollection>(); safeRandom = new SafeRandom(); this.queueGetPeriod = queueGetPeriod; this.initQueueTimeout = initQueueTimeout; this.maxDeliveryTime = maxDeliveryTime; numMessages = 0; logger = providerRuntime.GetLogger(GrainId + "-" + streamProviderName); logger.Info((int)ErrorCode.PersistentStreamPullingAgent_01, "Created {0} {1} for Stream Provider {2} on silo {3} for Queue {4}.", GetType().Name, GrainId.ToDetailedString(), streamProviderName, Silo, QueueId.ToStringWithHashCode()); numReadMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_READ_MESSAGES, strProviderName)); numSentMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_SENT_MESSAGES, strProviderName)); }