Ejemplo n.º 1
0
        public async Task PublishAsync(EventPublishData data, PublishPreferences preferences)
        {
            var eventDesc = new EventDescriptor {
                Service = data.Service, Event = data.Event
            };
            var subscribers = _eventSubscriber.GetSubscribers(eventDesc).ToList();

            if (subscribers.Count == 0)
            {
                return;
            }

            foreach (var subscriber in subscribers)
            {
                var invokeData = new MethodInvocationData
                {
                    IntentId    = _idGenerator.NewId(),
                    Service     = subscriber.Service,
                    Method      = subscriber.Method,
                    Parameters  = data.Parameters,
                    FlowContext = data.FlowContext,
                    Caller      = new CallerDescriptor(data.Service, data.Event, data.IntentId)
                };

                InvokeInBackground(invokeData, preferences);
            }
        }
 public static void Write(Message message, EventPublishData data, PublishPreferences preferences, ISerializer serializer)
 {
     message.Data["IntentId"]   = data.IntentId;
     message.Data["Service"]    = data.Service.Clone();
     message.Data["Event"]      = data.Event.Clone();
     message.Data["Format"]     = serializer.Format;
     message.Data["Parameters"] = serializer.SerializeToString(data.Parameters);
     message.Data["Caller"]     = data.Caller?.Clone();
     message.Data["SkipLocal"]  = preferences.SkipLocalSubscribers;
 }
Ejemplo n.º 3
0
        public Task PublishAsync(EventPublishData data, PublishPreferences preferences)
        {
            var message = new Message
            {
                Type = MessageType.Event,
            };

            EventPublishDataTransformer.Write(message, data, preferences, _serializer);

            _messageHub.Schedule(message);

            return(Task.CompletedTask);
        }
Ejemplo n.º 4
0
        public async Task PublishAsync(RaiseEventIntent intent)
        {
            var eventData = new EventPublishData
            {
                IntentId   = intent.Id,
                Service    = intent.Service,
                Event      = intent.Event,
                Parameters = intent.Parameters
            };

            if (_transitionScope.IsActive)
            {
                var context = (ITransitionContext)_transitionScope.CurrentMonitor.Context;
                eventData.FlowContext = context.FlowContext;
                eventData.Caller      = context.CurrentAsCaller();
            }

            var publisher = _eventPublisherProvider.GetPublisher(intent.Service, intent.Event);
            await publisher.PublishAsync(eventData, default);
        }
Ejemplo n.º 5
0
        public async Task PublishAsync(EventPublishData data, PublishPreferences preferences)
        {
            var exchangeName = _settings.ExchangeName
                               .Replace("{serviceName}", data.Service.Name)
                               .Replace("{eventName}", data.Event.Name);

            // TODO: declare once? what's the penalty?
            _channel.ExchangeDeclare(
                exchangeName,
                type: "fanout",
                durable: true,
                autoDelete: false,
                arguments: null);

            var properties = CreateMessageProperties(_channel);

            properties.Type = MessageTypes.Event;
            SetIntentId(properties, data.IntentId);
            SetFormat(properties, _serializer);
            properties.Headers.Add("X-Service-Name", data.Service.Name);
            properties.Headers.Add("X-Event-Name", data.Event.Name);
            if (preferences.SkipLocalSubscribers)
            {
                properties.Headers.Add("X-Skip-Local", true);
            }

            var payload = SerializePayload(data);

            _channel.BasicPublish(
                exchange: exchangeName,
                routingKey: "",
                basicProperties: properties,
                body: payload);

            _channel.WaitForConfirms(); // no async version :(
        }
Ejemplo n.º 6
0
        public async Task ReactAsync(EventPublishData data, ICommunicatorMessage message)
        {
            var eventDesc = new EventDescriptor {
                Service = data.Service, Event = data.Event
            };
            var subscribers = _eventSubscriber.GetSubscribers(eventDesc).ToList();

            if (subscribers.Count == 0)
            {
                return;
            }

            var publisherServiceReference = _serviceResolver.Resolve(data.Service);
            var publisherEventReference   = _eventResolver.Resolve(publisherServiceReference.Definition, data.Event);

            var behaviorSettings = _communicationSettingsProvider.GetEventSettings(publisherEventReference.Definition, external: false);

            //-------------------------------------------------------------------------------
            // MESSGE DE-DUPLICATION
            //-------------------------------------------------------------------------------

            if (behaviorSettings.Deduplicate &&
                !message.CommunicatorTraits.HasFlag(CommunicationTraits.MessageDeduplication) &&
                (message.IsRetry != false || string.IsNullOrEmpty(message.RequestId)))
            {
                // TODO: if has message de-dup'er, check if a dedup
                // return new InvokeRoutineResult { Outcome = InvocationOutcome.Deduplicated };
            }

            //-------------------------------------------------------------------------------
            // UNIT OF WORK
            //-------------------------------------------------------------------------------

            // TODO: Unit of Work - check if there is cached/stored data
            if (message.IsRetry != false)
            {
                // TODO: If has entities in transitions and they have been already committed,
                // skip method transition and re-try sending commands and events.
            }

            foreach (var subscriber in subscribers)
            {
                // Skip external services
                if (!_serviceResolver.TryResolve(subscriber.Service, out var subscriberServiceReference) ||
                    subscriberServiceReference.Definition.Type == ServiceType.External)
                {
                    continue;
                }

                var invokeData = new MethodInvocationData
                {
                    IntentId    = _idGenerator.NewId(),
                    Service     = subscriber.Service,
                    Method      = subscriber.Method,
                    Parameters  = data.Parameters,
                    FlowContext = data.FlowContext,
                    Caller      = new CallerDescriptor(data.Service, data.Event, data.IntentId)
                };

                // TODO: think about fanning out depending on the communication mechanism, number of subscribers per event, and settings.
                await RunAsync(invokeData, message);
            }
        }
Ejemplo n.º 7
0
        public async Task PublishAsync(EventPublishData data, PublishPreferences preferences)
        {
            await LocalPublisher.PublishAsync(data, default);

            await ExternalPublisher.PublishAsync(data, new PublishPreferences { SkipLocalSubscribers = true });
        }