node.jsexpressrethinkdb

NodeJS and RethinkDB - How to handle connection interruption (connection retry) when listening for table changes (realtime)?


ReqlRuntimeError: Connection is closed in:
r.table("users").changes()
^^^^^^^^^^^^^^^^^^^^^^^^^^
    at ReqlRuntimeError.ReqlError [as constructor] (/home/user/DEV/express-socketio/node_modules/rethinkdb/errors.js:23:13)
    at new ReqlRuntimeError (/home/user/DEV/express-socketio/node_modules/rethinkdb/errors.js:90:51)
    at mkErr (/home/user/DEV/express-socketio/node_modules/rethinkdb/util.js:177:10)
    at Feed.IterableResult._promptNext (/home/user/DEV/express-socketio/node_modules/rethinkdb/cursor.js:169:16)
    at Feed.IterableResult._addResponse (/home/user/DEV/express-socketio/node_modules/rethinkdb/cursor.js:84:12)
    at TcpConnection.<anonymous> (/home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:360:22)
    at TcpConnection.cancel (/home/user/DEV/express-socketio/node_modules/rethinkdb/util.js:26:16)
    at TcpConnection.cancel (/home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:789:43)
    at wrappedCb (/home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:270:17)
    at /home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:280:18
    at tryCatcher (/home/user/DEV/express-socketio/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._resolveFromResolver (/home/user/DEV/express-socketio/node_modules/bluebird/js/main/promise.js:483:31)
    at new Promise (/home/user/DEV/express-socketio/node_modules/bluebird/js/main/promise.js:71:37)
    at TcpConnection.<anonymous> (/home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:264:33)
    at TcpConnection.close (/home/user/DEV/express-socketio/node_modules/rethinkdb/util.js:43:16)
    at /home/user/DEV/express-socketio/node_modules/rethinkdb/net.js:782:46
[ERROR] 22:55:08 ReqlRuntimeError: Connection is closed in:
r.table("users").changes()
^^^^^^^^^^^^^^^^^^^^^^^^^^

I had this error when executing a test as following:

  1. My nodejs is listening for changes in a table (realtime),
  2. then I simulate a connection interruption by turning off the rethinkdb docker container
  3. and the error breaks the whole application.

I'm looking for how to handle this kind of error, so the application knows the connection was lost, but, in some way, after a period of X minutes/seconds/etc, try to reconnect, or even restart the application, I don't know...

I found this https://github.com/rethinkdb/rethinkdb/issues/4886, but nothing about avoiding app crash or trying to reconnect after a connection loss.

How can I proceed with this? Any thoughts? Thanks in advance.


Solution

  • The example isn't that complete. Consider this code that might run when a websocket is opened on a server:

    // write every change to file
    
    function onChange(err, cursor) {
      // log every change to console
      // Change format: https://rethinkdb.com/docs/changefeeds/javascript/
      cursor.each(console.log);
    
      // if file not open, open file 
      openFile()
    
      // write changes to file
      cursor.each(writeChangesToFile)
    
      // if you decide you no longer want these changes
      if (stopChangesNow) {
        cursor.close() // https://rethinkdb.com/api/javascript/#close-cursor
        cancel()
      }
    }
    
    // stop writing changes
    
    function cancel(stream) {
      // close file opened above
      closeFile()
    }
    
    try {
      r.table('users').changes().run(conn, onChange)
    } catch(e) {
      cancel()
    }
    

    You need the run() so your application can process the changes.

    You might not need the cancel() function unless you need to cleanup a socket, output stream, file handles, etc. You need the try/catch to keep from crashing.

    When a REST server crashes, it only terminates requests in progress.

    When a websocket server crashes, it terminates all it's sessions causing problems for a lot more users.