@Jason, Thanks for jumping in :)
I am not using Udi's implementation of DomainEvents.Raise<TEvent>(..). I am
familiar with that approach, but am instead doing event sourcing. What this
means is during the course of an operation one or more events are applied to
the Aggregate Root. Upon the commit of a UnitOfWork those events are
serialized to an event store after which they are published on a bus. Not
all usages of Domain Events are synchronous operations on the query store.
They can be but I have pulled those out of process.
In a separate process lives a series of Denormalizers which subscribe to
these events. But the domain itself may also subscribe to these events for
purpose of communicating across Bounded Contexts or perhaps contributing to
a saga.
My posting didn't have to do with any of this, though :).

Instead, it was related to the faulty assumption that calling Publish on
more than one message should assume that every endpoint in that batch of
messages can be derived from the first message in the batch. That works for
Send, but not Publish. When I am calling Send, I am safely making
assumptions about the endpoint to which I am Sending those
messages...namely, that they will go to the same place. When I call Publish,
that assumption should not be made.


On Thu, Aug 5, 2010 at 7:31 AM, Jason Meckley <jasonmeck...@gmail.com>wrote:

> Mike, if I'm following the discussion correctly the problem has become
> confusion between messages on RSB and handlers for domain events.
>
> messaging (RSB) is an asynchronous action. you can batch messages
> together and all the messages in the batch are send to the endpoint
> defined by the 1st message in the batch. that is by design to keep
> transactional boundaries. if you need to send multiple messages to
> various endpoints you need to send them separately, each it's own
> transaction.
>
> domain events are synchronous operations that would occur within the
> same transaction as the message(s) being processed. for example here
> is a consumer to process an order
> void Consume(ProcessOrder message)
> {
>   session.Get<Order>(message.OrderNumber).Process();
> }
>
> the Process() method on order might look like this
> void Process()
> {
>   //validate order is ready for processing
>   //change the state of order and/or order lines
>
>   DomainEvents.Raise<OrderProcessed>(this);
> }
>
> where DomainEvents.Raise is a static facade to instantiate and execute
> the various OrderProcessed. for example you may have the following
> handlers for order processing
> SendInvoiceToCustomer : IHandler<OrderProcessed>
> ShipProductsToCustomer : IHandler<OrderProcessed>
> DecreaseInventoryOfItemsOnTheOrder : IHandler<OrderProcessed>
> UpdateATableUsedForReporting : IHandler<OrderProcessed>
>
> all of these handlers would execute immediately, within the same
> transaction, when the order is processed. and if any of these
> operations would fail the entire transaction would rollback as well.
> Some of these handlers may call the service bus to send another
> message but each of those messages is yet another transaction
> independent of actually processing the order.
>
> I hope this helps rather than adds confusion or another tangent. From
> what I have read, understanding this distinction may help explain why
> RSB works the way it does, where domain events fit into the
> architecture and how the 2 are used to solve different problems. And
> why atomic transactions to various endpoints doesn't work (or is a bad
> idea).
>
> On Aug 5, 9:03 am, Mike Nichols <nichols.mik...@gmail.com> wrote:
> > @Udi
> > I am not sure I understand. I am using event sourcing, so I persist
> events
> > on the domain side for rehydration of Aggregates, etc (domain-side). The
> bus
> > publishes these events, which are subscribed to by interested query-side
> > denormalizers.
> >
> > On Thu, Aug 5, 2010 at 12:40 AM, Udi Dahan <
> thesoftwaresimpl...@udidahan.com
> >
> > > wrote:
> > > I think that the reason you're running into difficulty is that your
> > > persisting data on the command side that should have only been
> persisted on
> > > the query side.
> >
> > > Cheers,
> >
> > > -- Udi Dahan
> >
> > > -----Original Message-----
> > > From: rhino-tools-dev@googlegroups.com
> > > [mailto:rhino-tools-...@googlegroups.com] On Behalf Of Mike Nichols
> > > Sent: Thursday, August 05, 2010 1:09 AM
> > > To: Rhino Tools Dev
> > > Subject: [rhino-tools-dev] Re: rhino rsb subscription harvesting
> >
> > > @Udi
> > > I am persisting the events. After the events have been persisted they
> > > are put on the bus for publication.
> > > My initial concern here though was about the assumption that the first
> > > message in a batch is the sole provider of subscription details for an
> > > entire batch of messages. It seems like a user should just Publish a
> > > batch of messages on a bus and not be concerned about who is
> > > subscribed to them.
> >
> > > To be clear this code from the PublishInternal method in the
> > > defaultservicebus is what I am discussing.What this code is saying is
> > > that if you have two messages in a batch being Published, and each one
> > > is subscribed to by different endpoints, then the second message in
> > > the batch will not get published. That seems unpredictable to me:
> > > private bool PublishInternal(object[] messages)
> > >        {
> > >            if (messages == null)
> > >                throw new ArgumentNullException("messages");
> >
> > >            bool sentMsg = false;
> > >            if (messages.Length == 0)
> > >                throw new MessagePublicationException("Cannot publish
> > > an empty message batch");
> > >            object msg = messages[0];
> > >            IEnumerable<Uri> subscriptions =
> > > subscriptionStorage.GetSubscriptionsFor(msg.GetType());
> > >            foreach (Uri subscription in subscriptions)
> > >            {
> >
> > > transport.Send(endpointRouter.GetRoutedEndpoint(subscription),
> > > messages);
> > >                sentMsg = true;
> > >            }
> > >            return sentMsg;
> > >        }
> >
> > > m
> >
> > > On Aug 4, 9:51 am, Udi Dahan <thesoftwaresimpl...@udidahan.com> wrote:
> > > > Mike,
> >
> > > > The case of CQRS usually has the service layer publishing the events
> in
> > > > response to commands, domain events has nothing to do with it. If
> you're
> > > > talking about event-based persistence on the command-side, again,
> domain
> > > > events have nothing to do with the bus.
> >
> > > > Cheers,
> >
> > > > -- Udi Dahan
> >
> > > > -----Original Message-----
> > > > From: rhino-tools-dev@googlegroups.com
> >
> > > > [mailto:rhino-tools-...@googlegroups.com] On Behalf Of Mike Nichols
> > > > Sent: Wednesday, August 04, 2010 4:46 PM
> > > > To: Rhino Tools Dev
> > > > Subject: [rhino-tools-dev] Re: rhino rsb subscription harvesting
> >
> > > > If I have 5 events that took place on my aggregate root during the
> > > > course of a unit of work. My understanding is that the root
> represents
> > > > a transactional boundary. So I publish the events on the bus as a
> > > > batch. The subscriber (in this case, denormalizers for events that
> > > > write to a database) will go through each event and update the
> > > > database, ideally in a single transaction so that if one of the
> > > > handlers fails, then they all fail.
> > > > As I think about it, I am not sure why that is so important other
> than
> > > > the convenience of having NHib in a single session and cut down on
> the
> > > > number of roundtrips. But I realize this is an impl detail that
> > > > shouldn't be the driver.
> >
> > > > @Udi - I actually went back and forth on whether to publish these
> > > > individually or not, so it is helpful to hear from you on this. Can
> > > > you see why I would consider the batch a single unit though? If you
> > > > are using a denormalizer you always only send one event at a time to
> > > > that endpoint?
> >
> > > > On Aug 4, 6:35 am, Udi Dahan <thesoftwaresimpl...@udidahan.com>
> wrote:
> > > > > Then I'm afraid it sounds like you're not using DomainEvents the
> right
> > > way
> > > > -
> > > > > each event from the domain should be a discrete domain occurrence.
> >
> > > > > -- Udi Dahan
> >
> > > > > -----Original Message-----
> > > > > From: rhino-tools-dev@googlegroups.com
> >
> > > > > [mailto:rhino-tools-...@googlegroups.com] On Behalf Of Mike
> Nichols
> > > > > Sent: Wednesday, August 04, 2010 3:45 PM
> > > > > To: Rhino Tools Dev
> > > > > Subject: [rhino-tools-dev] Re: rhino rsb subscription harvesting
> >
> > > > > I am publishing the DomainEvents from my domain. These events are
> > > > > subscribed to by 1 (or more report) services that update the db
> state
> > > > > from those events.
> > > > > @Udi - I could publish them one at a time, yes, but I'd rather the
> > > > > whole batch fail since they represent a unit of work from my
> > > > > domain...I don't want some messages to succeed and others to fail
> > > > > leaving the db in an odd state.
> >
> > > > > On Aug 4, 5:39 am, Ayende Rahien <aye...@ayende.com> wrote:
> > > > > > What is the scenario in which you would want to publish a message
> > > batch?
> > > > > > And publishing doesn't use the owners, it uses the subscriptions
> > > list.
> > > > > > I think that I had the wrong idea in mind about what we are
> talking
> > > > about,
> > > > > > yes, for publish, that would make sense, but I still want to know
> > > what
> > > > > your
> > > > > > scenario is.
> >
> > > > > > On Wed, Aug 4, 2010 at 3:33 PM, Mike Nichols
> > > > > <nichols.mik...@gmail.com>wrote:
> >
> > > > > > > Isn't that the difference between Publish and Send though?
> > > > > > > 'Publishing' an event in my mind doesn't carry any assumption
> about
> > > > > > > who is dealing with its payload. 'Sending' on the other hand
> does
> > > > > > > carry those transactional assumptions.
> >
> > > > > > > On Aug 4, 5:26 am, Ayende Rahien <aye...@ayende.com> wrote:
> > > > > > > > Mike,
> > > > > > > > The problem is that there is a difference between the
> > > expectations.
> > > > > > > > You should be aware which messages goes to which endpoints.
> > > > > > > > By splitting a batch you may be violating the assumption of
> the
> > > user
> > > > > that
> > > > > > > > they are sending one unit of work to the server.
> >
> > > > > > > > I don't have an issue with throwing if you are sending a
> batch to
> > > > > mixed
> > > > > > > > endpoints, though.
> >
> > > > > > > > On Wed, Aug 4, 2010 at 3:22 PM, Mike Nichols
> > > > <nichols.mik...@gmail.com
> > > > > > > >wrote:
> >
> > > > > > > > > Yes, but each endpoint _will_ treat the batch as a single
> unit
> > > for
> > > > > the
> > > > > > > > > batch though only in its own context. Otherwise the
> publisher
> > > is
> > > > > > > required to
> > > > > > > > > have some knowledge of its subscribers right? To be clear
> > > (sorry
> > > > if
> > > > > I
> > > > > > > am
> > > > > > > > > thick), how do you handle this scenario:
> > > > > > > > > 1. There are two messages in a batch
> > > > > > > > > 2. Message1 is subscribed to by Endpoint1
> > > > > > > > > 3. Message2 is subscribed to by Endpoint2
> > > > > > > > > 4. You Publish(new[]{ message1,message2});
> >
> > > > > > > > > With the current codebase, only Endpoint1 will receive the
> > > batch
> > > > of
> > > > > > > > > messages...(it looks at 'messages[0]' to GetSubscriptions).
> > > That
> > > > > > > doesn't
> > > > > > > > > seem predictable.
> >
> > > > > > > > > Another option is to have the publisher somehow split up
> the
> > > > > messages
> > > > > > > so
> > > > > > > > > that they will be published to the correct endpoint. That
> seems
> > > to
> > > > > > > turns
> > > > > > > > > things upside down though.
> >
> > > > > > > > > Other than feeding messages one by one is there some better
> > > > > > > alternative?
> >
> > > > > > > > > On Wed, Aug 4, 2010 at 12:45 AM, Ayende Rahien
> > > <aye...@ayende.com>
> > > > > > > wrote:
> >
> > > > > > > > >> Mike,
> > > > > > > > >> Perf isn't what worries me.
> > > > > > > > >> Message batches are treated as a single transactional
> unit.
> > > > > > > > >> If you send them to different endpoints, you break that
> > > > assumption.
> >
> > > > > > > > >> On Wed, Aug 4, 2010 at 6:29 AM, Mike Nichols <
> > > > > > > nichols.mik...@gmail.com>wrote:
> >
> > > > > > > > >>> I have (clumsily) fixing an issue in rsb where it
> currently
> > > > simply
> > > > > > > > >>> looks at the first message in batch being Published for
> its
> > > > > > > > >>> subscription info.
> > > > > > > > >>> I am publishing a number of messages that may or may not
> be
> > > > > > > subscribed
> > > > > > > > >>> to (these are events from a store) and which are
> subscribed
> > > to
> > > > at
> > > > > > > > >>> different endpoints. Under the current setup
> > > (PublishInternal),
> > > > if
> > > > > a
> > > > > > > > >>> message doesn't happen to be subscribed to in the same
> > > endpoint
> > > > > the
> > > > > > > > >>> first message in the batch it will not get sent to get
> > > handled.
> >
> > > > > > > > >>> The initial fix is to GetSubscriptions for each message
> in
> > > the
> > > > > batch
> > > > > > > > >>> to make sure all subscriptions have been harvested that
> are
> > > > > > > > >>> interested.
> >
> > > > > > > > >>> My question is about the performance of something like
> this
> > > on
> > > a
> > > > > > > > >>> massive batch of messages where I am iterating on the
> > > collection
> > > > > > > > >>> (please see my pull request).
> >
> > > > > > > > >>> This scenario doesn't seem far fetched to me, but if
> there is
> > > a
> > > > > > > better
> > > > > > > > >>> way of implementing it I'd like to hear it.
> >
> > > > > > > > >>> --
> > > > > > > > >>> You received this message because you are subscribed to
> the
> > > > Google
> > > > > > > Groups
> > > > > > > > >>> "Rhino Tools Dev" group.
> > > > > > > > >>> To post to this group, send email to
> > > > > > > rhino-tools-...@googlegroups.com.
> > > > > > > > >>> To unsubscribe from this group, send email to
> >
> > > rhino-tools-dev+unsubscr...@googlegroups.com<rhino-tools-dev%2bunsubscr...@googlegroups.com>
> <rhino-tools-dev%2bunsubscr...@googlegroups.com<rhino-tools-dev%252bunsubscr...@googlegroups.com>
> >
> > > <rhino-tools-dev%2bunsubscr...@g
> > > > > ooglegroups.com>
> >
> > > <rhino-tools-dev%2bunsubscr...@googlegroups.com<rhino-tools-dev%252bunsubscr...@googlegroups.com>
> <rhino-tools-dev%252bunsubscr...@googlegroups.com<rhino-tools-dev%25252bunsubscr...@googlegroups.com>
> >
> > > <rhino-tools-dev%252Bunsubscr
> > > > > i...@googlegroups.com>
> >
> > > > > > > > >>> .
> > > > > > > > >>> For more options,
> >
> > ...
> >
> > read more »
>
> --
> You received this message because you are subscribed to the Google Groups
> "Rhino Tools Dev" group.
> To post to this group, send email to rhino-tools-...@googlegroups.com.
> To unsubscribe from this group, send email to
> rhino-tools-dev+unsubscr...@googlegroups.com<rhino-tools-dev%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/rhino-tools-dev?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to rhino-tools-...@googlegroups.com.
To unsubscribe from this group, send email to 
rhino-tools-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en.

Reply via email to