by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 01 21:14

    yevhen on gh-pages

    Update generated documentation (compare)

  • Jan 01 21:07

    yevhen on gh-pages

    Update generated documentation (compare)

  • Jan 01 21:00

    yevhen on master

    Make stream subscription serial… (compare)

  • Jan 01 20:59

    yevhen on master

    Make stream subscription serial… (compare)

  • Dec 30 2019 13:20

    yevhen on gh-pages

    Update generated documentation (compare)

  • Dec 30 2019 13:12

    yevhen on gh-pages

    Update generated documentation (compare)

  • Dec 30 2019 13:10

    yevhen on master

    Update README.md (compare)

  • Dec 30 2019 13:08

    yevhen on master

    Update README.md (compare)

  • Dec 30 2019 13:05

    yevhen on master

    Update readme (compare)

  • Dec 30 2019 13:03

    yevhen on master

    Get rid of incomplete F# api -… (compare)

  • Dec 27 2019 20:51

    yevhen on master

    Rename to better match pub-sub … Support passing stream sequence… Complete streaming api and test… (compare)

  • Dec 21 2019 21:17

    yevhen on gh-pages

    Update generated documentation (compare)

  • Dec 21 2019 21:08

    yevhen on master

    Fix test (compare)

  • Dec 21 2019 19:18

    yevhen on master

    More robust timing-related tests Revert "Fix R# settings" This … Revert "Reset R# settings" Thi… (compare)

  • Dec 21 2019 16:05

    yevhen on master

    Upgrade to Orleans 3.0.2 (compare)

  • Dec 21 2019 12:53

    yevhen on 3.0.0

    Upgrade to Orleans 3.0.2 (compare)

  • Dec 21 2019 12:53

    yevhen on 3.0.2

    (compare)

  • Dec 21 2019 12:52

    yevhen on 3.0.2

    Upgrade to Orleans 3.0.2 (compare)

  • Dec 19 2019 09:15

    yevhen on gh-pages

    Update generated documentation (compare)

  • Dec 19 2019 09:07

    yevhen on 2.7.0

    (compare)

Yevhen Bobrov
@yevhen
2.4.4 of Orleans should be released this week, Orleankka will follow
for those who will be migrating from 1.x to 2.x: if you find any omissions or inconsistencies in migration guide - please let me know (or just fix :)
Yevhen Bobrov
@yevhen
Orleans 2.4.4 is out. Now it's safe to continue migration using transitional releases starting from 010. Updated migration guide
Yevhen Bobrov
@yevhen
Published Orleankka 2.4.4. Details here
Matej Hertis
@mhertis
superb, can't wait to continue migration, will report here :)
Mario Adam
@i-dentify

Hey there... currently doing some research (reading only, not coding) on Orleans and found Orleankka on that way... Got some questions now, as I was previously (and currently) using EventFlow (CQRS/ES library) and being used to separate between a "Write-Side" (aka events applied to an aggregate) and a "Read-Side" (aka Read Models). Creating a read model is merely a subscription on a processed event applying the event payload to a read-optimized data structure.

Am I right that what I am used to call an aggregate with applied events are grains in Orleans? What is the read side then there. And how could it be used with Orleankka, since "Ask" seems to use the grains?

Yevhen Bobrov
@yevhen

Hi @i-dentify . Sorry for the late reply.

Yes, aggregates are usually what is hosted by grains. Grains (or actors) hold aggregate state in memory, readily available to process commands (and produce events). You save the trip to db for reading an aggregate on every command, which is crucial in high-performance scenarios.

