cube-js/cube

WebSocket Transport method blocks application if Cube is offline/incorrect URL/WebSockets disabled

Open

#6891 opened on Jul 16, 2023

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Rust (19,563 stars) (1,965 forks)batch import
help wanted

Description

Describe the bug Whenever you instantiate a CubeJsApi with the WebSocket Transport method and you attempt to use its API, the application will block waiting for the server's response. If the server is offline or you provide an incorrect URL or the WebSockets are not enabled, the application will block indefinitely.

This does not happen in the default transport method.

To Reproduce This issue is easily reproducible, you don't even have to install Cube. Simply using the code below will show how the application blocks waiting for the response, which never arrives.

  1. Assuming that we have a real-time data connection to Cube.js for subscribing queries:
import cubejs from '@cubejs-client/core';
import WebSocketTransport from '@cubejs-client/ws-transport';

const cubejsApi = cubejs({
  transport: new WebSocketTransport({
    authorization: CUBEJS_TOKEN,
    apiUrl: 'ws://localhost:4000/',
  }),
});
  1. And we want to subscribe/load a query:
const query = {
  "measures": ["stories.count"],
  "timeDimensions": [
    {
      "dimension": "stories.time",
      "dateRange": "last week",
      "granularity": "day"
    }
  ]
}

const subscription = await cubejsApi.subscribe( // HERE
  query,
  {},
  (error, resultSet) => {
    if (!error) {
      // handle the update
    }
  }
);
  1. Assuming that Cube.js is offline, the user provided the wrong URL or the WebSockets are disabled, the application will be waiting indefinitely.
  2. This also happens with any of the other methods, such as load, dryRun, meta...

Expected behavior The CubeJsApi API methods should not be executed indefinitely, they should have a timeout or a way to handle the cases where the request does not reach the server successfully or an error occurs.

Version: [v0.33.27]

Additional context

  1. I have tried setting Keep-Alive headers in the constructor above, they do not work either.
  2. Setting the Keep-Alive headers inside the WebSocket transport method does not work either.
  3. Even if you use the CubeJS REST API to test whether the server is online or not using the health endpoints, you do not have the guarantee that the server will have WebSockets enabled, which can also cause the application to wait indefinitely.

Contributor guide