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

Subscription support (through pusher.com) #65

Open
chillu opened this issue Jan 20, 2017 · 0 comments
Open

Subscription support (through pusher.com) #65

chillu opened this issue Jan 20, 2017 · 0 comments

Comments

@chillu
Copy link
Member

chillu commented Jan 20, 2017

Setup

  • Server defines a new subscription, with a method receiving a DataObject and optionally filter arguments, determining if the subscription applies
  • Client defines a GraphQL subscription query through the ApolloClient.subscribe() method

Subscribing to Changes

  • Client sends GraphQL subscription query when viewing a UI depending on these updates
  • Server checks local store for matching queries
  • If no query is matched, server creates a new channel identifier for the query and stores it
  • Server sends back channel identifier to the client
  • Client creates subscription to channel by using the pusher.com JS API

Sending Updates

  • Client sends GraphQL mutation
  • Server writes one or more DataObjects
  • onAfterWrite() hook fires
  • TODO map DataObject to subscriptions
  • Client ingests the update (e.g. adding a page into the correct leaf node in the page tree, based on the ParentID in the payload)

Unsubscribing

  • Client moves to another view, which no longer requires subscription
  • Client sends an unsubscribe to pusher.com
  • Clients calls ApolloClient.unsubscribe()
  • Server keeps query in local store

Authentication

TODO

Use Cases

  • Notify authors when another author views a particular record (page, file)
  • Notification of new workflow requests
  • Comment streams on pages (workflow)
  • Optimistic locking ("somebody else has started editing the page")
  • Items added to currently viewed campaign by another author
  • Update page tree (rename, create, delete, move of nodes)
  • Update list of files in AssetAdmin
  • Update folder name in breadcrumbs

Example Subscriptions

subscription onPageModified($id: ID!){
   pageModified(id: $id){
     title,
     urlSegment,
     parentId
   }
}

Notes

  • Hooking in on DataObject->write() rather than mutations in order to capture database modifications which aren't triggered by GraphQL. This also includes form submissions, so pretty much every CMS-facing modification
  • I think the "local store" for subscription queries should be in the SilverStripe database. The server can't predict which subscription queries it will receive, but in practice there'll be a pretty limited set (predetermined in the JS build files). So there's no point expiring/clearing these queries
  • For implementations other than pusher.com (e.g. a Ratchet web server hosted in parallel with a SilverStripe Apache), the
  • Channels don't need to be registered explicitly in pusher.com, clients can subscribe to arbitrary names
  • Long polling in Apollo would be a lot simpler to implement, but doesn't scale well: Every client will be interested in handful of GraphQL queries in the current view, and cause additional load on the server for every logged-in author. On the positive note, polling can be more granular in the data it needs to query since it knows e.g. the exact pagination state - while subscriptions will need to send every change of a certain type down to every subscriber.
  • Subscription updates of the local Apollo/GraphQL store have the same issues as described in Update GraphQL models after form submission: Individual views need to be in charge or inspecting a payload, and determining how it influences the GraphQL state they maintain through their own gql queries (e.g. adding a record to a filtered list)

References

unclecheese pushed a commit to open-sausages/silverstripe-graphql that referenced this issue Jan 9, 2018
…remove-unneeded-memberextension

API Remove MemberExtension, functionality is replaced by framework update
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

2 participants