public override async Task OnActivateAsync() { // set current grain key as aggregateName var nameSplit = GrainReference.GetPrimaryKeyString().Split(':'); var rootAggregateName = nameSplit[0]; _aggregateName = nameSplit[1]; // set metric names _underPressureMetricName = $"StreamDispatcher.{_aggregateName}.UnderPressure"; _queueSizeMetricName = $"StreamDispatcher.{_aggregateName}.QueueSize"; // get IAggregateStreamSettings instance from service collection filtered by grainKey var aggregateStreamSettings = ServiceProvider.GetServices <IAggregateStreamSettings>().FirstOrDefault(g => g.AggregateName == rootAggregateName); // throw if not able to get StreamSettings if (aggregateStreamSettings == null) { throw new InvalidOperationException($"unable to retrieve IAggregateStreamSettings for {nameSplit[0]}"); } // store grain resolver if (!aggregateStreamSettings.EventDispatcherSettingsMap.TryGetValue(_aggregateName, out _eventDispatcherSettings)) { throw new InvalidOperationException($"unable to retrieve EventDispatcherSettings for {_aggregateName}"); } if (_eventDispatcherSettings.PersistDispatcherState) { // call base OnActivateAsync await base.OnActivateAsync(); // set LastNotifiedEventVersion if needed if (State.LastNotifiedEventId == 0) { // get last event from db var lastEvent = await EventSource.GetLastAggregateEvent(rootAggregateName); // get LastNotifiedEventVersion as latest aggregate version from db or 0 await ApplyEvent(new UpdatedLastNotifiedEventId { LastNotifiedEventId = lastEvent?.Id ?? 0 }); // sync up lastQueuedEventId and LastNotifiedEventId _lastQueuedEventId = State.LastNotifiedEventId; } // sync up lastQueuedEventId and LastNotifiedEventId _lastQueuedEventId = State.LastNotifiedEventId; } // register pollForEvents method this.RegisterTimer(NotifySubscribers, null, TimeSpan.FromSeconds(1), _notifyInterval); // register metrics reporter this.RegisterTimer(ReportMetrics, null, TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(1)); }