-
Notifications
You must be signed in to change notification settings - Fork 1.2k
offline boot: does not (re)bind #1837
Comments
seems like this would need some combination of an for whatever reason, healing connections for web apps seems to be a Hard Problem -- gmail, slack, etc all rely heavily on the manual checks ( |
the API that I would like would be a libp2p level facility that imitates the browser online status, which the app can rely on regardless of the transport overall, this feels like a libp2p concern, and the real fix probably requires implementing the optional addresses at that level as per #1793 (comment) |
another idea would be to just periodically manually retry binding from inside the app as an interim solution, though I don't think there's an |
cc @mkg20001 |
I'm unsure whether the underlying logic for this should go into libp2p or ws-star-multi itself, Possible solutions:
I'd go for either putting it into Opinions? |
So the pseudo-interface I made up so far: class libp2p {
// event(per-listener) reconnect(Error?: error, Number?: nextReconnectTime)
// event(global) reconnect(Object?{[listener.address]: Error?}: errors, Number?: nextReconnectTime)
set reconnectsEnabled (bool) {
this._reconnectsEnabled = bool = Boolean(bool)
if (bool) {
recheckAndReconnect()
} else {
stopAllReconnects()
}
}
get reconnectsEnabled() {
return this._reconnectsEnabled
}
function recheckAndReconnect() {
if (this._scheudledReconnect) {
clearTimeout(this._scheudledReconnect)
this._scheudledReconnect = null
this._scheudledReconnectAt = null
}
iterateOverListeners(listener => {
if (listener.needReconnect) {
// somehow iterate over all listeners as key-value where address is key and do async listen
// so it yields an object in the form of {"/ip4": Error("Something...")}
}
})
}
function _reconnectListener(listener) {
listener.listen(listener.address, (err) => {
if (err) {
this._reconnectErrors[listener.address] = err // store errors for ui updates
if (!this._scheudledReconnect) {
const reconnectAt = Date.now() + this._reconnectCooldown // exponential growth? static? user specifiable growth function?
this._scheudledReconnect = setTimeout(this.recheckAndReconnect.bind(this), reconnectAt) // scheudle reconnect
this._scheudledReconnectTime = reconnectAt
}
this.emit('reconnect', this._reconnectErrors, this._scheudledReconnectTime) // notify app
listener.emit('reconnect', err, this._scheudledReconnectTime) // notify per-listener watcher
} else {
delete this._reconnectErrors[listener.address]
this.emit('reconnect', this._reconnectErrors, this._scheudledReconnectTime) // notify app
listener.emit('reconnect') // notify per-listener watcher
}
})
}
/*
listener.on('close', () => {
if (!libp2pIsStopping) {
if (this._reconnectsEnabled && !this._scheudledReconnect) {
listener.needReconnect = true
} else {
this._reconnectListener(listener)
}
}
})
*/
} An app would hook it like this (but with actual react code, and not some random JSX-returning functions): function offlineMode (enabled) {
libp2p._reconnectsEnabled = enabled
}
libp2p.on('reconnect', (errors, nextReconnect) {
if (errors) {
return (<div>
<h2>Reconnecting in {(nextReconnect - Date.now()) / 1000}...</h2>
{Object.keys(errors).map(address => (<h4>{address} couldn't be reconnected: {errors[address]}))}
</div>)
} else {
return (<div>Connected</div>)
}
}) (Noticed that I missed events for when it begins reconnecing. This could either be a seperate event ( |
I think libp2p should try to do a good effort of keeping the peer connected:
Implementing this in libp2p would avoid these 2 problems, implementing reconnect logic in a generic way. Also, I think that the reconnecting behaviour should be the default behaviour and not require special configuration. IMO, opting out of this behaviour should be the exception. Here is to better offline / intermittent-connectivity support from libp2p! :) |
@pgte That's sort of what I've implemented in #1837 (comment) Btw, could I get some feedback on that idea before I start implementing it? |
Also I've got a few questions that I need answered before continuing with this:
|
@mkg20001 I'm not sure about the internals or the API (perhaps it's better to ask @jacobheun et al.), but in my opinion, this shouldn't require any new user-land API, reconnects should work out of the box. One question (also to @jacobheun et al.) is what should be the transport interface that allows libp2p to manage dis/reconnects? I'm guessing the de-facto standard in node.js land would be emitting the events "connect" (once connected), "error", "reconnecting" and "end". I think that "connecting" can also be useful. Not sure how this plays with the current interface provided by a libp2p transport... Internally, I'd like to see an exponential backoff (in the past I think I've used this package to achieve that), without a permanent failure (backoff ceils at about a few seconds). IMO, all these backoff settings should be overridable. |
The equivalent for
In my proposal it did, but there are also extra APIs to force a reconnect at any point such as for adding a "Reconnect Now" button next to the countdown. IMO adding a few APIs to steer behavior is definitively a good idea. Other than that I'd agree on the mentioned things. Btw, @jacobheun could I get some feedback on my initial idea (See above)? |
I've started an issue in libp2p, libp2p/js-libp2p#312, to track this since it's been discussed in several places for various reasons and will require updates to several modules. I added my thoughts to the issue there. @mkg20001 the main thing I can see becoming an issue there is with multiple transports and multiple addresses. Consuming |
Please follow progress on this issue here libp2p/js-libp2p#312 |
When using js-ipfs v0.34.2 and websocket-star-multi with the
ignore_no_online
option, I'm able to start an js-ipfs embedded node while I have no internet connection.But, if I regain connectivity, the transport doesn't try to bind to any of the given ws-star servers, rendering the current process unreachable.
What I would like to happen is to be able to bind (and rebind) if connectivity is intermitted, in spite of the node starting offline.
Is this something that should be handled by a) the app (and how?) b) libp2p or c) the ws-star-multi transport?
/cc @parkan
The text was updated successfully, but these errors were encountered: