zeromq.js icon indicating copy to clipboard operation
zeromq.js copied to clipboard

[beta.6] zeromq prevents Electron window from refreshing, blocks indefinitely

Open trusktr opened this issue 5 years ago • 4 comments

Describe the bug

Hello!

I was using zeromq 5, and I upgraded to 6-beta.6 yesterday. Now when I hit ctrl-r to refresh my electron application, it hangs indefinitely (have to exit with ctrl-c or close the window).

There is no output in devtools. But eventually I found that running electron with ELECTRON_ENABLE_LOGGING=true does show one last message in the terminal before the freeze:

(node:73342) WARNING: Waiting for queued ZeroMQ messages to be delivered. Set 'context.blocky = false' to change this behaviour.

I'm using v5-compat, so I think it should behave the same. I believe refreshing an electron app should not be indefinitely blocked by zeromq. Not sure what's happening exactly though.

It didn't happen while on v5, only while on v5-compat.

Reproducing

I'm not able to make a small reproduction with Electron Fiddle. I am able to make a socket in Electron Fiddle, and refreshing works.

Expected behavior

When I exit the node process (f.e. refresh the Electron window) it should not block.

The code I have is almost the same as with v5 (but using v5-compat). The only slight difference is I needed to change one socket.send('string') call to socket.send(['string']) due to the new TypeScript type signature expecting only arrays (v5 can accept a direct string value).

Tested on

  • OS: Manjaro Linux
  • ZeroMQ.js version: 6.0.0-beta.6

Any idea what a workaround is?

Ideally this problem can be solved so that Electron users aren't blocked out of the box.

trusktr avatar Sep 15 '20 20:09 trusktr

I tried a workaround with no luck. I tried placing

window.unloadTasks = []

window.addEventListener('beforeunload', () => {
  for (const task of window.unloadTasks) task()
})

at the top of my index module. Then anywhere in other code (classes, which always run later than the top level of the index module), I am trying things like

    socket.connect(path)

    const close = () => {
      socket.disconnect(path)
      socket.close()
    }

    window.unloadTasks.push(close)

but no luck. I was hoping maybe I could catch the unload event (on refresh of the Electron web app) and close sockets so that they won't be blocked (for whatever reason).

trusktr avatar Sep 15 '20 20:09 trusktr

@rolftimmermans This prevents our Electron apps from being refreshable out of the box.

trusktr avatar Sep 22 '20 17:09 trusktr

I tried

import * as zmq from 'zeromq/v5-compat'

zmq.context.blocky = false

// use `zqm` compat layer...

as I'm using the compatibility layer, which didn't work (Cannot set property 'blocky' of undefined).

The following worked:

import * as _zmq from 'zeromq/'
import * as zmq from 'zeromq/v5-compat'

_zmq.context.blocky = false

// use `zqm` compat layer...

trusktr avatar Sep 22 '20 18:09 trusktr

I'm not sure that blocky=true should be the default. I've never experienced a dependency that blocked process exit.

Here's a question: this didn't happen in v5, so maybe importing zmq/v5-compat should at least set it to false by default?

trusktr avatar Sep 22 '20 18:09 trusktr