Skip to content

Add autoconnect to ScProvider#5217

Merged
jacogr merged 6 commits intomasterfrom
nik-add-retry-to-scprovider
Sep 23, 2022
Merged

Add autoconnect to ScProvider#5217
jacogr merged 6 commits intomasterfrom
nik-add-retry-to-scprovider

Conversation

@wirednkod
Copy link
Copy Markdown
Member

@wirednkod wirednkod commented Sep 14, 2022

Resolves issue mentioned in substrate connect repo - issues #1243 and #1141

@wirednkod wirednkod marked this pull request as draft September 14, 2022 14:14
@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 14, 2022

The objective is to add an equivalent of this block of code:

if (this.#autoConnectMs > 0) {
setTimeout((): void => {
this.connectWithRetry().catch(() => {
// does not throw
});
}, this.#autoConnectMs);
}

We want to automatically reconnect when we disconnect.

@wirednkod wirednkod marked this pull request as ready for review September 15, 2022 11:19
@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 15, 2022

So it's not that simple. The problem to solve is not what to do when the health checker says that we're not healthy. The problem to solve is what to do when the connection to the extension dies. In other words, you should try to reconnect when an error event happens. The problem is that there's no way right now from the API of the connect package to detect when the connection to the extension has died, other than the fact that the Chain.sendJsonRpc and Chain.remove functions throw an exception.

@wirednkod
Copy link
Copy Markdown
Member Author

So it's not that simple. The problem to solve is not what to do when the health checker says that we're not healthy. The problem to solve is what to do when the connection to the extension dies. In other words, you should try to reconnect when an error event happens. The problem is that there's no way right now from the API of the connect package to detect when the connection to the extension has died, other than the fact that the Chain.sendJsonRpc and Chain.remove functions throw an exception.

Im not sure why you refer to the extension. At the moment, When laptop goes to sleep and then resumes, the current code was cleaning up all subscriptions due to the emit of disconnect. The health checker continues to show that we are healthy, but since the subscription is cleared - there is no way to communicate something back to the App.
What is solved in this PR, is to avoid killing subscriptions when autoconnect is set to true (default and when a manual disconnect does not take place).
This way when the computer resumes, the subscription still exists and receives all the messages.

jacogr
jacogr previously approved these changes Sep 16, 2022
Copy link
Copy Markdown
Member

@jacogr jacogr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It look sane. Happy to approve even if it only partly moves in the right direction.

@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 16, 2022

This PR "seems" wrong to me. It would mean that the provider can report a disconnected event, then later a connected event, without the active subscriptions being killed.

I can't strictly say that this is wrong because it depends on the small details of the API of the Provider interface, and these small details aren't written anywhere. But it definitely feels wrong to me.

@wirednkod
Copy link
Copy Markdown
Member Author

The way I approached it, is that the subscription should be cleaned only if disconnect is called. Everything else (emit connect - emit disconnect - emit connect) seems to me as a network failure (intentional through sleep mode or not), and IMO subscriptions should not be cleared).

@jacogr
Copy link
Copy Markdown
Member

jacogr commented Sep 16, 2022

So the events handling would depend fully on the underlying layer. For instance in WS, when you get a disconnect, it would mean that the underlying transport is gone and dead, you will never receive anything on it again. In the WsProvider, after a network layer disconnect/re-connect, all subs that were existing re-created to ensure continuance. (Just continuing with the current ones will never have any data)

So in this case, if a disconnect/reconnect means that the existing subs are still ongoing, it would be fine. If not, it would mean you have subscriptions that won't get any data back.

@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 16, 2022

The entire and only reason why we have this health checker system and why we generate disconnected and connected events is precisely to prevent PolkadotJS from querying information at certain moments.

When we generate a "disconnected" event, we precisely mean "DO NOT USE THE CLIENT RIGHT NOW /!\ /!"

It feels extremely surprising to me that subscriptions would stay alive during this mode.
We should, IMO, do it the same way as the WsProvider and treat "disconnected" as "the client is completely unaccessible", rather than in a mode where everything is unaccessible but subscriptions stay alive.

@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 16, 2022

The ScProvider is currently behaving the same way as the WsProvider, and this PR makes the ScProvider more tolerant in an attempt to fix a problem somewhere.

To me this indicates that this is not the correct fix. If things work fine with the WsProvider, and they do, then they should work fine with the ScProvider as well. And if necessary we should instead try to make the ScProvider behave more similarly to the WsProvider, rather than differently.

@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 16, 2022

Ok, read more, and the WsProvider re-subscribes:

#resubscribe = (): void => {

I don't really understand why this is done in the WsProvider rather than a different layer, but this is what we should do in the ScProvider.

@wirednkod wirednkod requested review from jacogr and pgolovkin and removed request for pgolovkin September 19, 2022 10:59
Copy link
Copy Markdown
Member

@jacogr jacogr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small comment, looks sane otherwise.

It could make sense, now that there are 2 providers that require the same functionality, to extract resubscriptions - not for this PR, it would need investigation (could probably use an issue).

Comment thread packages/rpc-provider/src/substrate-connect/ScProvider.ts Outdated
@wirednkod
Copy link
Copy Markdown
Member Author

could probably use an issue

As per your request: #5228

@wirednkod wirednkod requested review from jacogr and removed request for pgolovkin September 23, 2022 07:32
Copy link
Copy Markdown
Member

@jacogr jacogr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

@jacogr jacogr merged commit 421f767 into master Sep 23, 2022
@jacogr jacogr deleted the nik-add-retry-to-scprovider branch September 23, 2022 09:47
@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 23, 2022

It's missing a this.#resubscribeMethods.delete when you unsubscribe

@tomaka
Copy link
Copy Markdown
Contributor

tomaka commented Sep 23, 2022

It's also not clear to me why resubscribeMethods needs to be a different map than subscriptions

@wirednkod
Copy link
Copy Markdown
Member Author

It's also not clear to me why resubscribeMethods needs to be a different map than subscriptions

Because subscriptions upon disconnect are cleared. Thats the initial source of the problem I described before. When disconnect occurs the cleanup empties the Map and thus reconnect cannot work.

I'll fix the .delete on a new PR.

@polkadot-js-bot
Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@polkadot-js polkadot-js locked as resolved and limited conversation to collaborators Sep 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants