mirror of
https://github.com/block/buzz.git
synced 2026-11-01 15:01:12 +00:00
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz> Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import type { ProjectChannelRequest } from "@/features/projects/projectChannelRequest";
|
|
|
|
export const MAX_PENDING_PROJECT_CHANNEL_REQUESTS = 100;
|
|
const MAX_SEEN_PROJECT_CHANNEL_REQUEST_IDS =
|
|
MAX_PENDING_PROJECT_CHANNEL_REQUESTS * 2 + 1;
|
|
|
|
export type AcceptedProjectChannelRequest = {
|
|
agentPubkey: string;
|
|
request: ProjectChannelRequest;
|
|
};
|
|
|
|
export type ProjectChannelRequestQueue = {
|
|
activeRequestId: string | null;
|
|
pending: AcceptedProjectChannelRequest[];
|
|
seenRequestIds: Set<string>;
|
|
};
|
|
|
|
export type EnqueueProjectChannelRequestResult =
|
|
| { status: "show"; candidate: AcceptedProjectChannelRequest }
|
|
| { status: "queued" | "duplicate" | "overflow" };
|
|
|
|
export function createProjectChannelRequestQueue(): ProjectChannelRequestQueue {
|
|
return {
|
|
activeRequestId: null,
|
|
pending: [],
|
|
seenRequestIds: new Set(),
|
|
};
|
|
}
|
|
|
|
export function enqueueProjectChannelRequest(
|
|
queue: ProjectChannelRequestQueue,
|
|
candidate: AcceptedProjectChannelRequest,
|
|
): EnqueueProjectChannelRequestResult {
|
|
const requestId = candidate.request.requestId;
|
|
if (queue.seenRequestIds.has(requestId)) return { status: "duplicate" };
|
|
|
|
if (
|
|
queue.activeRequestId !== null &&
|
|
queue.pending.length >= MAX_PENDING_PROJECT_CHANNEL_REQUESTS
|
|
) {
|
|
// Keep the requests already visible to the owner and drop the newest one.
|
|
// Do not mark it seen: a later retry may be accepted after space opens.
|
|
return { status: "overflow" };
|
|
}
|
|
|
|
queue.seenRequestIds.add(requestId);
|
|
pruneSeenRequestIds(queue);
|
|
|
|
if (queue.activeRequestId === null) {
|
|
queue.activeRequestId = requestId;
|
|
return { status: "show", candidate };
|
|
}
|
|
|
|
queue.pending.push(candidate);
|
|
return { status: "queued" };
|
|
}
|
|
|
|
export function advanceProjectChannelRequestQueue(
|
|
queue: ProjectChannelRequestQueue,
|
|
): AcceptedProjectChannelRequest | null {
|
|
const next = queue.pending.shift() ?? null;
|
|
queue.activeRequestId = next?.request.requestId ?? null;
|
|
pruneSeenRequestIds(queue);
|
|
return next;
|
|
}
|
|
|
|
function pruneSeenRequestIds(queue: ProjectChannelRequestQueue) {
|
|
if (queue.seenRequestIds.size <= MAX_SEEN_PROJECT_CHANNEL_REQUEST_IDS) return;
|
|
|
|
const pendingIds = new Set(
|
|
queue.pending.map((candidate) => candidate.request.requestId),
|
|
);
|
|
for (const requestId of queue.seenRequestIds) {
|
|
if (requestId !== queue.activeRequestId && !pendingIds.has(requestId)) {
|
|
queue.seenRequestIds.delete(requestId);
|
|
if (queue.seenRequestIds.size <= MAX_SEEN_PROJECT_CHANNEL_REQUEST_IDS) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|