You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a work in progress. Posting here as a PR so we can discuss. Particularly interested in what @dcolthorp has to say. Regarding #47 (comment), this PR provides a way of registering sagas using an action observable AND awaiting the completion of all actions in the store. See unit tests for details.
Due to necessity I branched this off of my previous branch (PR #60), hence why the commit from that PR also shows up in this PR.
I've just lumped all code together in one file for now.
The distinct features in this PR are:
The following two delegates denoting async/blocking sagas:
void Saga(action, store)
Task AsyncSaga(action, store)
I'm considering changing this a bit so that they only accept an action parameter, and then have the sagas be returned from a function that accepts the store. Kind of like middleware, where the middleware has access to the store through the function that creates the middleware. Removing the store parameter would make the saga register syntax look cleaner, and also removes the store parameter from sagas that don't need it. Input welcome.
Two extension methods on IObservable<T> for registering async and non-async sagas.
AwaitableStore which exposes DispatchAsync and also has internally accessible member(s) for keeping track of async operations that DispatchAsync should await (currently this is simply a method IDisposable AsyncOperation() to be used in using statements, as seen in the extension method.)
The IObservable<T> extension methods RunsSaga and RunsAsyncSaga
Things to do before this can be merged:
Structure: Where to put the classes and interfaces
Determine if/how various features should be integrated with existing Redux.NET classes.
@dcolthorp It should be exception safe now. Calling Dispatch (on any store) or await DispatchAsync() (on AwaitableStore) will 1) bubble up the exception, and 2) make sure that the async task count is decremented.
I've added a ton of tests, check them out to see how it's used. Some tests might be unnecessary due to being pretty much being guaranteed by .NET, but much of it was copy-paste and I didn't stop to think too hard on whether all the tests were strictly needed.
I've updated the initial comment with more information.
@dcolthorp Regarding #47 (comment) and your mention of TakeLatest: I tried experimenting, but couldn't find a solution that was simpler than simply letting the sagas themselves handle this. I do that already in a few of my listeners.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a work in progress. Posting here as a PR so we can discuss. Particularly interested in what @dcolthorp has to say. Regarding #47 (comment), this PR provides a way of registering sagas using an action observable AND awaiting the completion of all actions in the store. See unit tests for details.
Due to necessity I branched this off of my previous branch (PR #60), hence why the commit from that PR also shows up in this PR.
I've just lumped all code together in one file for now.
The distinct features in this PR are:
The following two delegates denoting async/blocking sagas:
void Saga(action, store)Task AsyncSaga(action, store)I'm considering changing this a bit so that they only accept an
actionparameter, and then have the sagas be returned from a function that accepts the store. Kind of like middleware, where the middleware has access to the store through the function that creates the middleware. Removing the store parameter would make the saga register syntax look cleaner, and also removes the store parameter from sagas that don't need it. Input welcome.Two extension methods on
IObservable<T>for registering async and non-async sagas.ObservableActionStorewhich exposes an IObservable of actions. Can be dropped in favor of a simple extension toStoreif we figure out New ActionDispatched event would duplicate StateChanged #63.AwaitableStorewhich exposesDispatchAsyncand also has internally accessible member(s) for keeping track of async operations thatDispatchAsyncshould await (currently this is simply a methodIDisposable AsyncOperation()to be used inusingstatements, as seen in the extension method.)The
IObservable<T>extension methodsRunsSagaandRunsAsyncSagaThings to do before this can be merged: