public async Task <IPersistentStreamPullingManager> InitializePullingAgents( string streamProviderName, IQueueAdapterFactory adapterFactory, IQueueAdapter queueAdapter) { IStreamQueueBalancer queueBalancer = CreateQueueBalancer(streamProviderName); var managerId = SystemTargetGrainId.Create(Constants.StreamPullingAgentManagerType, this.siloDetails.SiloAddress, streamProviderName); var pubsubOptions = this.ServiceProvider.GetOptionsByName <StreamPubSubOptions>(streamProviderName); var pullingAgentOptions = this.ServiceProvider.GetOptionsByName <StreamPullingAgentOptions>(streamProviderName); var filter = this.ServiceProvider.GetServiceByName <IStreamFilter>(streamProviderName) ?? new NoOpStreamFilter(); var manager = new PersistentStreamPullingManager( managerId, streamProviderName, this.PubSub(pubsubOptions.PubSubType), adapterFactory, queueBalancer, filter, pullingAgentOptions, this.loggerFactory, this.siloDetails.SiloAddress, queueAdapter); var catalog = this.ServiceProvider.GetRequiredService <Catalog>(); catalog.RegisterSystemTarget(manager); // Init the manager only after it was registered locally. var pullingAgentManager = manager.AsReference <IPersistentStreamPullingManager>(); // Need to call it as a grain reference though. await pullingAgentManager.Initialize(); return(pullingAgentManager); }
public TGrainInterface GetSystemTarget <TGrainInterface>(GrainType grainType, SiloAddress destination) where TGrainInterface : ISystemTarget { var grainId = SystemTargetGrainId.Create(grainType, destination); return(this.GetSystemTarget <TGrainInterface>(grainId.GrainId)); }
/// <summary> /// Take responsibility for a set of new queues that were assigned to me via a new range. /// We first create one pulling agent for every new queue and store them in our internal data structure, then try to initialize the agents. /// ERROR HANDLING: /// The responsibility to handle initialization and shutdown failures is inside the Agents code. /// The manager will call Initialize once and log an error. It will not call initialize again and will assume initialization has succeeded. /// Same applies to shutdown. /// </summary> /// <param name="myQueues"></param> /// <param name="failOnInit"></param> /// <returns></returns> private async Task AddNewQueues(IEnumerable <QueueId> myQueues, bool failOnInit) { // Create agents for queues in range that we don't yet have. // First create them and store in local queuesToAgentsMap. // Only after that Initialize them all. var agents = new List <PersistentStreamPullingAgent>(); foreach (var queueId in myQueues) { if (queuesToAgentsMap.ContainsKey(queueId)) { continue; } try { var agentIdNumber = Interlocked.Increment(ref nextAgentId); var agentId = SystemTargetGrainId.Create(Constants.StreamPullingAgentType, this.Silo, $"{streamProviderName}_{agentIdNumber}_{queueId.ToStringWithHashCode()}"); IStreamFailureHandler deliveryFailureHandler = await adapterFactory.GetDeliveryFailureHandler(queueId); var agent = new PersistentStreamPullingAgent(agentId, streamProviderName, this.loggerFactory, pubSub, streamFilter, queueId, this.options, this.Silo, queueAdapter, queueAdapterCache, deliveryFailureHandler); this.ActivationServices.GetRequiredService <Catalog>().RegisterSystemTarget(agent); queuesToAgentsMap.Add(queueId, agent); agents.Add(agent); } catch (Exception exc) { logger.Error(ErrorCode.PersistentStreamPullingManager_07, "Exception while creating PersistentStreamPullingAgent.", exc); // What should we do? This error is not recoverable and considered a bug. But we don't want to bring the silo down. // If this is when silo is starting and agent is initializing, fail the silo startup. Otherwise, just swallow to limit impact on other receivers. if (failOnInit) { throw; } } } try { var initTasks = new List <Task>(); foreach (var agent in agents) { initTasks.Add(InitAgent(agent)); } await Task.WhenAll(initTasks); } 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. } if (agents.Count > 0) { Log(ErrorCode.PersistentStreamPullingManager_08, "Added {0} new queues: {1}. Now own total of {2} queues: {3}", agents.Count, Utils.EnumerableToString(agents, agent => agent.QueueId.ToString()), NumberRunningAgents, PrintQueues(queuesToAgentsMap.Keys)); } }
private static SystemTargetGrainId CreateId(ILocalSiloDetails localSiloDetails) { return(SystemTargetGrainId.Create(Constants.SystemMembershipTableType, SiloAddress.New(localSiloDetails.SiloAddress.Endpoint, 0))); }