prosemeteor / prosemirror

Prosemirror integration for Meteor.js
MIT License
18 stars 2 forks source link

Remove Authority when no more users are editing #18

Closed ejfrancis closed 7 years ago

ejfrancis commented 8 years ago

When no more clients are editing a doc:

ejfrancis commented 8 years ago

Some notes on how to detect when a client has disconnected are below. I believe we'll want to know when the disconnect is done on the server side, but I'm including both server and client detection:

Detect the closed connection on the server

Meteor allows us to register a callback on the server that's given the Connection instance when a client connects. This object contains a onClose method that can be used like this

Meteor.onConnection(function onConnect(connection) {
   let connectionId = connection.id;
   connection.onClose(() => {
      // handle client disconnected
   });
})

We need to know which connection are editing which documents, so that when no more users are interacting with a doc we can remove its Authority instance from that app server's memory. Perhaps we can use the connection's unique id string and associate it with a docId in the Authority instance for that doc. So when a user calls the Meteor Method ProseMeteor.openDoc or ProseMeteor.stepsSince we can make sure that connection's id string is stored in that document's Authority in a property called something like connectionIds: [ ]. That way when a user disconnects, we can check which Authority has that connection id so we can know which document that user was viewing.

Detect the closed connection on the client

When a new connection is created via DDP.connect(url) a Connection instance is returned. There is no ddpConnection.onDisconnect() method, but it does have a status value that's reactive. So we can do something like this to make our code run via Tracker when a user disconnects

import { Tracker } from 'meteor/tracker';

const connection = DDP.connect(url, options);
Tracker.autorun(() => {
  if ( (['failed', 'offline'].indexOf(connection.status().status) !== -1) {
      // user is disconnected. handle it
  }
});

The possible values in the "status" field are described in the docs:

ejfrancis commented 7 years ago

Another option, given by MDG staff, is to implement a keepalive method that clients call on an interval. This introduces a small overhead by adding more requests but would be easy to do http://stackoverflow.com/a/10274212