CardanoSolutions / ogmios

❇️ A WebSocket JSON/RPC bridge for Cardano
https://ogmios.dev
Mozilla Public License 2.0
304 stars 90 forks source link

Introduce reconnect / retry logic on the TypeScript client #308

Closed MartinSchere closed 3 months ago

MartinSchere commented 1 year ago

What Git revision / release tag are you using?

be859d6cc4adae512da31358e4870098ff741e83

Do you use any client SDK? If yes, which one?

Typescript client SDK

Describe what the problem is?

The websocket connection can be lost at any time, and if that's the case, there is no reconnect logic.

What should be the expected behavior?

There should be an option in the InteractionContext to specify a reconnect strategy.

If applicable, what are the logs from the server around the occurence of the problem?

WebSocketClosed: WebSocket is closed
MartinSchere commented 1 year ago

An easy solution is to use:

https://www.npmjs.com/package/reconnecting-websocket

Let me know if you want me to put up a PR @KtorZ

KtorZ commented 1 year ago

That's a good point, although, Ogmios is under some quite heavy change at the moment (v6 is coming). I'll be splitting the typescript-client in a separate repository soon. Happy to consider PRs from that new repository :)

MartinSchere commented 1 year ago

@KtorZ What's the ETA for the new release? If the migration is too heavy, then is it possible to fix this in the current release?

The socket interface does not have a connect method that we can call outside createInteractionContext, so this is blocking.

Happy to help with PRs.

KtorZ commented 1 year ago

I started looking into this. Note that it isn't as easy as plugging-in a 'reconnecting-websocket' for several reasons:

  1. First, the mini-protocols are actually stateful. So, loosing the connection has side-effects that a simple reconnection cannot accommodate. This is particular true for pretty much all protocols but the transaction submission. This is non-trivial and protocol-specific, so we would need to define a recovery strategy for each protocol so that the connection can be re-opened.

  2. We had issues in the past with the isomorphic aspect of the WebSocket. The node.js socket and browser sockets have (had, as it seems that recent versions fix this) vastly different APIs. So we had to create our own isomorphic wrapper. The reconnecting-websocket seems already better than the old ws as it's already compliant with the browser API. Yet, it doesn't provide some of the method we rely on such as removeAllListeners. So these would have to be refined.

  3. The project is 4 years old, have a few open unaddressed issues and doesn't look much maintained. Which doesn't inspire confidence in using it.

So, I've started rolling something relatively simple in the client but it's also taking longer than the time I had budgeted for it at the moment. So I'll park it aside and proceed with the release of 6.0.0 without it with the intention of bringing it in a following release once the TS client has been split apart in another repository.