cube-js / cube

📊 Cube — The Semantic Layer for Building Data Applications
https://cube.dev
Other
17.94k stars 1.78k forks source link

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

Open wurzy opened 1 year ago

wurzy commented 1 year ago

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/', }), });

2. And we want to subscribe/load a query:
```js
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.
github-actions[bot] commented 1 year ago

If you are interested in working on this issue, please leave a comment below and we will be happy to assign the issue to you. If this is the first time you are contributing a Pull Request to Cube.js, please check our contribution guidelines. You can also post any questions while contributing in the #contributors channel in the Cube.js Slack.