Skip to content

Commit

Permalink
chore: abort quote requests
Browse files Browse the repository at this point in the history
  • Loading branch information
micaelae committed Oct 16, 2024
1 parent a594615 commit 3703e95
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 41 deletions.
85 changes: 45 additions & 40 deletions app/scripts/controllers/bridge/bridge-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@ const metadata: StateMetadata<{ bridgeState: BridgeControllerState }> = {
},
};

const RESET_STATE_ABORT_MESSAGE = 'Reset controller state';

export default class BridgeController extends StaticIntervalPollingController<
typeof BRIDGE_CONTROLLER_NAME,
{ bridgeState: BridgeControllerState },
BridgeControllerMessenger
> {
#pollingTokenForQuotes: string | undefined;

#abortController: AbortController | undefined;

constructor({ messenger }: { messenger: BridgeControllerMessenger }) {
super({
name: BRIDGE_CONTROLLER_NAME,
Expand Down Expand Up @@ -102,27 +106,26 @@ export default class BridgeController extends StaticIntervalPollingController<
updateBridgeQuoteRequestParams = async (
paramsToUpdate: Partial<QuoteRequest>,
) => {
this.stopAllPolling();
this.#abortController?.abort('Quote request updated');

if (this.#pollingTokenForQuotes) {
this.stopPollingByPollingToken(this.#pollingTokenForQuotes);
}
// TODO abort previous fetchBridgeQuotes request
const { bridgeState } = this.state;
const updatedQuoteRequest = {
...bridgeState.quoteRequest,
...paramsToUpdate,
};

const { quotes, quotesLastFetched, quotesLoadingStatus } =
DEFAULT_BRIDGE_CONTROLLER_STATE;
this.update((_state) => {
_state.bridgeState = {
...bridgeState,
quoteRequest: {
...updatedQuoteRequest,
},
quotes,
quotesLastFetched,
quotesLoadingStatus,
..._state.bridgeState,
quoteRequest: updatedQuoteRequest,
quotes: DEFAULT_BRIDGE_CONTROLLER_STATE.quotes,
quotesLastFetched: DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched,
quotesLoadingStatus:
DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus,
};
});

Expand Down Expand Up @@ -151,26 +154,16 @@ export default class BridgeController extends StaticIntervalPollingController<
insufficientBal,
},
);
} else {
this.stopAllPolling();
this.update((_state) => {
_state.bridgeState = {
..._state.bridgeState,
quotes,
quotesLastFetched,
quotesLoadingStatus,
};
});
}
};

resetState = () => {
this.stopAllPolling();
this.#abortController?.abort(RESET_STATE_ABORT_MESSAGE);

this.update((_state) => {
_state.bridgeState = {
..._state.bridgeState,
...DEFAULT_BRIDGE_CONTROLLER_STATE,
quotes: [],
bridgeFeatureFlags: _state.bridgeState.bridgeFeatureFlags,
};
});
Expand Down Expand Up @@ -203,57 +196,69 @@ export default class BridgeController extends StaticIntervalPollingController<
await this.#setTokens(chainId, 'destTokens');
};

switchToAndFromInputs = () => {
const { bridgeState } = this.state;
const { quotes, quotesLastFetched, quotesLoadingStatus, quoteRequest } =
DEFAULT_BRIDGE_CONTROLLER_STATE;
switchToAndFromInputs = async () => {
this.stopAllPolling();
this.#abortController?.abort('Switched to and from inputs');

const { bridgeState } = this.state;
this.update((_state) => {
_state.bridgeState = {
...bridgeState,
srcTopAssets: bridgeState.destTopAssets,
destTopAssets: bridgeState.srcTopAssets,
srcTokens: bridgeState.destTokens,
destTokens: bridgeState.srcTokens,
quotes,
quotesLastFetched,
quotesLoadingStatus,
quoteRequest: {
...quoteRequest,
srcChainId: bridgeState.quoteRequest.destChainId,
destChainId: bridgeState.quoteRequest.srcChainId,
srcTokenAddress: bridgeState.quoteRequest.destTokenAddress,
destTokenAddress: bridgeState.quoteRequest.srcTokenAddress,
},
quotes: DEFAULT_BRIDGE_CONTROLLER_STATE.quotes,
quotesLastFetched: DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched,
quotesLoadingStatus:
DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus,
};
});

await this.updateBridgeQuoteRequestParams({
srcChainId: bridgeState.quoteRequest.destChainId,
destChainId: bridgeState.quoteRequest.srcChainId,
srcTokenAddress: bridgeState.quoteRequest.destTokenAddress,
destTokenAddress: bridgeState.quoteRequest.srcTokenAddress,
srcTokenAmount: '',
});
};

#fetchBridgeQuotes = async (request: QuoteRequest) => {
this.#abortController?.abort('New quote request');
this.#abortController = new AbortController();
if (request.srcChainId === request.destChainId) {
return;
}
const { bridgeState } = this.state;
this.update((_state) => {
_state.bridgeState = {
...bridgeState,
quotesLastFetched: Date.now(),
quotesLoadingStatus: RequestStatus.LOADING,
};
});

try {
// TODO abort controller integration
const quotes = await fetchBridgeQuotes(request);
const quotes = await fetchBridgeQuotes(
request,
this.#abortController.signal,
);
this.update((_state) => {
_state.bridgeState = {
...bridgeState,
quotes,
quotesLastFetched: Date.now(),
quotesLoadingStatus: RequestStatus.FETCHED,
};
});
} catch (error) {
console.error('Failed to fetch bridge quotes', error);
this.update((_state) => {
_state.bridgeState = {
...bridgeState,
quoteRequest:
error === RESET_STATE_ABORT_MESSAGE
? DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest
: _state.bridgeState.quoteRequest,
quotesLoadingStatus: RequestStatus.ERROR,
};
});
Expand Down
7 changes: 6 additions & 1 deletion ui/pages/bridge/bridge.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,18 @@ export async function fetchBridgeTokens(
// Returns a list of bridge tx quotes
export async function fetchBridgeQuotes(
request: QuoteRequest,
signal: AbortSignal,
): Promise<QuoteResponse[]> {
const url = `${BRIDGE_API_BASE_URL}/getQuote?${Object.entries(request)
.map(([k, v]) => `${k}=${v}`)
.join('&')}`;
const quotes = await fetchWithCache({
url,
fetchOptions: { method: 'GET', headers: CLIENT_ID_HEADER },
fetchOptions: {
method: 'GET',
headers: CLIENT_ID_HEADER,
signal,
},
cacheOptions: { cacheRefreshTime: 0 },
functionName: 'fetchBridgeQuotes',
});
Expand Down

0 comments on commit 3703e95

Please sign in to comment.