Pass Request signal down from API controllers

This commit is contained in:
Alex Gleason
2024-01-23 15:53:29 -06:00
parent 77f2e2d940
commit 5b24b7ad39
26 changed files with 81 additions and 59 deletions

View File

@@ -132,9 +132,10 @@ const accountStatusesController: AppController = async (c) => {
const pubkey = c.req.param('pubkey');
const { since, until } = paginationSchema.parse(c.req.query());
const { pinned, limit, exclude_replies, tagged } = accountStatusesQuerySchema.parse(c.req.query());
const { signal } = c.req.raw;
if (pinned) {
const [pinEvent] = await eventsDB.query([{ kinds: [10001], authors: [pubkey], limit: 1 }]);
const [pinEvent] = await eventsDB.query([{ kinds: [10001], authors: [pubkey], limit: 1 }], { signal });
if (pinEvent) {
const pinnedEventIds = getTagSet(pinEvent.tags, 'e');
return renderStatuses(c, [...pinnedEventIds].reverse());
@@ -156,7 +157,7 @@ const accountStatusesController: AppController = async (c) => {
filter['#t'] = [tagged];
}
let events = await eventsDB.query([filter]);
let events = await eventsDB.query([filter], { signal });
if (exclude_replies) {
events = events.filter((event) => !findReplyTag(event.tags));
@@ -292,10 +293,11 @@ const unblockController: AppController = async (c) => {
const favouritesController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const params = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events7 = await eventsDB.query(
[{ kinds: [7], authors: [pubkey], ...params }],
{ signal: AbortSignal.timeout(1000) },
{ signal },
);
const ids = events7
@@ -304,9 +306,7 @@ const favouritesController: AppController = async (c) => {
const events1 = await eventsDB.query(
[{ kinds: [1], ids, relations: ['author', 'event_stats', 'author_stats'] }],
{
signal: AbortSignal.timeout(1000),
},
{ signal },
);
const statuses = await Promise.all(events1.map((event) => renderStatus(event, c.get('pubkey'))));

View File

@@ -38,10 +38,11 @@ const adminAccountsController: AppController = async (c) => {
}
const { since, until, limit } = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events = await eventsDB.query([{ kinds: [30361], authors: [Conf.pubkey], since, until, limit }]);
const events = await eventsDB.query([{ kinds: [30361], authors: [Conf.pubkey], since, until, limit }], { signal });
const pubkeys = events.map((event) => event.tags.find(([name]) => name === 'd')?.[1]!);
const authors = await eventsDB.query([{ kinds: [0], authors: pubkeys }]);
const authors = await eventsDB.query([{ kinds: [0], authors: pubkeys }], { signal });
for (const event of events) {
const d = event.tags.find(([name]) => name === 'd')?.[1];

View File

@@ -6,10 +6,12 @@ import { renderAccounts } from '@/views.ts';
/** https://docs.joinmastodon.org/methods/blocks/#get */
const blocksController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const { signal } = c.req.raw;
const [event10000] = await eventsDB.query([
{ kinds: [10000], authors: [pubkey], limit: 1 },
]);
const [event10000] = await eventsDB.query(
[{ kinds: [10000], authors: [pubkey], limit: 1 }],
{ signal },
);
if (event10000) {
const pubkeys = getTagSet(event10000.tags, 'p');

View File

@@ -6,10 +6,12 @@ import { renderStatuses } from '@/views.ts';
/** https://docs.joinmastodon.org/methods/bookmarks/#get */
const bookmarksController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const { signal } = c.req.raw;
const [event10003] = await eventsDB.query([
{ kinds: [10003], authors: [pubkey], limit: 1 },
]);
const [event10003] = await eventsDB.query(
[{ kinds: [10003], authors: [pubkey], limit: 1 }],
{ signal },
);
if (event10003) {
const eventIds = getTagSet(event10003.tags, 'e');

View File

@@ -5,8 +5,9 @@ import { eventsDB } from '@/storages.ts';
const instanceController: AppController = async (c) => {
const { host, protocol } = Conf.url;
const { signal } = c.req.raw;
const [event] = await eventsDB.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }]);
const [event] = await eventsDB.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], { signal });
const meta = jsonServerMetaSchema.parse(event?.content);
/** Protocol to use for WebSocket URLs, depending on the protocol of the `LOCAL_DOMAIN`. */

View File

@@ -13,7 +13,9 @@ const mediaBodySchema = z.object({
});
const mediaController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const result = mediaBodySchema.safeParse(await parseBody(c.req.raw));
const { signal } = c.req.raw;
if (!result.success) {
return c.json({ error: 'Bad request.', schema: result.error }, 422);
@@ -21,7 +23,7 @@ const mediaController: AppController = async (c) => {
try {
const { file, description } = result.data;
const media = await uploadFile(file, { pubkey: c.get('pubkey')!, description });
const media = await uploadFile(file, { pubkey, description }, signal);
return c.json(renderAttachment(media));
} catch (e) {
console.error(e);

View File

@@ -6,10 +6,11 @@ import { renderNotification } from '@/views/mastodon/notifications.ts';
const notificationsController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const { since, until } = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events = await eventsDB.query(
[{ kinds: [1], '#p': [pubkey], since, until }],
{ signal: AbortSignal.timeout(3000) },
{ signal },
);
const statuses = await Promise.all(events.map((event) => renderNotification(event, pubkey)));

View File

@@ -8,12 +8,14 @@ import { createAdminEvent } from '@/utils/api.ts';
import { jsonSchema } from '@/schema.ts';
const frontendConfigController: AppController = async (c) => {
const { signal } = c.req.raw;
const [event] = await eventsDB.query([{
kinds: [30078],
authors: [Conf.pubkey],
'#d': ['pub.ditto.pleroma.config'],
limit: 1,
}]);
}], { signal });
const configs = jsonSchema.pipe(z.array(configSchema)).catch([]).parse(
event?.content ? await decryptAdmin(Conf.pubkey, event.content) : '',
@@ -35,13 +37,14 @@ const frontendConfigController: AppController = async (c) => {
const configController: AppController = async (c) => {
const { pubkey } = Conf;
const { signal } = c.req.raw;
const [event] = await eventsDB.query([{
kinds: [30078],
authors: [pubkey],
'#d': ['pub.ditto.pleroma.config'],
limit: 1,
}]);
}], { signal });
const configs = jsonSchema.pipe(z.array(configSchema)).catch([]).parse(
event?.content ? await decryptAdmin(pubkey, event.content) : '',
@@ -53,13 +56,14 @@ const configController: AppController = async (c) => {
/** Pleroma admin config controller. */
const updateConfigController: AppController = async (c) => {
const { pubkey } = Conf;
const { signal } = c.req.raw;
const [event] = await eventsDB.query([{
kinds: [30078],
authors: [pubkey],
'#d': ['pub.ditto.pleroma.config'],
limit: 1,
}]);
}], { signal });
const configs = jsonSchema.pipe(z.array(configSchema)).catch([]).parse(
event?.content ? await decryptAdmin(pubkey, event.content) : '',

View File

@@ -25,13 +25,12 @@ type SearchQuery = z.infer<typeof searchQuerySchema>;
const searchController: AppController = async (c) => {
const result = searchQuerySchema.safeParse(c.req.query());
const { signal } = c.req.raw;
if (!result.success) {
return c.json({ error: 'Bad request', schema: result.error }, 422);
}
const signal = AbortSignal.timeout(1000);
const [event, events] = await Promise.all([
lookupEvent(result.data, signal),
searchEvents(result.data, signal),
@@ -46,12 +45,12 @@ const searchController: AppController = async (c) => {
const [accounts, statuses] = await Promise.all([
Promise.all(
results
.filter((event): event is NostrEvent => event.kind === 0)
.filter((event) => event.kind === 0)
.map((event) => renderAccount(event)),
),
Promise.all(
results
.filter((event): event is NostrEvent => event.kind === 1)
.filter((event) => event.kind === 1)
.map((event) => renderStatus(event, c.get('pubkey'))),
),
]);

View File

@@ -241,10 +241,12 @@ const pinController: AppController = async (c) => {
const unpinController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const eventId = c.req.param('id');
const { signal } = c.req.raw;
const event = await getEvent(eventId, {
kind: 1,
relations: ['author', 'event_stats', 'author_stats'],
signal,
});
if (event) {
@@ -273,12 +275,13 @@ const zapController: AppController = async (c) => {
const id = c.req.param('id');
const body = await parseBody(c.req.raw);
const params = zapSchema.safeParse(body);
const { signal } = c.req.raw;
if (!params.success) {
return c.json({ error: 'Bad request', schema: params.error }, 400);
}
const target = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] });
const target = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'], signal });
const author = target?.author;
const meta = jsonMetaContentSchema.parse(author?.content);
const lnurl = getLnurl(meta);

View File

@@ -31,7 +31,9 @@ const hashtagTimelineController: AppController = (c) => {
};
/** Render statuses for timelines. */
async function renderStatuses(c: AppContext, filters: DittoFilter[], signal = AbortSignal.timeout(1000)) {
async function renderStatuses(c: AppContext, filters: DittoFilter[]) {
const { signal } = c.req.raw;
const events = await eventsDB.query(
filters.map((filter) => ({ ...filter, relations: ['author', 'event_stats', 'author_stats'] })),
{ signal },