Esempio n. 1
0
        private void StopProjection(IEventStoreProjection projection)
        {
            if (!_projectionSubscriptions.ContainsKey(projection.ProjectionName))
            {
                return;
            }

            _projectionSubscriptions[projection.ProjectionName].Close();
            _projectionSubscriptions.Remove(projection.ProjectionName);
        }
Esempio n. 2
0
        private async Task SubscribeProjection(IEventStoreProjection currentEventStoreProjection, AppFunc chain, IDictionary <string, object> environment)
        {
            environment.Log("Subscribing projection: {0}", LogLevel.Debug, currentEventStoreProjection.ProjectionName);

            var bufferSettings = environment.GetSettings <ProjectionSettings>().GetBufferSettings();

            while (true)
            {
                if (!running)
                {
                    return;
                }

                if (_projectionSubscriptions.ContainsKey(currentEventStoreProjection.ProjectionName))
                {
                    _projectionSubscriptions[currentEventStoreProjection.ProjectionName].Close();
                    _projectionSubscriptions.Remove(currentEventStoreProjection.ProjectionName);
                }

                try
                {
                    var eventNumberManager = environment.Resolve <IManageEventNumbersForProjections>();

                    var messageProcessor    = new MessageProcessor();
                    var messageSubscription = Observable
                                              .FromEvent <DeSerializationResult>(x => messageProcessor.MessageArrived += x, x => messageProcessor.MessageArrived -= x)
                                              .Buffer(TimeSpan.FromSeconds(bufferSettings.Seconds), bufferSettings.NumberOfEvents)
                                              .Subscribe(async x => await PushEventsToProjections(chain, currentEventStoreProjection, x, environment).ConfigureAwait(false));

                    var eventStoreSubscription = _eventStoreConnection.SubscribeToStreamFrom(currentEventStoreProjection.ProjectionName,
                                                                                             await eventNumberManager.GetLastEvent(currentEventStoreProjection.ProjectionName, environment).ConfigureAwait(false), CatchUpSubscriptionSettings.Default,
                                                                                             (subscription, evnt) => messageProcessor.OnMessageArrived(_eventSerialization.DeSerialize(evnt)),
                                                                                             subscriptionDropped: async(subscription, reason, exception) => await SubscriptionDropped(chain, currentEventStoreProjection, reason, exception, environment).ConfigureAwait(false));

                    _projectionSubscriptions[currentEventStoreProjection.ProjectionName] = new ProjectionSubscription(messageSubscription, eventStoreSubscription);

                    return;
                }
                catch (Exception ex)
                {
                    if (!running)
                    {
                        return;
                    }

                    environment.Log(ex, "Couldn't subscribe projection: {0}. Retrying in 5 seconds.", LogLevel.Warn, currentEventStoreProjection.ProjectionName);

                    await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false);
                }
            }
        }
Esempio n. 3
0
        private async Task SubscriptionDropped(AppFunc chain, IEventStoreProjection projection, SubscriptionDropReason reason, Exception exception, IDictionary <string, object> environment)
        {
            if (!running)
            {
                return;
            }

            environment.Log(exception, "Subscription dropped for projection: {0}. Reason: {1}. Retrying...", LogLevel.Warn, projection.ProjectionName, reason);

            if (reason != SubscriptionDropReason.UserInitiated)
            {
                await SubscribeProjection(projection, chain, environment).ConfigureAwait(false);
            }
        }
Esempio n. 4
0
        private async Task PushEventsToProjections(AppFunc chain, IEventStoreProjection projection, IEnumerable <DeSerializationResult> events, IDictionary <string, object> environment)
        {
            if (!running)
            {
                return;
            }

            var eventsList = events.ToList();

            var successfullEvents = eventsList
                                    .Where(x => x.Successful)
                                    .ToList();

            if (!successfullEvents.Any())
            {
                return;
            }

            try
            {
                var requestEnvironment = new Dictionary <string, object>();
                foreach (var item in environment)
                {
                    requestEnvironment[item.Key] = item.Value;
                }

                var request = requestEnvironment.GetEventStoreRequest();

                request.Projection = projection;
                request.Events     = eventsList;

                using (requestEnvironment.OpenCorrelationContext(Guid.NewGuid().ToString()))
                {
                    await chain(requestEnvironment).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                //TODO:Mark service as failing to we can report that via consul
                environment.Log(ex, "Couldn't push events to projection: {0}", LogLevel.Error, projection.ProjectionName);

                StopProjection(projection);

                await environment.Notifications().Error("projections", $"Projection: {projection.ProjectionName} failed!", ex).ConfigureAwait(false);
            }
        }