Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting Provider for calls from feathers sync #104

Open
RickEyre opened this issue Jan 17, 2019 · 10 comments
Open

Setting Provider for calls from feathers sync #104

RickEyre opened this issue Jan 17, 2019 · 10 comments

Comments

@RickEyre
Copy link

I was curious if it's possible / a good idea / already being done, to set the provider value to 'sync' or something when the service call is triggered by feathers sync.

I've read in the docs that it's not advised to use event listeners to modify global state when using feathers-sync, however, if the provider was set this would allow a check to run on the listener before executing.

I'd like to have my listeners modify global state and would also like to use feathers-sync so if this is possible that would be great.

@RickEyre
Copy link
Author

I think we would just have to set it here correct?

If this seems like a good idea, I'm happy to make a pull request.

@daffl
Copy link
Member

daffl commented Jan 17, 2019

feathers-sync publishes the service events to all servers. It doesn't really trigger the service call itself. Publishing the events is done by hooking into the service event emitter and replacing it with the synchronization mechanism. So internally all service events are actually handled by feathers-sync and treated the same and there currently isn't an easy way to know where it came from.

This is why it is recommended to do anything that should only happen once in an after hook.

@RickEyre
Copy link
Author

Okay I see. This makes it hard to use a reactive model when using Feathers events; which is what I was hoping to adopt.

The utility of feathers events really goes down if I can only use them to update local cache and hook into real-time like the docs suggest.

Is adding this feature something that you're at all interested in? I'm happy to do the work if you are interested and can give some pointers.

If not, I will have to think of how to restructure my application.

Thanks.

@daffl
Copy link
Member

daffl commented Jan 17, 2019

How does the reactive model look like?

Definitely not opposed to adding this as a feature but I currently can't think of a good way to make that possible. Basically you'd have to be able to determine what server the event came from and then have that server ignore the corresponding incoming synchronization message. Maybe giving each instance a unique id and passing that along might help.

@RickEyre
Copy link
Author

It's nothing too complicated.

I have a lot of side effects in my application and I like to have those side effects to be owned by the service of the resource that is being mutated by the side effect.

For example, when a person registers with my application I need to subscribe them to notifications. What I would like is for the notification service to handle this through listening for events from the people service, rather than the people service being in charge of subscribing people for notifications.

It just makes the system easier to reason about. The knowledge about how a service works in the system is encapsulated into that service itself and we accomplish this by having the services be in charge of handling their own side effects through listening to events.

Each side effect could potentially cause others which results in the Feather's service events being (kind of) a data stream that is operated on asynchronously.

It works really well and I need to start scaling my application at some point which is where I've run into this issue now.

@RickEyre
Copy link
Author

@daffl thoughts? Anything I can help with here?

@daffl
Copy link
Member

daffl commented Jan 25, 2019

So what I think would need to happen is add unique server name to the sync-out event (in https://github.com/feathersjs-ecosystem/feathers-sync/blob/master/lib/core.js#L47):

        return app.emit('sync-out', {
          event, path, data, context, name: someServerName
        });

And then still emit the event (always call https://github.com/feathersjs-ecosystem/feathers-sync/blob/master/lib/core.js#L38). On sync-in it would then check if it came from the same server

  app.on('sync-in', ({ event, path, data, context, name }) => {
    if (name === someServerName) {
      return;
    }

someServerName would be set in the configuration. That way it can be backwards compatible, too (it just will use the old behaviour if the name isn't set). Then it is possible to add a flag to the context that differentiates between synchronized and internal calls.

@RickEyre
Copy link
Author

@daffl okay awesome. I can work on a pull request for that then.

@daffl
Copy link
Member

daffl commented Jan 25, 2019

Sounds great, let me know if you need anything!

@deskoh
Copy link
Contributor

deskoh commented Nov 15, 2019

With custom serializer and deserializer support PR #130, can this be achieved by allowing deserialized value to be null?

https://github.com/deskoh/feathers-sync/blob/3efa4c9e493ae3e8a3e9081edb0deb1930a14bc4/lib/core.js#L16-L29

  app.on('sync-in', (rawData) => {
    if (rawData === null) return;
    // ...
  })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants