Skip to content

Commit

Permalink
feat: implement abort identifies
Browse files Browse the repository at this point in the history
  • Loading branch information
Deivu committed Dec 20, 2024
1 parent 9e910d3 commit 0b69141
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 25 deletions.
8 changes: 4 additions & 4 deletions src/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ export function Fetch(url: string|URL, options: RequestOptions): Promise<FetchRe
*/
export async function FetchSessions(token: string): Promise<SessionObject> {
const url = new URL('https://discord.com/api/v10/gateway/bot');
const data = await Fetch(url, {
const response = await Fetch(url, {
method: 'GET',
headers: { authorization: `Bot ${token}` }
});
if (data.code >= 200 && data.code <= 299)
return JSON.parse(data.body);
if (response.code >= 200 && response.code <= 299)
return JSON.parse(response.body);
else
throw new Error(`Response received is not ok, code: ${data.code}`)
throw new Error(`Response received is not ok, code: ${response.code}`)
}

/**
Expand Down
56 changes: 35 additions & 21 deletions src/concurrency/ConcurrencyClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Fetch } from '../Util';
import { BaseWorker } from '../ipc/BaseWorker';
import { Delay, Fetch } from '../Util';

/**
* Internal class that is passed to @discordjs/ws to handle concurrency
Expand All @@ -16,33 +15,48 @@ export class ConcurrencyClient {
}

/**
* Method to try and acquire a lock for identify
* Method to try and acquire a lock for identify. This could never error or else it would hang out the whole system.
* Look at (https://github.com/discordjs/discord.js/blob/f1bce54a287eaa431ceb8b1996db87cbc6290317/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts#L321)
* If it errors that isn't anything from websocket shard, this will have issues
*/
public async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {
const url = new URL(`http://${this.address}:${this.port}/concurrency/acquire`);
url.searchParams.append('shardId', shardId.toString());

const response = await Fetch(url.toString(), {
method: 'POST',
headers: { authorization: this.password }
});
const listener = () => {
const url = new URL(`http://${this.address}:${this.port}/concurrency/cancel`);

// 202 = acquire lock cancelled, 204 = success, allow identify, 4xx = something bad happened
if (response.code !== 204) {
throw new Error('Acquire lock failed');
url.searchParams.append('shardId', shardId.toString());

Fetch(url.toString(), {
method: 'DELETE',
headers: { authorization: this.password }
}).catch(() => null);
}
}

/**
* Aborts an acquire lock request
*/
private abortIdentify(shardId: number): void {
const url = new URL(`http://${this.address}:${this.port}/concurrency/cancel`);
url.searchParams.append('shardId', shardId.toString());
try {
signal.addEventListener('abort', listener);

const response = await Fetch(url.toString(), {
method: 'POST',
headers: { authorization: this.password }
});

Fetch(url.toString(), {
method: 'DELETE',
headers: { authorization: this.password }
}).catch(() => null);
if (response.code === 202 || response.code === 204) {
// aborted request || ok request
return;
}

if (response.code >= 400 && response.code <= 499) {
// something happened server didn't accept your req
await Delay(1000);
return;
}
} catch (_) {
// this should not happen but we just delay if it happens
await Delay(1000);
} finally {
signal.removeEventListener('abort', listener);
}
}
}

0 comments on commit 0b69141

Please sign in to comment.