Platform: Web Worker Effects

Created on 19 Jul 2017  路  9Comments  路  Source: ngrx/platform

Migrating from effects#95 (cc @CoderCat84)

Just wanted to throw a thought out there, has it ever been considered to run ngrx/effects on a web worker? It seems like pretty prime case for it given that it subscribes to messages and responds with a message and doesn't access the DOM. There would obviously be some challenges like getting the latest state from the store but I feel like; at least in the way that I use ngrx this might work well, my reducers are pure and simple my views only subscribe to observable from the store and my effects do all of the heavy lifting.

I like this idea, a lot, and we should make this A Thing. cc @jeffbcross @alxhub

Would be reasonably straightforward to use angular/core (for DI) run effects in the background, and implement a simple bridge API that handles piping actions to the appropriate remote thread.

cc @surma cuz this would probably be pretty neato with some of your API sketches...

Effects enhancement

Most helpful comment

With Web Worker support landing in CLI, we should revisit this.

All 9 comments

Oh this is interesting! For context:

I have been working on an API proposal to make off-thread work much much easier/convenient. Please see the Explainer in the repository.

@bfgeek and I have been working on a polyfill the last couple of days (still on a branch), but it鈥檚 close to being done so I鈥檇 love for y鈥檃ll to test it out.

wouldn't the Angular worker, solve this?
as I understand it, all app logic (should include ngrx?) on a worker (which is on a 2nd thread), with angular rendering on the main thread.
the issue is not proposing having the state also on the worker (it cant b/c state service), or is it?
what comes to my mind is what I once read on the NativeScript blog or their GH repo; that serializing/ +marshaling can result in worst performance. IIRC, isn't that why react team chose not to do vdom diffing on a worker? obviously NG is different+better with CD with zones.. I hope results are too.
on the other hand

iOS and Android native platforms, for example, restrict (by default) the usage of any APIs not critical to UI manipulation on the main thread.

you are the experts here anyways.

Bump. Is there any official solution to use effects inside web workers? Or general integration with ngrx?

With Web Worker support landing in CLI, we should revisit this.

Now that the web workers have landed, should this be revisited?

I've been giving this idea a try, i'd like to share my approach:

  1. create a web worker
    Basically, this: https://angular.io/guide/web-worker

  2. emit actions to the worker
    I put this in my app.component:

import {Actions} from '@ngrx/effects';
import {Store} from '@ngrx/store';
...

  constructor(
    private actions$: Actions,
    private store: Store<State>,
  ) {
      const worker = ... // see 1. above
      this.actions$.subscribe(action => worker.postMessage(action));
      worker.onmessage = (({data}) => store.dispatch(data));
  }
  1. re-create an actions stream inside the web worker
import {ActionsSubject} from '@ngrx/store';

const actions$ = new ActionsSubject();
addEventListener('message', ({data}) => {
  actions$.next(data);
});
  1. create an effect in the web worker
function createWorkerEffect(stream): Observable<Action> {
    stream.subscribe(action => postMessage(action);
}
createWorkerEffect(actions$.pipe(
    ofType(fetchAllMyData),
    mergeMap(() => fetch("alldata.json")),
    map(alldata => fetchAllDataSuccess({alldata})),
));

  1. and 4. are pseudo-code, they won't work. As soon as I import anything - even just the Action interface, the app will no longer build:
    image

By making my worker code a whole lot more ugly and bypassing any references to @ngrx, I managed to make this work.

What needs to be done:

  1. Trace and hopefully resolve build errors when referencing interfaces and actions of @ngrx/store and @ngrx/effects. We will probably need at least ActionsSubject, Action, ofType inside the web worker to make the code much cleaner.
  1. Introduce a module that sets up the bridge between the Angular app and the worker (basically step 2.)

  2. Introduce utilities that make coding the worker easier, as described in steps 3 and 4

This seems like an interesting project to pursue.
So I'd like to know what the typical path for larger NgRx features like this take. Something like

  • define the need
  • validate the use case
  • define the goals
  • define the API
  • build

I'd be interested in working on this but would look to the maintainers for guidance on starting.

I just commented something about this issue in the other issue, i hope it helps
https://github.com/ngrx/platform/issues/195#issuecomment-807780203
Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandonroberts picture brandonroberts  路  3Comments

brandonroberts picture brandonroberts  路  3Comments

ghost picture ghost  路  3Comments

dollyshah-02-zz picture dollyshah-02-zz  路  3Comments

mappedinn picture mappedinn  路  3Comments