On Thursday, March 2, 2017 at 11:04:58 PM UTC-6, Jeremy Evans wrote:
>
> On Thursday, March 2, 2017 at 2:26:20 PM UTC-8, Mike Pastore wrote:
>>
>>
>> Can you elaborate at all? Is there a way to capture the state in most 
>> cases and ship it to another Ruby process with its own Sequel connection?
>>
>
> Sequel makes heavy use of extended modules/singleton classes in datasets, 
> and some of those effect the results, even with the same SQL used.  For 
> example, see the graph_each extension.  It's not possible to serialize all 
> datasets as they can contain unmarshallable state.
>
> I think capturing the SQL and using it will probably work for "most 
> cases".  However, I don't think it will work for all cases.
>

Okay, thank you for the explanation.
 

> I will admit that I do not fully understand how event-sourcing implies the 
> use of a queuing library like 0MQ
>

Consider an application distributed over multiple data centers. Ideally 
you'd have some way to reliably deliver events to and coalesce them on the 
write-master, regardless of node outages, network delays, failovers, etc. 
It makes sense to me to use some kind of message queue here, but I'm still 
exploring this.

or why you wouldn't want to do:
>
> user1, user2 = User.first(2) # uses DB (sync)
> user1.update(:foo=>'bar') # uses DB (sync)
> CqrsAsyncFactoryFactory.new.new.new(:model=>:User, :id=>user2.id, 
> :action=>:update, :atttributes=>{:foo=>'qux'}).call # uses MQ (async), 
> just kidding about FactoryFactory.new.new
>

That gave me a chuckle. :-) Wouldn't we also need an 
AbstractCqrsAsyncFactoryFactory?

And then have Sequel (or a library written in another language) handle the 
> event after getting the data from 0MQ.  I guess in other words, what's the 
> benefit of queuing just the SQL, as opposed to queuing the abstract change 
> you want to make?
>

That was my first approach, actually, and I still may end up pursuing this. 
The thought that occurs to me though is that it would be beneficial over 
the long term to keep all the "business logic" for a topic contained in a 
single module. Having your read-only queries in a module in one application 
and your read-write queries in a different module in a second application 
could become a maintenance nightmare. 

I see that you've represented the update query in an abstract way to keep 
the logic on the sending side, so that helps. But you know better than 
almost anyone how many different ways there are to write insert, update, 
and delete queries, and trying to come up with a grammar to handle all 
those cases could be quite an exercise. Especially considering we already 
have a perfectly fine grammar for exactly that purpose: SQL. So that's kind 
of where I'm coming from, if that makes sense. 

You also may want the ability to have a synchronous query become 
asynchronous and vice-versa. Having to transcribe grammars each time would 
get tedious. Being able to use the same (or same-ish) syntax for both types 
of queries would be a huge win.
 

> If you really did want to just want to ship the SQL for a query, maybe 
> overriding the Dataset#execute* methods to do something like:
>
> def execute(sql, opts={})
>   if @opts[:server] == :cqrs
>     CqrsAyncSql.new(sql).call
>     nil
>   else
>     super
>   end
> end
>
> That may work as long as you don't care about the results of the method. 
>  Something like that would work with the API you proposed.
>

Ah, I see how that could work. Thank you for the example. I'll explore this 
along with the other ideas you've given me.

Thank you again!

Mike

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to