添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams
  • single main process sitting in the memory and working like a web server;
  • system user's commands that can be run through CLI and exit when they are done.
  • I want to implement something like IPC between main and CLI processes, and it seems that ZeroMQ bindings for Node.js is a quite good candidate for doing that. I've chosen 6.0.0-beta.4 version:

    Version 6.0.0 (in beta) features a brand new API that solves many fundamental issues and is recommended for new projects.

    Using Request / Reply I was able to achieve what I wanted: CLI process notifies the main process about some occurred event (and optionally receives some data as a response) and continues its execution. A problem I have right now is that my CLI process hangs if the main process is off (is not available). The command still has to be executed and exit without notifying the main process if it's unable to establish a connection to a socket.

    Here is a simplified code snippet of my CLI running in asynchronous method:

    const { Request } = require('zeromq');
    async function notify() {
      let parsedResponse;
      try {
        const message = { event: 'hello world' };
        const socket = new Request({ connectTimeout: 500 });
        socket.connect('tcp://127.0.0.1:33332');
        await socket.send(JSON.stringify(message));
        const response = await socket.receive();
        parsedResponse = JSON.parse(response.toString());
      catch (e) {
        console.error(e);
      return parsedResponse;
    (async() => {
      const response = await notify();
      if (response) {
        console.log(response);
      else {
        console.log('Nothing is received.');
    })();
    

    I set connectTimeout option but wonder how to use it. The docs state:

    Sets how long to wait before timing-out a connect() system call. The connect() system call normally takes a long time before it returns a time out error. Setting this option allows the library to time out the call at an earlier interval.

    Looking at connect one see that it's not asynchronous:

    Connects to the socket at the given remote address and returns immediately. The connection will be made asynchronously in the background.

    Ok, probably send method of the socket will wait for connection establishment and reject a promise on connection timeout...but nothing happens there. send method is executed and the code is stuck at resolving receive. It's waiting for reply from the main process that will never come. So the main question is: "How to use connectTimeout option to handle socket's connection timeout?" I found an answer to similar question related to C++ but it actually doesn't answer the question (or I can't understand it). Can't believe that this option is useless and that it was added to the API in order to nobody can't use it.

    I also would be happy with some kind of a workaround, and found receiveTimeout option. Changing socket creation to

    const socket = new Request({ receiveTimeout: 500 });
    

    leads to the the rejection in receive method and the following output:

    { [Error: Socket temporarily unavailable] errno: 11, code: 'EAGAIN' }
    Nothing is received.
    

    Source code executed but the process doesn't exit in this case. Seems that some resources are busy and are not freed. When main process is on the line everything works fine, process exits and I have the following reply in output:

    { status: 'success' }
    

    So another question is: "How to exit the process gracefully on rejecting receive method with receiveTimeout?". Calling process.exit() is not an option here!

    P.S. My environment is:

  • Kubuntu 18.04.1;
  • Node 10.15.0;
  • ZeroMQ bindings are installed this way:

    $ yarn add [email protected] --zmq-shared
    

    ZeroMQ decouples the socket connection mechanics from message delivery. As the documentation states connectTimeout only influences the timeout of the connect() system call and does not affect the timeouts of sending/receiving messages.

    For example:

    const zmq = require("zeromq")
    async function run() {
      const socket = new zmq.Dealer({connectTimeout: 2000})
      socket.events.on("connect:retry", event => {
        console.log(new Date(), event.type)
      socket.connect("tcp://example.com:12345")
    run()
    

    The connect:retry event occurs every ~2 seconds:

    > node test.js
    2019-11-25T13:35:53.375Z connect:retry
    2019-11-25T13:35:55.536Z connect:retry
    2019-11-25T13:35:57.719Z connect:retry
    

    If we change connectTimeout to 200 then you can see the event will occur much more frequently. The timeout is not the only thing influencing the delay between the events, but it should be clear that it happens much quicker.

    > node test.js
    2019-11-25T13:36:05.271Z connect:retry
    2019-11-25T13:36:05.531Z connect:retry
    2019-11-25T13:36:05.810Z connect:retry
    

    Hope this clarifies the effect of connectTimeout.

    Thanks for clarifying a meaning of connectTimeout, but your code snippet doesn't work for me due to some reasons for local connections to tcp://localhost:12345 or tcp://127.0.0.1:12345. – ezze Nov 25, 2019 at 15:11 Sorry... Everything works fine! I forgot to stop the main process so connect event instead of connect:retry is occurred. This was very helpful! – ezze Nov 25, 2019 at 15:13 To summarize, I leave a reference to Github comment related to receiveTimeout option. In order to handle receiveTimeout rejection gracefully one should use the following options for Request instance: { linger: 0 } or { immediate: true, sendTimeout: 500, receiveTimeout: 500 }. – ezze Nov 25, 2019 at 15:23

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •