Exemplo n.º 1
0
        private async Task HandleMessageAsync(IAsyncBusEntity bus, VersionMoveAndConfirmNotification notification)
        {
            _log.LogInformation($"received 'VersionMoveAndConfirm(new=#{notification.VersionNumber}, old=#{notification.OldVersion}, b=#{notification.BaseVersionNumber})' notification from Vendor #{notification.FactoryInstanceId}");
            if (notification.FactoryInstanceId == FactoryInstanceId)
            {
                _log.LogInformation($"skip processing of self generated notification");
                return;
            }

            UpdateGlobalLatestVersionNumber(notification.VersionNumber);

            var rejectedVersionAccumulator = _versions.AddOrUpdate(notification.OldVersion,
                                                                   v => new MovedVersionAccumulator(v, notification.BaseVersionNumber, notification.VersionNumber),
                                                                   a => a.MoveVersion(notification.BaseVersionNumber, notification.VersionNumber));

            _log.LogVerbose($"rejected version #{rejectedVersionAccumulator.VersionNumber} for base #{notification.BaseVersionNumber}");

            var versionAccumulator = _versions.AddOrUpdate(notification.VersionNumber,
                                                           v => new SingleVersionAccumulator(v, notification.BaseVersionNumber),
                                                           a => a.ConfirmVersion(notification.BaseVersionNumber));

            _log.LogVerbose($"accumulated version #{versionAccumulator.VersionNumber} for base #{notification.BaseVersionNumber}");

            await ProcessConfirmedVersions(bus);

            _log.LogInformation($"finished processing 'VersionMoveAndConfirm(new=#{notification.VersionNumber}, old=#{notification.OldVersion}, b=#{notification.BaseVersionNumber})' notification from Vendor #{notification.FactoryInstanceId}");
        }
Exemplo n.º 2
0
        public Task StartAsync(IAsyncBusBroker busBroker)
        {
            _log.LogInformation($"Start Troll actor '{FactoryInstanceId}' of factory '{FactoryId}'");

            _bus = _busConfigFunc(busBroker);
            return(Task.FromResult(0));
        }
Exemplo n.º 3
0
        protected Task OnMessage(IAsyncBusEntity entity, string messageId, IDictionary <string, string> headers, object data)
        {
            _log.LogTrace($"Fabric Async Bus Listener received message '{messageId}' from '{entity.EntityId}': {data}");

            // TBD

            return(Task.FromResult(0));
        }
Exemplo n.º 4
0
        public async Task <Tuple <long, Task <long> > > PromoteNewVersion(IAsyncBusEntity bus, long baseVersionNumber)
        {
            var versionAccumulator = _versions.AddOrUpdate(Interlocked.Increment(ref _versionNumber), v => new SingleVersionAccumulator(v, baseVersionNumber), a => a.ConfirmVersion(baseVersionNumber));

            _log.LogVerbose($"Vendor actor instance #{FactoryInstanceId} of factory '{FactoryId}' promote new version #{versionAccumulator.VersionNumber} for base #{baseVersionNumber}");

            await bus.PublishMessageAsync(new VersionConfirmNotification(FactoryId, FactoryInstanceId, versionAccumulator.VersionNumber, baseVersionNumber));

            return(new Tuple <long, Task <long> >(versionAccumulator.VersionNumber, versionAccumulator.ConfirmTask));
        }
Exemplo n.º 5
0
        public Task HandleMessageAsync(IAsyncBusEntity sender, VersionCumulativeUpdateNotification <T> notification)
        {
            _log.LogInformation($"Librarian actor #{FactoryInstanceId} of factory '{FactoryId}' received notification of type '{notification.GetType()}' from async bus entity '{sender.EntityId}'");
            _log.LogVerbose($"VersionCumulativeUpdate: base=#{notification.CumulativeUpdate.BaseVersionNumber}, version=#{notification.VersionNumber}, cumulativeUpdate='{notification.CumulativeUpdate.GetType()}'");

            _updates.AddOrUpdate(notification.CumulativeUpdate.BaseVersionNumber,
                                 v => new Dictionary <long, ICumulativeUpdate <T> > {
                { notification.FactoryInstanceId, notification.CumulativeUpdate }
            },
                                 d => { d.Add(notification.FactoryInstanceId, notification.CumulativeUpdate); return(d); });

            return(Task.FromResult(0));
        }
        protected override IEnumerable <ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            _log.LogInformation("Create Service Listeners");

            var asyncBusConfig = _config.Sections["AsyncBus"];

            if (asyncBusConfig == null)
            {
                throw new ArgumentException("Configuration section 'AsyncBus' not found");
            }

            _actionsEntity = _asyncBusBroker.GetEntity(asyncBusConfig.Parameters["ActionsEntity"].Value);
            return(new[]
            {
                new ServiceInstanceListener(ctx => new AsyncBusListener(_actionsEntity, ctx, _loggerFactory.CreateLogger("ActionsEntityListener")), _actionsEntity.EntityId)
            });
        }
Exemplo n.º 7
0
        public async Task StartAsync(IAsyncBusBroker busBroker)
        {
            _log.LogInformation((int)Events.Start, $"Start Vendor actor instance #{FactoryInstanceId} of factory '{FactoryId}'");
            if (Interlocked.CompareExchange(ref _isInitialized, 1, 0) != 0)
            {
                _log.LogWarning($"Vendor actor #{FactoryInstanceId} of factory '{FactoryId}' already started");
                return;
            }

            _log.LogVerbose($"Start internal Vendor actor instance #{_librarian.FactoryInstanceId} of factory '{FactoryId}'");
            await _librarian.StartAsync(busBroker);

            _log.LogVerbose($"Get async bus entity for Vendor actor #{FactoryInstanceId} of factory '{FactoryId}'");
            _busEntity = _busEntityFunc(busBroker);

            _log.LogVerbose($"Subscribe for notifications from async bus entity '{_busEntity.EntityId}', Vendor actor #{FactoryInstanceId} of factory '{FactoryId}'");
            await Task.WhenAll(
                _busEntity.SubscribeAsync <VersionConfirmNotification>(HandleMessageAsync),
                _busEntity.SubscribeAsync <VersionMoveAndConfirmNotification>(HandleMessageAsync));

            _log.LogInformation($"Vendor actor instance #{FactoryInstanceId} of factory '{FactoryId}' has been successfully started");
        }
