Cannot update a WSSWSSharedDoc when no browser client is connected

I have successfully created a node server that uses the WSSharedDoc class from utils.js from y-websocket-server. I am running a spawned process that writes its stdout to a document that then syncs up (beautifully) with a client browser. This is the node side updater:

//get the right document
  output = utils.docs.get(data['code']).getText('output')

//clear the document before starting spawn
  output.delete(0,output.length);

//spawn process
  ps[data['code']] = spawn("python3",[`-u`,`code/${data['code']}.py`])

//stream spawned process into ytext
  ps[data['code']].stdout.on('data',(data) => {output.insert(output.length,`${data}`)
  })

And this is the client listener

const yO = ydoc.getText('output')
yO.observe(event => { $("#output").html(yO.toString());})

So long as a client is open, this works beautifully and the spawned stream updates in the browser in real time. But if I close all clients, the spawned process continues, but the ytext in the WSSharedDoc no longer receives the updates. If I restart the process with the client attached it works fine. To be clear, if I have multiple browser windows open the spawn stream updates continute, but if I close all browsers and then reopen I only see the ytext as recent as the last browser tab was closed.

I am guessing there is some flag that prevents the ytext from receiving updates if there is no client attached to the websocketserver, if so how can I override

Thanks for taking the time to help me.

Sometimes typing out the problem and then eating a bag of potato chips brings clarity. Upon inspection of utils.js I found

    if (doc.conns.size === 0 && persistence !== null) {
      // if persisted, we store state and destroy ydocument
      persistence.writeState(doc.name, doc).then(() => {
        doc.destroy()
      })

I changed the 0 to -1 and voila, hacky hacky worky worky. But I’m guessing this is going to bite me later. Curious how. Any advice would be most appreciated.

For this type of application you probably want to create a client that connects to a server. The client can be a nodejs process (see https://github.com/yjs/y-websocket#client-code-in-nodejs). The node application that uses input from python connects to the default y-websocket server.

If you never want to close rooms, you can also just disable the if-condition, like you are already doing. In that case, just remove the if-condition including its content.

Thanks @dmonad: my challenge is that I want to serve websocket-server from the same express instance and I don’t know now how to connect to myself in that context. I suppose my hack is the functional equivalent.

Anyway appreciate your time, and the more I use Y.js the better it gets. Really appreciate your effort and talent here.

1 Like