Wrt projections: 1-to-1 projection (basically a snapshot of aggregate's state) could be hosted and queried directly in/from the source actor, like InventoryItem actor holding its in-stock count in memory (which it also uses for processing business commands) or in a different one. For the former, for the query messages, you may utilize tricks like message interleaving since queries are pure and should not create problems. For the latter, you just create an additional (replica) actor which processes steam of aggregate events and holds an aggregates's snapshot in memory, once again saving you a trip to db on every aplpication of the event. In both cases, actors serve as a cache for the aggregate state, more like a K-V store

for 1-to-many projections - you will need some sort of the global stream support from your event store. Then, whether you hold the state of projection in memory or not, depends much on a kind of projection, size of the data and data access patterns. For example, holding a list of all inventory items in memory might be feasible if it's short, otherwise projecting it to a db table you can later query on might be more feasible for your use-case. Majority of business apps which use event-sourcing project into some kind of db
Yevhen Bobrov
@yevhen
for those migrating from transitional to 2.x: I've found non-critical but annoying bug in the legacy support package. Addressed with release 2.4.6
Mario Adam
@i-dentify

Hi @yevhen - thanks for the response.So does this mean:

a) the grain is (given a persistent storage) persisted in a serialized form - means: it gets overridden when the state changes?
b) to store events in an event sourcing manner I have to provide an additional actor which stores the events as-is?
c) to store my grains in a read-optimized (mainly 1-to-many) projection, I have to provide an additional actor which saves the data to my (e.g. relational) database with its custom entities?
d) an api or whatsoever which would consume my read-optimized projections wouldn't use the actor system at all but instead directly perform its queries (e.g. using a custom Entity Framework implementation)
c) the "Ask"-method at orleankka to "read" on grains would be optimal for e.g. reading a complete grain (e.g. by its unique identifier) or some sort of validation before applying events to the grain?

Yevhen Bobrov
@yevhen
Are you familiar with InventoryItem CQRS example from Greg Young?
Do you have working experience with production system that uses event-sourcing?
Mario Adam
@i-dentify
I'd basically say: yes... yet so far I used the EventFlow-library which is inspired by Eric Evans DDD-book
In my understanding the current state of an aggregate is basically the sum of all its events sequentially applied... so there is basically no need to store the aggregate itself but instead its events... thatswhy my questions (a) and (b)
Yevhen Bobrov
@yevhen
Regarding your questions:
A) the grain is the aggregate. The snapshot of it’s state which it needs to make business decisions against incoming commands (business logic, validation, etc) could be stored in db for faster access or it may rebuild it from past events upon activation
B) nope. The event-sourced grain stores produced events itself. Check example with Event Store here
C) yes/no. The projection itself may simply be wired with event store global stream listener, like the one in Event Store and just produce db change commands (sql crud) in response. Whether you want it to be an actor or not depends solely on past state it need to have in order to project an event.
D) yes, it’s basically by the book implementation of CQRS. You don’t need to proxy via actors just to do a simple sql query. Use storage provided capabilities
E) the Ask method it’s just a way to query actor in-memory state, could be a snapshot (like inventory item counter). What to return is completely up to you. You may use it to return event produced by the command to the caller or use for additional queries (see GetIncentoryItemDetails in sample I mentioned above)
Mario Adam
@i-dentify

OK - thanks... concerning your answer:

a) I hoped so... I've just been a bit confused by your initial answer which sounded as if the grain is stored as-is
b) will check that
c) oh - I really have to take a deeper look at EventStore than... did not know about its technical implementation so far
d) fine - I hoped so as well, as this means, I don't have to carry additional overload for a completely read-based api than
e) understood

