Saga-like flows?

213 views
Skip to first unread message

Josef Bodnár

unread,
Nov 2, 2017, 7:21:25 AM11/2/17
to StrangeIoC
Hi,
in my regular boring corporate job I started with javascript + react-native + redux.
My bad feelings about javascript aside, I started using redux-saga (https://github.com/redux-saga/redux-saga) and I like the approach, so I wanted to ask how feasible / valuable addition to StrangeIoC would be to add some of the concepts used in there.

Let me explain the concept...
Note: I don't like the term "saga", so I will call it "flow".

The basic idea behind flow is to merge together synchronous and asynchronous calls into more comprehensible structure - flow. Example:

Game Flow:
1/ load game level
2/ wait on LEVEL_LOADED
3/ init game
4/ start game
5/ wait on one of (GAME_FINISHED, GAME_ABORTED)
6/ if game is finished, save score
7/ go back to menu

In redux-saga this would translate 1:1 to something like:

function* gameFlow(){
  yield call(loadGameLevelFlow); //calling subflow
  yield take(LEVEL_LOADED); //wait for an event
  yield call(initGame); //call subflow
  yield call(startGame); //call subflow
  let action = yield take([GAME_FINISHED, GAME_ABORTED]); //wait for one of the events
  if (action.type === 'GAME_FINISHED'){
    yield call(saveScore); //call some (synchronous?) service
  }
  yield put(SHOW_MENU); //dispatch an event
}

The beauty of this is, that you can express complex, asynchronous flows in a single function. You can nest these, wait for user input, etc.. and hide it behind a single line call.
Note that the flow can wait indefinetly for the events and the sub-flows might be also asynchronous and pause the wait.
There are more features than the mentioned call(), put(), take() (for example delay(), non-blocking calls, throttling (allowing subflow to be re-executed only after specific time)).

This is kinda like the Reactive approach, but in my opinion much more easier to understand.


As a side note, the flows in redux-saga do not actually execute anything by themselves, they just return a simple instruction object for each yield. The saga interpreter actually does the waiting, delays, etc.
This has a huge benefit you can unit-test the flows without any mocking neccessary. You just call .next() on the returned iterator and compare the instruction (e.g. test that now we should be waiting for the GAME_FINISHED event).
Also note that in redux you do not directly write into Model for some javascript concurrency reasons, so any modification of a model is also an instruction object.


Now the interesting part - introducing this to StrangeIoC ...
- The direct benefit would be to write "higher" level logic into single method and thus avoid the extra signal - command bindings overhead.
- You can replace the mentioned events with Signals 1:1 (at least with singletons, AFAIK)
- Flows would probably be the new thing since Commands are a different concept. Flows are not bound / executed by a signal as a rule, they are always called from another flow. In Redux-saga they allow this binding via a watcher flows like this:

function* gameFlowWatcher(){
   yield takeEvery(START_GAME, gameFlow); //every time this event is dispatched, start game flow
}

function* gameFlow(){ ...}

But you can always replace direct sub-flow call via this indirection and vice versa - depending on which style you prefer.

What do you think? Is it worth considering?
I might try to implement it once I get some free time ...

Josef

Josef Bodnár

unread,
Nov 2, 2017, 10:41:17 AM11/2/17
to StrangeIoC
The more I think about this, the more it seems to me that the Flows would be a higher level alternative to Commands. This could reduce the complexity of bindings a lot.

BTW in redux-saga I seriously lack the binding support of StrangeIoC - all the bindings are decentralized and hidden in the watcher flows, etc... not to mention these is nothing like Contexts ... just kudos! :-)

Josef


Dne čtvrtek 2. listopadu 2017 12:21:25 UTC+1 Josef Bodnár napsal(a):

wco...@gmail.com

unread,
Nov 2, 2017, 10:58:59 AM11/2/17
to Josef Bodnár, StrangeIoC
Let's set up a skype call sometime this weekend to chat about this. Sounds interesting but early morning brain is stopping me from grokking it just now :)

Sent from my iPhone
--
You received this message because you are subscribed to the Google Groups "StrangeIoC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strangeioc+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Josef Bodnár

unread,
Nov 3, 2017, 9:20:45 AM11/3/17
to StrangeIoC
I will be available only the next weekend. I am in GMT+1 time zone...
I will try to contact you next week so we can get in touch...
Thanks!
Josef

Dne čtvrtek 2. listopadu 2017 15:58:59 UTC+1 wcorwin napsal(a):
Reply all
Reply to author
Forward
0 new messages