Skip to content

treat filter subscription as a subscription to every store matching the filter #110

Open

Description

@ngalaiko

setup:

assume a client-server architecture where on SyncMap is used with createFIlter on the offline/remote client and addSyncMap +addSyncMapFilter on the backend

problem:

when creating a filter, client and server exchange a lot of messages to:

  1. subscribe to a list. that's two messages
  2. subscribe to every item of the list. that's one or two messages depending on if server subscribes a client, or client subscribes by iteself

that's a lot of pressure on the network and synchronisation for really no reason.

solution:

filter subscription is enough for the server to send actions related to every matching item of the channel

there seems no need to explicitly subscribe client to every matching store separately, or maybe I am missing something?

Activity

  1. transferred this issue fromlogux/serveron Sep 9, 2022
  2. ai commented on Sep 9, 2022

    @ai
    Member

    Both client and server need IDs of each subscribed element.

    If we can find a way to get find them without an action, it always will be a good idea.

    Do you have an idea how to make PR?

  3. ngalaiko commented on Sep 10, 2022

    @ngalaiko
    Author

    I haven't looked into it too much, but it seems possible.

    on the client side:

    1. createFilter should be synchronously populated with initial data from the client's state
    2. for every new action, it it matches any existing filter, filter's value should be updated with an action

    on the server side:

    1. for every new action, for every known filter, if an action matches the filter, it should be sent to the client
  4. ai commented on Sep 10, 2022

    @ai
    Member

    createFilter should be synchronously populated with initial data from the client's state

    It is impossible because log is an async store (for instance, IndexedDB has only async API).

    for every new action, it it matches any existing filter, filter's value should be updated with an action

    change action will not have all model’s fields. As the result it will be impossible to tell is it part of filter or not.

    Imagine you have name: 'a' filter and see { type: 'users/changed', id: 'X', fields: { age: 50 } }. How you will tell that it is your or not item without a list of subscribed IDs?

    for every new action, for every known filter, if an action matches the filter, it should be sent to the client

    1. Client A created filter { age: 50, name: 'a' }
    2. Client B changed user with ID X age to 50. You do not have information of the name to find did it matched the selection.
    3. Client C changed another user with ID Y to role: 'admin'. How do you know age and name of Y user?
  5. ngalaiko commented on Sep 10, 2022

    @ngalaiko
    Author

    Imagine you have name: 'a' filter and see { type: 'users/changed', id: 'X', fields: { age: 50 } }. How you will tell that it is your or not item without a list of subscribed IDs?

    given that I already have a full item in the scope (from the init step), I could simply merge it with it

    same applies for the server side.

    Client B changed user with ID X age to 50. You do not have information of the name to find did it matched the selection.

    server does have the info. it keeps an index of elements matching the filter in memory for every connected client. when client B changes user with ID X age to 50, it sends an action to the server. server resends it to client A

    Client C changed another user with ID Y to role: 'admin'. How do you know age and name of Y user?

    when filter is created, all of the matching elements (from the initial function in the addSyncMapFilter) are used to create in-memory index.

    It is impossible because log is an async store (for instance, IndexedDB has only async API).

    either way it would be very fast, since it happens without communicating with other clients or servers on the client

  6. ai commented on Sep 11, 2022

    @ai
    Member

    given that I already have a full item in the scope (from the init step)

    Only if server already send the initial data.

    same applies for the server side.
    all of the matching elements (from the initial function in the addSyncMapFilter) are used to create in-memory index.

    Dangerous (server could have 1000 of client with 10 subscriptions with 1000 elements each). But we can try.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions