arangodb / arangojs

The official ArangoDB JavaScript driver.
https://arangodb.github.io/arangojs
Apache License 2.0
601 stars 107 forks source link

How to handle connection errors ? #415

Closed Sfinx closed 6 years ago

Sfinx commented 7 years ago

Seems like Database() do not have any error callbacks and do not have any of the connected()/state() functions. How to know that connection was successful/unsuccessful ? For example doing connection to the unresolved host will not return any errors at the following simple example:

var db_config = {
  url: 'http://root:@some.unknown.host:8529',
  retryConnection: true
};
var db = new arangodb.Database(db_config);
db.listCollections(/* false */)
 .then(collections => {
   for (var i in collections) {
     console.log(collections[i]);
   }
}, err => {
  console.log('listCollections error: ' + err);
});
maku commented 7 years ago

@Sfinx had the some problem - now i do a http call to /_api/version to check if DB is up

Sfinx commented 7 years ago

It is ugly and unprofessional. Moreover - the dedicated error callback must exist in Database class - [on_connection_error()] to be able for application to distinguish and react appropriately to the connections only errors. So app can use its own reconnect logic or at least know that something happened at the link way.

pluma commented 7 years ago

As the driver uses the HTTP API there is no concept of a persistent connection that could meaningfully be up or not so there's no point in being able to pass a callback to the database object itself.

We're in the process of adding a native connection layer that also supports the new Velocystream protocol and we'll likely revisit the connection logic for node once that has landed as well. I'm suspecting that the observed behaviour is triggered by the "retry" logic (the error handler is never reached because the driver keeps retrying unsuccessfully forever).

Sfinx commented 7 years ago

I thought that there exist some keepalive logic inside driver that can call this callback for the Database object.

Thanks anyway ! Will wait for the changes. For now I've made workaround calling dumb db.listCollections with retries disabled to be sure that connection was made successful.

pluma commented 7 years ago

Yes, there's a keepalive but the connections will eventually timeout if they're not used. The keepalive logic is mostly to prevent the overhead of re-opening connections when performing a large number of requests, not to keep persistent connections (which might block ArangoDB from handling other requests).

ansarizafar commented 7 years ago

@pluma Is there any update on native connection layer. I am considering to replace Mongodb with ArangoDB for an eCommerce project but I am surprised to know that ArangoDB client is using http connection to connect with the server. Will native client be available with up coming V3.2 release?

pluma commented 7 years ago

@ansarizafar That arangojs currently uses http shouldn't pose a problem in practice. All of the published performance comparisons use ArangoDB over http and most of our customers also use ArangoDB over http. However it is true that many node.js libraries that perform http requests are unnecessarily slow (often because of very limited support for keepalive). We iterated over several implementations before arriving at the http connection code we use now in arangojs.

Sfinx commented 7 years ago

We iterated over several implementations before arriving at the http connection code we use now in arangojs.

And what problems did you meet with websockets ? It is ideal for such things :

IMHO HTTP is "back to the 2000 years " way

baslr commented 7 years ago

HTTP is a protocol on top of TCP/IP. If a TCP/IP connection is established you can send whatever you want. In this case the data is interpreted as http. If http would be slow Berners-Lee would not have developed it.

Websockets are not secure per default.

The initial slowness of arangojs was due to the npm request library which had 1) a ton of useless code that arangojs did not needed 2) no connection reusage. A new TCP/IP connects starts to transmit slowly and then doubles the speed each time until a max send speed is achieved. I once performance tested arangojs3 https://github.com/baslr/fastango/issues/1 If you compare the second with the first image you can see the difference between no connection reusage and connection reusage.

To support websockets you first have to think about an API over websocket.

Sfinx commented 7 years ago

Websocket is based on TCP/IP too - if the connection is established you can send whatever you want. HTTP is not secure by default too. The API question is confusing: just use Velocypack directly or JSON if you do not like the binary data. Websokets perfectly support binary data over connection what I can't say about HTTP which is mostly old boring text protocol. My question is still do not answered - pluma told that "iterated over several implementations". I'm wonder what the problems he meets with websockets if he ever tried them.

baslr commented 7 years ago

With API I mean: you need a agreement how to do things: how to query, collection creation and so on. This has to be defined "the websocket way" not the HTTP way.

With "iterated over several implementations" he meant several http request module implementations / variants. I think there are no technical problems to implement an API via websockets. Its maybe not the top priority at the moment. ArangoDB itself has to handle websockets and thats currently not the case.

Possible in the short term would be a broker / proxy that exposes a websocket connection for the browser and does http to the server.

Sfinx commented 7 years ago

With JSON I mean JSON-RPC. Simple, looks like:


--> {"jsonrpc": "2.0", "method": "createCollection", "args": { "name": "myCollection" } }
<-- {"jsonrpc": "2.0", "result": { "code": 0, "msg": "success" } }
pluma commented 6 years ago

It's possible to determine whether a database configuration works by calling the get() method on the database object and waiting for it to resolve.

In the upcoming major release 6.0.0 async logic should no longer result in stuck promises, so as long as you wait for promises to resolve/reject, you should always be able to get an error if something went wrong.

westtrade commented 1 year ago

If http would be slow Berners-Lee would not have developed it.

If http would be slow Berners-Lee would not have developed it.

Really? 🤣. It's look like if Windows 95 would be slow Microsoft would not have developed it. 🤣🤣🤣 Good appeal to authority

pluma commented 1 year ago

@westtrade I'd prefer if you keep the tone more respectful. This isn't Twitter.