Lexical + Yjs on multiple containers

I am using Lexical editor based on this documentation: React | Lexical

In my custom y-websocket server I store updated in db using y-mongodb.

export default function setupWSConnection(conn: WebSocket, req: http.IncomingMessage) {
  ...
  const [doc, isNew] = getYDoc(docName);
  doc.conns.set(conn, new Set());
  // listen and reply to events
  conn.on('message', (message: ArrayBuffer) => messageListener(conn, doc, new Uint8Array(message)));

  if (isNew) {
    doc.on('update', async (update: Uint8Array) => {
      await mongoDbPersistence.storeUpdate(docName, update);
    });
  }

Meanwhile, on the client side, I store the editor state from Lexical in another collection.

On last disconnect I remove everything from DB

export const closeConn = (doc: WSSharedDoc, conn: WebSocket): void => {
  const controlledIds = doc.conns.get(conn);
  if (controlledIds) {
    doc.conns.delete(conn);
    awarenessProtocol.removeAwarenessStates(doc.awareness, Array.from(controlledIds), null);

    if (doc.conns.size === 0) {
      doc.destroy();
      docs.delete(doc.name);

      // remove from db, if the init from client works we will remove mongodb persistence
      mongoDbPersistence.clearDocument(doc.name).catch(e => {
        logger.error(e, `Cannot remove doc: ${doc.name} from db %e`, e);
      });
    }
  }

  conn.close();
};

I do this to know if I should bootstrap the Lexical editor with the initial editor state which comes from another collection and is the source of truth. If there are no yjs transactions in DB then the editor should bootstrap, else just initialize and get the state from YDoc.

This approach works ok on one container.

But when users connect from different containers, there are 2 instances of YDoc.
When one user from Container A refreshed the page on one instance of WebSocket server the doc.conns.size === 0 and it removes the yjs-transactions from DB. After page loads the DB is empty and the editor bootstraps the YDoc with it’s state from another collection.

How do I make sure that connections are shared across several instances of YDoc on separate WebSocket containers?

I haven’t found an off-the-shelf solution for this. Some proxies claim to support this (HAProxy with sticky sessions). However, I don’t believe that such a solution can be very robust. HAProxy (or alternatives) give no guarantee that clients will always target the same server. Either you implement this manually (e.g. via consistent hashing or by using a database to handle which server is currently responsible for which servers) or you allow multiple servers to host the same document. The latter is definitely preferable.