Skip to content
Snippets Groups Projects
Commit d6588258 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame :jack_o_lantern:
Browse files

fixup! Bug 40597: Implement TorSettings module

Bug 41114: Fix no-async-promise-executor on TorConnect.

Move the responsibility of starting the next state callback and broadcat
the state change from the begin function to the transition function.
This is what will actually empower us to remove the async promise
executor, because they will not have to block the state change anymore.
parent f4cdebff
Branches
Tags
1 merge request!980Bug 42512: Rebased alpha onto Firefox 115.10.0esr
......@@ -132,6 +132,7 @@ export const TorConnectTopics = Object.freeze({
// cancels a bootstrap attempt)
class StateCallback {
#state;
#promise;
#transitioning = false;
on_transition = nextState => {};
......@@ -142,17 +143,16 @@ class StateCallback {
async begin(...args) {
lazy.logger.trace(`Entering ${this.#state} state`);
// Make sure we always have an actual promise.
try {
// this Promise will block until this StateCallback has completed its work
await Promise.resolve(this._callback(...args));
lazy.logger.info(`Exited ${this.#state} state`);
// handled state transition
Services.obs.notifyObservers(
{ state: this._nextState.state },
TorConnectTopics.StateChange
);
this._nextState.begin(...this._nextStateArgs);
this.#promise = Promise.resolve(this._callback(...args));
} catch (err) {
this.#promise = Promise.reject(err);
}
try {
// If the callback throws, transition to error as soon as possible.
await this.#promise;
lazy.logger.info(`${this.#state}'s callback is done`);
} catch (obj) {
TorConnect._changeState(
TorConnectState.Error,
......@@ -162,19 +162,47 @@ class StateCallback {
}
}
transition(nextState, ...args) {
async transition(nextState, ...args) {
lazy.logger.trace(
`Transition requested from ${this.#state} to ${nextState.state}`,
args
);
this._nextState = nextState;
this._nextStateArgs = [...args];
if (this.#transitioning) {
// Should we check turn this into an error?
// It will make dealing with the error state harder.
lazy.logger.warn("this.#transitioning is already true.");
}
// Signal we should bail out ASAP.
this.#transitioning = true;
// calls the on_transition callback to resolve any async work or do per-state cleanup
// this call to on_transition should resolve the async work currentlying going on in this.begin()
this.on_transition(nextState.state);
this.#transitioning = true;
lazy.logger.debug(
"Waiting for the previous state's callback to return before the transition."
);
try {
await this.#promise;
} catch (e) {
// begin should already transform exceptions into the error state.
if (nextState.state !== TorConnectState.Error) {
lazy.logger.error(
`Refusing the transition to ${nextState.state} because the callback threw.`,
e
);
return;
}
}
lazy.logger.debug("Ready to transition");
Services.obs.notifyObservers(
{ state: nextState.state },
TorConnectTopics.StateChange
);
nextState.begin(...args);
}
get transitioning() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment