Orleans storage provider for Orleans

Hi,

Just published a storage provider for MS Orleans: https://github.com/jkonecki/Orleans.EventSourcing.

The implementation may be a bit naive but may be helpful if you want to quickly spike migration of your existing EventStore application to Orleans.

Feedback welcomed!

Jakub

Do you think a transaction is actually needed here? It is much more expensive to write that way that to use atomic writes.

Just out of curiousity: From what I understand a transaction in Orleans can span multiple actors/grains. Is this handled somehow in this implementation, or is it more a matter of crossing your fingers and hoping for the best? :wink:

/Peter

As of now transactions are limited to a single stream (as they should be) writing transactionally through multiple actors is considered an anti-pattern

“That said, support for cross-actor transactions is a topic under investigation.” from http://blogs.msdn.com/b/dotnet/archive/2014/04/02/available-now-preview-of-project-orleans-cloud-services-at-scale.aspx

Seems like they’re not quite clear on the behaviour:

“By default, all of the grains that process an external
request are included within a single transaction, so that the request
executes atomically and in isolation”

(http://research.microsoft.com/pubs/153347/socc125-print.pdf))

Doesn’t matter, I personally think it looks like a mess (code-gen etc), and stopped investigating further after the above whitepaper…

/Peter

There is a fix for this “mess” in a progress … :wink:

That should be a “no-go”. It just breaks the whole idea of
autonomous agents

That paper suggests (emphasis mine):

  1. Orleans transactions are atomic, consistent, isolated, and durable. During execution, a transaction sees only a single activation of each grain involved in the transaction, thus every transaction
    by itself sees a consistent application state. This state is isolated from changes made by concurrently executing transactions.
    A transaction’s
    updates to durable storage, even if they occur in multiple grains, become visible atomically to subsequent transactions when the transaction completes; so another transaction sees the
    entire, consistent set of changes from a completed transaction. **Updates across many grains are atomically committed to durable storage, providing a consistent mechanism for persisting the result of a computation. **

Seems to be some conflicting information around

yes.

There are however some libraries for instance in erlang to handle this (paxos)

yeah I would not make this a requirement.

When using a transaction now in event store btw it is scoped to a stream onbly!

We could make this more relaxed inside a single replica set.

Current Storage Provider API has no notion of the transaction.

As others stated before cross-actor transactions are not the best ideas, especially since the actors may be running in separate silos (physical nodes) and we’re back to DTC world of pain and misery.

Jakub

Greg,

So should i just get rid of the transaction and call AppendToStreamAsync passing all the events?

Jakub

Generally that would be prefered for up to a significantly large number of events (say a few hundred)

Maybe offer a way to say I need to stream them instead like what you do now.

Greg

I wouldn’t dismiss it that quickly.
I have a feeling after talking to some guys during London Azure User group that you may see Orleans tab in Azure portal one day…

Jakub

My guess is you will. Its a much better model for services in the cloud.

Current write page size is 500 so for smaller number of events there will be no transaction.

What do you mean by ‘stream them instead’?

Jakub

Yes, I’m fully aware of the target platform, and I’m very intrested in actor model. I just don’t like the approach they’ve taken, excplicit message passing usually turns out a lot cleaner than trying to mimic local method calls across the network, in my experience… But I guess you could program in that style yourself, on top of the framework.

/Peter

Yes, you can do it on top of it. But it’s quite involved :slight_smile:

In fact, nothing stopping you to have actor methods which simply

accept a single message parameter.
Even polymorphic dispatch works out of the box. So you can have a
higher-order function which accepts some base Message interface.
And then dispatch internally (inside actor) to a more specific
handler by using “dynamic”.

But you'll still need to obtain a reference to an actor by using

some obnoxious static factory, codegened by Orleans MSBuild target.
That’s really ugly and not unit-test friendly, at all.

To overcome this, framework need to do some form of DI.
I hope they fix this in the next release, given we have provided a

lot of feedback on this.

I did some work on message bus for Orleans, and it's started

breezing but still in flux.
I hope to combine Orleans.Bus with Orleans.EventSourcing to have
Orleans.CQRS soon :slight_smile:

Orleans.EventSourcing will be even more compelling with sharding.

I think there can be some specific stuff done with Orleans to make it better by getting close to orleans from a ges perspective similar to akka stuff in the jvm api