Exemplo n.º 8
0
 public AsyncBusListener(IAsyncBusEntity asyncBusEntity, StatelessServiceContext serviceContext, ILogger log)
 {
     _asyncBusEntity = asyncBusEntity;
     _serviceContext = serviceContext;
     _log            = log;
 }
Exemplo n.º 9
0
 protected abstract Task ExecuteHandler(IAsyncBusEntity entity, string messageId, IDictionary <string, string> headers, object message);
Exemplo n.º 10
0
 public static Task <IAsyncBusEntitySubscription> SubscribeAsync <T>(this IAsyncBusEntity entity, Func <T, Task> messageHandler) where T : class
 {
     return(entity.SubscribeAsync((s, i, h, d) => d is T ? messageHandler((T)d) : DefaultResultTask));
 }
Exemplo n.º 11
0
 public static Task PublishMessageAsync <T>(this IAsyncBusEntity entity, T message) where T : class
 {
     return(entity.PublishMessageAsync(new Dictionary <string, string>(), message));
 }
Exemplo n.º 12
0
 private Task OnActionReceived(IAsyncBusEntity entity, string messageId, IDictionary <string, string> headers, object data)
 {
     _log.LogInformation($"Received message '{messageId}' from '{entity.EntityId}' with Action");
     return(Task.FromResult(0));
 }
Exemplo n.º 13
0
 public CitizensController(IAsyncBusEntity asyncBusEntity)
 {
     _asyncBusEntity = asyncBusEntity;
 }
Exemplo n.º 14
0
 protected override Task ExecuteHandler(IAsyncBusEntity entity, string messageId, IDictionary <string, string> headers, object message)
 {
     return(_asyncHandler(entity, messageId, headers, message));
 }
Exemplo n.º 15
0
        private async Task ProcessConfirmedVersions(IAsyncBusEntity bus)
        {
            Func <long, VersionAccumulator> moveVersionFunc = null;
            var confirmedVersionNumber = Volatile.Read(ref _confirmedVersionNumber);
            var versionNumber          = Volatile.Read(ref _versionNumber);

            _log.LogVerbose($"Start process confirmed versions from #{confirmedVersionNumber} to #{versionNumber}");

            while (confirmedVersionNumber <= versionNumber)
            {
                _log.LogInformation($"Processing version #{confirmedVersionNumber}");

                VersionAccumulator originalAccumulator;
                var versionAccumulator = _versions.AddOrUpdate(confirmedVersionNumber, v => null, a => a.ApproveOrMoveVersion(out moveVersionFunc), out originalAccumulator);
                if (versionAccumulator == null)
                {
                    _log.LogInformation($"Version #{confirmedVersionNumber} doesn't exist");
                    return;
                }

                if (versionAccumulator.IsCompleted && originalAccumulator?.IsCompleted == true)
                {
                    _log.LogVerbose($"Version #{confirmedVersionNumber} has been already approved or moved");
                    confirmedVersionNumber = Interlocked.Increment(ref _confirmedVersionNumber);

                    continue;
                }

                if (versionAccumulator.IsCompleted || (!versionAccumulator.IsCompleted && confirmedVersionNumber == versionNumber))
                {
                    var baseVersion = (versionAccumulator as BaseVersionAccumulator)?.BaseVersionNumber;
                    if (baseVersion == null)
                    {
                        throw new InvalidOperationException($"Version accumulator #{versionAccumulator.VersionNumber} cannot be completed with multiple base versions");
                    }

                    if (moveVersionFunc != null)
                    {
                        _log.LogInformation((int)Events.Moving, $"Moving version #{versionAccumulator.VersionNumber} for base #{baseVersion}");
                        VersionAccumulator currentAccumulator;
                        do
                        {
                            versionNumber = Interlocked.Increment(ref _versionNumber);
                            _versions.AddOrUpdate(versionNumber, moveVersionFunc, a => a, out currentAccumulator);
                        } while (currentAccumulator != null);

                        _log.LogInformation((int)Events.Moved, $"Moved version #{versionAccumulator.VersionNumber} for base #{baseVersion} to version #{versionNumber}");
                        await bus.PublishMessageAsync(new VersionMoveAndConfirmNotification(FactoryId, FactoryInstanceId, versionNumber, baseVersion.Value, versionAccumulator.VersionNumber));
                    }
                    else
                    {
                        _log.LogInformation((int)Events.Approved, $"Approved version #{versionAccumulator.VersionNumber} for base #{baseVersion}");
                        await bus.PublishMessageAsync(new VersionConfirmNotification(FactoryId, FactoryInstanceId, versionAccumulator.VersionNumber, baseVersion.Value));
                    }

                    confirmedVersionNumber = Interlocked.Increment(ref _confirmedVersionNumber);
                    if (confirmedVersionNumber > versionNumber)
                    {
                        if (Interlocked.CompareExchange(ref _versionNumber, confirmedVersionNumber, versionNumber) == versionNumber)
                        {
                            _log.LogInformation((int)Events.SetVersion, $"Set last version number #{confirmedVersionNumber}");
                        }

                        return;
                    }
                }
            }
        }