Yevhen Bobrov
@yevhen
Let me know after you check the example whether it answered your questions about possible design of cqrs-style event-sourcef actors
Yevhen Bobrov
@yevhen
1) I've published few more releases since 2.4.x (2.5.0, 2.6.0, 2.7.0)
2) And updated Orleankka to run on Orleans 3.x (3.0.0)
Piotr Stępniewski
@k3nsei
Hi is there any guide how to create solution with Orleankka. And how to do CQRS with ES?
Yevhen Bobrov
@yevhen
Hi @k3nsei There is no guide per-se, but you can find 2 examples of possible CQRS/ES implementation using Orleankka in accompanied Samples (https://github.com/OrleansContrib/Orleankka/tree/master/Samples/CSharp/EventSourcing/Persistence). Just clone the repo and open the Orleankka solution locally, then you can play with examples. One is built using Streamstone and will require local storage emulator and the second one is built with GetEventStore and you will need an instance of GES running locally. If you're on Windows you can execute from cli Nake.bat located in the root folder, it will auto-download GES locally, and then execute Nake.bat run to spin-up an instance of GES on the loclahost so you can run the sample.
Yevhen Bobrov
@yevhen
Few more notes: the examples do illustrate how messages (commands/queries) could be defined and handled by corresponding actors which represent Aggregates, and how the persistence and state replay is handled. The implementation of global projection is highly specific to a particular event store and storage backing the read model, and of course, your data access requirements, so it's out of scope. You may check samples/docs on GetEventStore site for an example on how to build global projection using a catch-up subscription
You may substitute GES/Streamstone with any other event store implementation, the basic canvas will be the same.
Piotr Stępniewski
@k3nsei
What about project structure?
Is there any plans for forcus on documentation?
Yevhen Bobrov
@yevhen
yep, working on this. Next release will bring streaming api completeness and hope to push docs soon
Piotr Stępniewski
@k3nsei
Because as new to C# and Orleans. There is not many sources that I can learn.
So for example right now the biggest problem for me is how to structure my project. So this is example of good documentation on that topic https://angular.io/guide/file-structure
Yevhen Bobrov
@yevhen
@k3nsei well, Orleankka is just a tiny extension to Orleans. You can get all of the information regarding the structure of the project by reading Orleans docs http://dotnet.github.io/orleans/Documentation/tutorials_and_samples/tutorial_1.html#project-setup
Gustavo Sainz
@sainzg
@yevhen is it possible in the Orleanskka - fsm to make it reconfigurable dynamically so when adding new state/transitions the previously ones can be undone, and the restart from where the new one is inserted (if not inserted at the end)?
Yevhen Bobrov
@yevhen
@sainzg Hi! First of all, welcome to our chat! ))
I'm not sure I understand the use-case, can you give a more concrete example?
the states in FSM are usually static. But transitions are dynamic. In case of durable FSM, you save the last state (name) and then set it as initial during actor activation. The state will receive Activate message so it can restart the work (continue).
Yevhen Bobrov
@yevhen
you can, of course, assemble FSM dynamically (using the API) before activating the initial state. It's not a problem to re-configure it afterwards (for example on handling of some message) dynamically as well. But you will need to reassemble the whole FSM, since it's immutable after you built it.
so instead of adding states dynamically, you may rebuild FSM and then replace the existing one
why you want to add states dynamically? What are you trying to achieve?
Gustavo Sainz
@sainzg
That a given process in time might change some state/transitions by adding or removing them and whatever was done before the new state is added can be undone, if it already happened.
So the current FSM implementation you've done is very useful and it needs a way to become intelligent/flexible enough to rework itself at runtime based on some injected new state/transition/behavior and also undo any of the previously done behaviors
FSM are confined to model a specific context and instead a DFSM (dynamic FSM) can accomodate multiple configurable contexts and redo/undo themselves
Yevhen Bobrov
@yevhen
What you’re describing sounds more like a Saga or the Workflow, where states/transitions form a DAG which can be
Yevhen Bobrov
@yevhen
rolled back
Yevhen Bobrov
@yevhen
FSM in Orleankka is just a way to compose behaviors that could be switched at runtime (by means of transitions). It allows fluent composition of state's receive function with higher-order functions to implement cross-cutting concerns and to mix other receive functions (be means of traits) for message handler reuse. Plus, it allows composing state in hierarchies, once again for reuse (code compression). It's more like Erlang's way of switching actor behavior dynamically then kind of a workflow solution you're describing
Yevhen Bobrov
@yevhen
giving it some thought, it should be easy to record all state transitions (S1->S2->S3) into some kind of log. Then you can use that log to undo all transitions in reverse order by mapping state names to state receive functions and invoking each with some special message (say Undo) to execute the rollback behavior. You can plug that "recorder" function via extend parameter when building a state, since it's a cross-cutting concern, similar to how Durable higher-order function is plugged in this example https://github.com/OrleansContrib/Orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/Copier.cs#L96
and it will look pretty much similar to this https://github.com/OrleansContrib/Orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/Copier.cs#L207 but will just store the history of all state transitions
Yevhen Bobrov
@yevhen
by the way, behaviors in Orleankka support such a rollback of the states but history of transitions is tracked only in-memory. Use BecomeStacked instead of calling Become for transitioning to the next state. Then you can simply call behavior.Unbecome() and FSM will move to the previous state (sending Unbecome message to current state and Become to the previous state). Internally, it uses a Stack to push/pop states. Is that what you're looking for?
Gustavo Sainz
@sainzg
Looks like your description of the process will work for us, so by using the state pattern through behaviors seems to be a better approach than using a FSM?
Andy Hoyle
@andyhoyle
Hi all!
Crazy times. Hope you're all well.
Getting a weird error when testing, and it may be something I'm doing: System.ArgumentException: 'An item with the same key has already been added. Key: NUnitTestProject1.Domain.WidgetActor'
> Orleankka.Runtime.dll!Orleankka.DispatcherRegistry.Register(System.Type type, Orleankka.Dispatcher dispatcher) Line 26
Andy Hoyle
@andyhoyle
Oops turns out should have been using [OneTimeSetup] instead of [Setup] when using NUnit