Beispiel #1
0
        /// <inheritdoc/>
        public override Task Initialize(string strProviderName, IStreamQueueMapper queueMapper, TimeSpan siloMaturityPeriod)
        {
            if (queueMapper == null)
            {
                throw new ArgumentNullException("queueMapper");
            }
            var options = this.serviceProvider.GetRequiredService <IOptionsSnapshot <LeaseBasedQueueBalancerOptions> >().Get(strProviderName);

            if (options == null)
            {
                throw new KeyNotFoundException($"No lease base queue balancer options was configured for provider {strProviderName}, nor was a default configured.");
            }
            this.leaseProvider      = this.serviceProvider.GetRequiredService(options.LeaseProviderType) as ILeaseProvider;
            this.leaseLength        = options.LeaseLength;
            this.allQueues          = new ReadOnlyCollection <QueueId>(queueMapper.GetAllQueues().ToList());
            this.siloMaturityPeriod = siloMaturityPeriod;
            NotifyAfterStart().Ignore();
            //make lease renew frequency to be every half of lease time, to avoid renew failing due to timing issues, race condition or clock difference.
            var timerLogger = this.loggerFactory.CreateLogger <AsyncTaskSafeTimer>();

            this.renewLeaseTimer = new AsyncTaskSafeTimer(timerLogger, this.MaintainAndBalanceQueues, null, this.siloMaturityPeriod, this.leaseLength.Divide(2));
            //try to acquire maximum leases every leaseLength
            this.tryAcquireMaximumLeaseTimer = new AsyncTaskSafeTimer(timerLogger, this.AcquireLeaseToMeetMaxResponsibilty, null, this.siloMaturityPeriod, this.leaseLength);
            //Selector default to round robin selector now, but we can make a further change to make selector configurable if needed.  Selector algorithm could
            //be affecting queue balancing stablization time in cluster initializing and auto-scaling
            this.queueSelector = new RoundRobinSelector <QueueId>(this.allQueues);
            return(MaintainAndBalanceQueues(null));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 public LeaseBasedQueueBalancer(string name, LeaseBasedQueueBalancerOptions options, ILeaseProvider leaseProvider, ITimerRegistry timerRegistry, IServiceProvider services, ILoggerFactory loggerFactory)
     : base(services, loggerFactory.CreateLogger($"{typeof(LeaseBasedQueueBalancer).FullName}.{name}"))
 {
     this.options       = options;
     this.leaseProvider = leaseProvider;
     this.timerRegistry = timerRegistry;
 }
 /// <summary>
 /// Constructor
 /// </summary>
 public LeaseBasedQueueBalancer(string name, LeaseBasedQueueBalancerOptions options, ILeaseProvider leaseProvider, ITimerRegistry timerRegistry, IServiceProvider services, ILoggerFactory loggerFactory)
     : base(services, loggerFactory.CreateLogger($"{nameof(LeaseBasedQueueBalancer)}-{name}"))
 {
     this.options       = options;
     this.leaseProvider = leaseProvider;
     this.timerRegistry = timerRegistry;
     this.executor      = new AsyncSerialExecutor();
     this.myQueues      = new List <AcquiredQueue>();
 }
 public LeaseProviderActor(ILeaseProvider leaseProvider,
                           IMessageSerializer messageSerializer,
                           LeaseProviderConfiguration leaseProviderConfiguration,
                           ILogger logger)
 {
     this.leaseProvider     = leaseProvider;
     this.messageSerializer = messageSerializer;
     this.logger            = logger;
     clusterName            = leaseProviderConfiguration.ClusterName.GetBytes();
 }
Beispiel #5
0
 private async Task EnsureWorkflowInstanceIsNotBeingModified(string instanceId)
 {
     // The instance can be persisted but potentially also be being modified. To make sure it's not, attempt to take
     // out a lease on the instance.
     ILeaseProvider leaseProvider = this.serviceProvider.GetRequiredService <ILeaseProvider>();
     await leaseProvider.ExecuteWithMutexAsync(
         _ => Console.WriteLine($"Acquired lease for instance {instanceId}"),
         instanceId,
         new Linear(TimeSpan.FromSeconds(1), 30)).ConfigureAwait(false);
 }
 public RendezvousService(ILeaseProvider leaseProvider,
                          ISynodConfiguration synodConfig,
                          ISocketFactory socketFactory,
                          RendezvousConfiguration config,
                          ILogger logger)
 {
     this.socketFactory = socketFactory;
     this.logger = logger;
     localNode = synodConfig.LocalNode;
     this.leaseProvider = leaseProvider;
     this.config = config;
     cancellationTokenSource = new CancellationTokenSource();
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TenantedWorkflowEngineFactory"/> class.
 /// </summary>
 /// <param name="configuration">Configuration containing the base cloud event publisher source that will be used to create a tenant-specific source for the workflow engine.</param>
 /// <param name="workflowStoreFactory">The factory for retrieving tenanted workflow stores.</param>
 /// <param name="workflowInstanceStoreFactory">The factory for retrieving tenanted workflow instance stores.</param>
 /// <param name="leaseProvider">The lease provider.</param>
 /// <param name="cloudEventPublisherFactory">The publisher factory for workflow events.</param>
 /// <param name="logger">The logger.</param>
 public TenantedWorkflowEngineFactory(
     TenantedWorkflowEngineFactoryConfiguration configuration,
     ITenantedWorkflowStoreFactory workflowStoreFactory,
     ITenantedWorkflowInstanceStoreFactory workflowInstanceStoreFactory,
     ILeaseProvider leaseProvider,
     ITenantedCloudEventPublisherFactory cloudEventPublisherFactory,
     ILogger <IWorkflowEngine> logger)
 {
     this.leaseProvider                = leaseProvider ?? throw new ArgumentNullException(nameof(leaseProvider));
     this.logger                       = logger ?? throw new ArgumentNullException(nameof(logger));
     this.workflowStoreFactory         = workflowStoreFactory ?? throw new ArgumentNullException(nameof(workflowStoreFactory));
     this.workflowInstanceStoreFactory = workflowInstanceStoreFactory ?? throw new ArgumentNullException(nameof(workflowInstanceStoreFactory));
     this.cloudEventPublisherFactory   = cloudEventPublisherFactory ?? throw new ArgumentNullException(nameof(cloudEventPublisherFactory));
     this.configuration                = configuration;
 }
Beispiel #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WorkflowEngine"/> class.
        /// </summary>
        /// <param name="workflowStore">The repository in which to store workflows.</param>
        /// <param name="workflowInstanceStore">The repository in which to store workflow instances.</param>
        /// <param name="leaseProvider">The lease provider.</param>
        /// <param name="cloudEventSource">The source to use when publishing cloud events.</param>
        /// <param name="cloudEventPublisher">The publisher for workflow events.</param>
        /// <param name="logger">A logger for the workflow instance service.</param>
        public WorkflowEngine(
            IWorkflowStore workflowStore,
            IWorkflowInstanceStore workflowInstanceStore,
            ILeaseProvider leaseProvider,
            string cloudEventSource,
            ICloudEventDataPublisher cloudEventPublisher,
            ILogger <IWorkflowEngine> logger)
        {
            this.workflowStore         = workflowStore ?? throw new ArgumentNullException(nameof(workflowStore));
            this.workflowInstanceStore =
                workflowInstanceStore ?? throw new ArgumentNullException(nameof(workflowInstanceStore));

            this.leaseProvider       = leaseProvider ?? throw new ArgumentNullException(nameof(leaseProvider));
            this.logger              = logger ?? throw new ArgumentNullException(nameof(logger));
            this.cloudEventPublisher = cloudEventPublisher ?? throw new ArgumentNullException(nameof(cloudEventPublisher));
            this.cloudEventSource    = cloudEventSource;
        }
Beispiel #9
0
 public RendezvousService(ILeaseProvider leaseProvider,
                          ISynodConfigurationProvider synodConfigProvider,
                          ISocketFactory socketFactory,
                          IMessageSerializer serializer,
                          IRendezvousConfigurationProvider configProvider,
                          IPerformanceCounterManager <KinoPerformanceCounters> performanceCounterManager,
                          ILogger logger)
 {
     this.socketFactory             = socketFactory;
     this.logger                    = logger;
     this.serializer                = serializer;
     localNode                      = synodConfigProvider.LocalNode;
     this.leaseProvider             = leaseProvider;
     this.configProvider            = configProvider;
     this.performanceCounterManager = performanceCounterManager;
     cancellationTokenSource        = new CancellationTokenSource();
     pongMessage                    = Message.Create(new PongMessage());
     leaderPayload                  = serializer.Serialize(new RendezvousNode
     {
         BroadcastUri = configProvider.BroadcastUri.ToSocketAddress(),
         UnicastUri   = configProvider.UnicastUri.ToSocketAddress()
     });
 }
        /// <inheritdoc/>
        public override Task Initialize(IStreamQueueMapper queueMapper)
        {
            if (queueMapper == null)
            {
                throw new ArgumentNullException("queueMapper");
            }
            this.allQueues = new ReadOnlyCollection <QueueId>(queueMapper.GetAllQueues().ToList());
            if (this.allQueues.Count == 0)
            {
                return(Task.CompletedTask);
            }
            this.leaseProvider = this.serviceProvider.GetRequiredService(options.LeaseProviderType) as ILeaseProvider;
            NotifyAfterStart().Ignore();
            //make lease renew frequency to be every half of lease time, to avoid renew failing due to timing issues, race condition or clock difference.
            ITimerRegistry timerRegistry = this.serviceProvider.GetRequiredService <ITimerRegistry>();

            this.renewLeaseTimer = timerRegistry.RegisterTimer(null, this.MaintainAndBalanceQueues, null, this.options.SiloMaturityPeriod, this.options.LeaseLength.Divide(2));
            //try to acquire maximum leases every leaseLength
            this.tryAcquireMaximumLeaseTimer = timerRegistry.RegisterTimer(null, this.AcquireLeaseToMeetMaxResponsibility, null, this.options.SiloMaturityPeriod, this.options.SiloMaturityPeriod);
            //Selector default to round robin selector now, but we can make a further change to make selector configurable if needed.  Selector algorithm could
            //be affecting queue balancing stablization time in cluster initializing and auto-scaling
            this.queueSelector = new RoundRobinSelector <QueueId>(this.allQueues);
            return(MaintainAndBalanceQueues(null));
        }
Beispiel #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Lease"/> class.
 /// </summary>
 /// <param name="leaseProvider">The platform-specific lease provider.</param>
 /// <param name="leasePolicy">The lease policy.</param>
 /// <param name="id">The unique lease ID.</param>
 protected Lease(ILeaseProvider leaseProvider, LeasePolicy leasePolicy, string id)
 {
     this.LeaseProvider = leaseProvider ?? throw new ArgumentNullException(nameof(leaseProvider));
     this.LeasePolicy   = leasePolicy ?? throw new ArgumentNullException(nameof(leasePolicy));
     this.Id            = id;
 }
Beispiel #12
0
 protected GoldenPathLeaseProviderTestRunner(ILeaseProvider leaseProvider, ITestOutputHelper output)
 {
     this.leaseProvider = leaseProvider;
     this.output        = output;
 }
Beispiel #13
0
        private async Task <bool> TryAcquireLeaseAndExecuteAsync <T>(Func <CancellationToken, T, Task> action, CancellationTokenSource cancellationTokenSource, ILeaseProvider leaseProvider, T arg)
        {
            try
            {
                this.CheckProperties();

                await Retriable.RetryAsync(async() =>
                {
                    await this.AcquireLeaseAndExecuteInnerAsync(action, cancellationTokenSource, leaseProvider, arg);
                },
                                           cancellationTokenSource.Token,
                                           this.RetryStrategy,
                                           this.RetryPolicy);

                return(true);
            }
            catch (LeaseAcquisitionUnsuccessfulException)
            {
                return(false);
            }
        }
Beispiel #14
0
        private async Task <Tuple <bool, T> > TryAcquireLeaseAndExecuteAsync <T>(Func <CancellationToken, Task <T> > action, CancellationTokenSource cancellationTokenSource, ILeaseProvider leaseProvider)
        {
            try
            {
                this.CheckProperties();

                var result = await Retriable.RetryAsync(
                    () => this.AcquireLeaseAndExecuteInnerAsync(action, cancellationTokenSource, leaseProvider),
                    cancellationTokenSource.Token,
                    this.RetryStrategy,
                    this.RetryPolicy);

                return(new Tuple <bool, T>(true, result));
            }
            catch (LeaseAcquisitionUnsuccessfulException)
            {
                return(new Tuple <bool, T>(false, default(T)));
            }
        }
Beispiel #15
0
        private async Task AcquireLeaseAndStartRenewingAsync(CancellationToken cancellationToken, ILeaseProvider leaseProvider, Lease lease)
        {
            Trace.TraceInformation("[{0}] Attempting to acquire a Lease with a lease policy name : {1} - duration: {2}",
                                   this.LeasePolicy.ActorName, this.LeasePolicy.Name, this.LeasePolicy.Duration);

            await lease.AcquireAsync(this.LeasePolicy);

            Trace.TraceInformation(
                "[{0}] Lease was successfully acquired for lease policy name : {1} - duration: {2}",
                this.LeasePolicy.ActorName,
                this.LeasePolicy.Name,
                this.LeasePolicy.Duration);

            var leaseDuration = this.LeasePolicy.Duration.HasValue
                ? this.LeasePolicy.Duration.Value.Add(TimeSpan.FromSeconds(-5))
                : leaseProvider.DefaultLeaseDuration.Add(TimeSpan.FromSeconds(-1));

            var renewEvery = TimeSpan.FromSeconds(Math.Round(leaseDuration.TotalSeconds / 3));

            this.AcquireRenewingLease(cancellationToken, lease, renewEvery);
        }
Beispiel #16
0
        private async Task AcquireLeaseAndExecuteInnerAsync <T>(Func <CancellationToken, T, Task> action, CancellationTokenSource cancellationTokenSource, ILeaseProvider leaseProvider, T arg)
        {
            using (var lease = new Lease(leaseProvider, this.leasePolicyValidator))
            {
                try
                {
                    await this.AcquireLeaseAndStartRenewingAsync(cancellationTokenSource.Token, leaseProvider, lease);

                    await action(cancellationTokenSource.Token, arg);

                    Trace.TraceInformation("[{0}] Action completed using lease policy name : {1}", this.LeasePolicy.ActorName, this.LeasePolicy.Name);

                    cancellationTokenSource.Cancel();
                }
                catch (LeaseAcquisitionUnsuccessfulException)
                {
                    Trace.TraceInformation("[{0}] Lease could not be obtained with policy name : {1}.", this.LeasePolicy.ActorName, this.LeasePolicy.Name);
                    throw;
                }
            }
        }
Beispiel #17
0
 public Lease(ILeaseProvider leaseProvider, ILeasePolicyValidator leasePolicyValidator)
 {
     this.LeasePolicyValidator = leasePolicyValidator;
     this.leaseProvider = leaseProvider;
 }
Beispiel #18
0
 public InstanceDiscoveryActor(ILeaseProvider leaseProvider,
                               LeaseProviderConfiguration leaseProviderConfiguration)
 {
     this.leaseProvider = leaseProvider;
     clusterName        = leaseProviderConfiguration.ClusterName.GetBytes();
 }
Beispiel #19
0
 public Lease(ILeaseProvider leaseProvider, ILeasePolicyValidator leasePolicyValidator)
 {
     this.LeasePolicyValidator = leasePolicyValidator;
     this.leaseProvider        = leaseProvider;
 }