mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 19:45:05 +01:00
Convert RequestScheduler.js to ts
This commit is contained in:
parent
0aae31a450
commit
cf54b78af7
@ -23,7 +23,7 @@ import {HomeServerApi} from "./net/HomeServerApi.js";
|
|||||||
import {Reconnector, ConnectionStatus} from "./net/Reconnector";
|
import {Reconnector, ConnectionStatus} from "./net/Reconnector";
|
||||||
import {ExponentialRetryDelay} from "./net/ExponentialRetryDelay";
|
import {ExponentialRetryDelay} from "./net/ExponentialRetryDelay";
|
||||||
import {MediaRepository} from "./net/MediaRepository";
|
import {MediaRepository} from "./net/MediaRepository";
|
||||||
import {RequestScheduler} from "./net/RequestScheduler.js";
|
import {RequestScheduler} from "./net/RequestScheduler";
|
||||||
import {Sync, SyncStatus} from "./Sync.js";
|
import {Sync, SyncStatus} from "./Sync.js";
|
||||||
import {Session} from "./Session.js";
|
import {Session} from "./Session.js";
|
||||||
import {PasswordLoginMethod} from "./login/PasswordLoginMethod";
|
import {PasswordLoginMethod} from "./login/PasswordLoginMethod";
|
||||||
|
@ -19,33 +19,43 @@ import {AbortError} from "../../utils/error";
|
|||||||
import {HomeServerError} from "../error.js";
|
import {HomeServerError} from "../error.js";
|
||||||
import {HomeServerApi} from "./HomeServerApi.js";
|
import {HomeServerApi} from "./HomeServerApi.js";
|
||||||
import {ExponentialRetryDelay} from "./ExponentialRetryDelay";
|
import {ExponentialRetryDelay} from "./ExponentialRetryDelay";
|
||||||
|
import {Clock} from "../../platform/web/dom/Clock.js";
|
||||||
|
import type {HomeServerRequest} from "./HomeServerRequest.js";
|
||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
constructor(methodName, args) {
|
public readonly methodName: string;
|
||||||
this._methodName = methodName;
|
public readonly args: any[];
|
||||||
this._args = args;
|
public resolve: (result: Response) => void;
|
||||||
|
public reject: (error: AbortError) => void;
|
||||||
|
public requestResult?: HomeServerRequest;
|
||||||
|
private readonly _responsePromise: Promise<Response>;
|
||||||
|
|
||||||
|
constructor(methodName: string, args: any[]) {
|
||||||
|
this.methodName = methodName;
|
||||||
|
this.args = args;
|
||||||
this._responsePromise = new Promise((resolve, reject) => {
|
this._responsePromise = new Promise((resolve, reject) => {
|
||||||
this._resolve = resolve;
|
this.resolve = resolve;
|
||||||
this._reject = reject;
|
this.reject = reject;
|
||||||
});
|
});
|
||||||
this._requestResult = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abort() {
|
abort(): void {
|
||||||
if (this._requestResult) {
|
if (this.requestResult) {
|
||||||
this._requestResult.abort();
|
this.requestResult.abort();
|
||||||
} else {
|
} else {
|
||||||
this._reject(new AbortError());
|
this.reject(new AbortError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response() {
|
response(): Promise<Response> {
|
||||||
return this._responsePromise;
|
return this._responsePromise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeServerApiWrapper {
|
class HomeServerApiWrapper {
|
||||||
constructor(scheduler) {
|
private readonly _scheduler: RequestScheduler;
|
||||||
|
|
||||||
|
constructor(scheduler: RequestScheduler) {
|
||||||
this._scheduler = scheduler;
|
this._scheduler = scheduler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,21 +70,22 @@ for (const methodName of Object.getOwnPropertyNames(HomeServerApi.prototype)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RequestScheduler {
|
export class RequestScheduler {
|
||||||
constructor({hsApi, clock}) {
|
private readonly _hsApi: HomeServerApi;
|
||||||
|
private readonly _clock: Clock;
|
||||||
|
private readonly _requests: Set<Request> = new Set();
|
||||||
|
private _stopped = false;
|
||||||
|
private _wrapper = new HomeServerApiWrapper(this);
|
||||||
|
|
||||||
|
constructor({ hsApi, clock }: { hsApi: HomeServerApi; clock: Clock }) {
|
||||||
this._hsApi = hsApi;
|
this._hsApi = hsApi;
|
||||||
this._clock = clock;
|
this._clock = clock;
|
||||||
this._requests = new Set();
|
|
||||||
this._isRateLimited = false;
|
|
||||||
this._isDrainingRateLimit = false;
|
|
||||||
this._stopped = true;
|
|
||||||
this._wrapper = new HomeServerApiWrapper(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get hsApi() {
|
get hsApi(): HomeServerApiWrapper {
|
||||||
return this._wrapper;
|
return this._wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop(): void {
|
||||||
this._stopped = true;
|
this._stopped = true;
|
||||||
for (const request of this._requests) {
|
for (const request of this._requests) {
|
||||||
request.abort();
|
request.abort();
|
||||||
@ -82,40 +93,49 @@ export class RequestScheduler {
|
|||||||
this._requests.clear();
|
this._requests.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start(): void {
|
||||||
this._stopped = false;
|
this._stopped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hsApiRequest(name, args) {
|
_hsApiRequest(name: string, args: any[]): Request {
|
||||||
const request = new Request(name, args);
|
const request = new Request(name, args);
|
||||||
this._doSend(request);
|
this._doSend(request);
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _doSend(request) {
|
private async _doSend(request: Request): Promise<void> {
|
||||||
this._requests.add(request);
|
this._requests.add(request);
|
||||||
try {
|
try {
|
||||||
let retryDelay;
|
let retryDelay: ExponentialRetryDelay | undefined;
|
||||||
while (!this._stopped) {
|
while (!this._stopped) {
|
||||||
try {
|
try {
|
||||||
const requestResult = this._hsApi[request._methodName].apply(this._hsApi, request._args);
|
const requestResult = this._hsApi[
|
||||||
|
request.methodName
|
||||||
|
].apply(this._hsApi, request.args);
|
||||||
// so the request can be aborted
|
// so the request can be aborted
|
||||||
request._requestResult = requestResult;
|
request.requestResult = requestResult;
|
||||||
const response = await requestResult.response();
|
const response = await requestResult.response();
|
||||||
request._resolve(response);
|
request.resolve(response);
|
||||||
return;
|
return;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof HomeServerError && err.errcode === "M_LIMIT_EXCEEDED") {
|
if (
|
||||||
|
err instanceof HomeServerError &&
|
||||||
|
err.errcode === "M_LIMIT_EXCEEDED"
|
||||||
|
) {
|
||||||
if (Number.isSafeInteger(err.retry_after_ms)) {
|
if (Number.isSafeInteger(err.retry_after_ms)) {
|
||||||
await this._clock.createTimeout(err.retry_after_ms).elapsed();
|
await this._clock
|
||||||
|
.createTimeout(err.retry_after_ms)
|
||||||
|
.elapsed();
|
||||||
} else {
|
} else {
|
||||||
if (!retryDelay) {
|
if (!retryDelay) {
|
||||||
retryDelay = new ExponentialRetryDelay(this._clock.createTimeout);
|
retryDelay = new ExponentialRetryDelay(
|
||||||
|
this._clock.createTimeout
|
||||||
|
);
|
||||||
}
|
}
|
||||||
await retryDelay.waitForRetry();
|
await retryDelay.waitForRetry();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
request._reject(err);
|
request.reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user