mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Merge remote-tracking branch 'origin/main' into use-postgres-js
This commit is contained in:
commit
e208d7ef56
11 changed files with 43 additions and 13 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
image: denoland/deno:1.45.0
|
image: denoland/deno:1.45.2
|
||||||
|
|
||||||
default:
|
default:
|
||||||
interruptible: true
|
interruptible: true
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
deno 1.45.0
|
deno 1.45.2
|
||||||
16
CHANGELOG.md
16
CHANGELOG.md
|
|
@ -7,9 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.1.0] - 2024-07-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Prometheus support (`/metrics` endpoint).
|
||||||
|
- Sort zaps by amount; add pagination.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Added IP rate-limiting of HTTP requests and WebSocket messages.
|
||||||
|
- Added database query timeouts.
|
||||||
|
- Fixed nos2x compatibility.
|
||||||
|
|
||||||
## [1.0.0] - 2024-06-14
|
## [1.0.0] - 2024-06-14
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|
||||||
[unreleased]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.0.0...HEAD
|
[unreleased]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.1.0...HEAD
|
||||||
|
[1.1.0]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.0.0...v1.1.0
|
||||||
[1.0.0]: https://gitlab.com/soapbox-pub/ditto/-/tags/v1.0.0
|
[1.0.0]: https://gitlab.com/soapbox-pub/ditto/-/tags/v1.0.0
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://deno.land/x/deno@v1.41.0/cli/schemas/config-file.v1.json",
|
"$schema": "https://deno.land/x/deno@v1.41.0/cli/schemas/config-file.v1.json",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"start": "deno run -A src/server.ts",
|
"start": "deno run -A src/server.ts",
|
||||||
"dev": "deno run -A --watch src/server.ts",
|
"dev": "deno run -A --watch src/server.ts",
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,21 @@ class Conf {
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
/** Database query timeout configurations. */
|
||||||
|
timeouts: {
|
||||||
|
/** Default query timeout when another setting isn't more specific. */
|
||||||
|
get default(): number {
|
||||||
|
return Number(Deno.env.get('DB_TIMEOUT_DEFAULT') || 5_000);
|
||||||
|
},
|
||||||
|
/** Timeout used for queries made through the Nostr relay. */
|
||||||
|
get relay(): number {
|
||||||
|
return Number(Deno.env.get('DB_TIMEOUT_RELAY') || 1_000);
|
||||||
|
},
|
||||||
|
/** Timeout used for timelines such as home, notifications, hashtag, etc. */
|
||||||
|
get timelines(): number {
|
||||||
|
return Number(Deno.env.get('DB_TIMEOUT_TIMELINES') || 15_000);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
/** Character limit to enforce for posts made through Mastodon API. */
|
/** Character limit to enforce for posts made through Mastodon API. */
|
||||||
static get postCharLimit(): number {
|
static get postCharLimit(): number {
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ const accountStatusesController: AppController = async (c) => {
|
||||||
filter['#t'] = [tagged];
|
filter['#t'] = [tagged];
|
||||||
}
|
}
|
||||||
|
|
||||||
const opts = { signal, limit, timeout: 10_000 };
|
const opts = { signal, limit, timeout: Conf.db.timeouts.timelines };
|
||||||
|
|
||||||
const events = await store.query([filter], opts)
|
const events = await store.query([filter], opts)
|
||||||
.then((events) => hydrateEvents({ events, store, signal }))
|
.then((events) => hydrateEvents({ events, store, signal }))
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ async function renderNotifications(
|
||||||
const store = c.get('store');
|
const store = c.get('store');
|
||||||
const pubkey = await c.get('signer')?.getPublicKey()!;
|
const pubkey = await c.get('signer')?.getPublicKey()!;
|
||||||
const { signal } = c.req.raw;
|
const { signal } = c.req.raw;
|
||||||
const opts = { signal, limit: params.limit, timeout: 15_000 };
|
const opts = { signal, limit: params.limit, timeout: Conf.db.timeouts.timelines };
|
||||||
|
|
||||||
const events = await store
|
const events = await store
|
||||||
.query(filters, opts)
|
.query(filters, opts)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const suggestedTimelineController: AppController = async (c) => {
|
||||||
async function renderStatuses(c: AppContext, filters: NostrFilter[]) {
|
async function renderStatuses(c: AppContext, filters: NostrFilter[]) {
|
||||||
const { signal } = c.req.raw;
|
const { signal } = c.req.raw;
|
||||||
const store = c.get('store');
|
const store = c.get('store');
|
||||||
const opts = { signal, timeout: 10_000 };
|
const opts = { signal, timeout: Conf.db.timeouts.timelines };
|
||||||
|
|
||||||
const events = await store
|
const events = await store
|
||||||
.query(filters, opts)
|
.query(filters, opts)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
} from '@nostrify/nostrify';
|
} from '@nostrify/nostrify';
|
||||||
|
|
||||||
import { AppController } from '@/app.ts';
|
import { AppController } from '@/app.ts';
|
||||||
|
import { Conf } from '@/config.ts';
|
||||||
import { relayInfoController } from '@/controllers/nostr/relay-info.ts';
|
import { relayInfoController } from '@/controllers/nostr/relay-info.ts';
|
||||||
import { relayConnectionsGauge, relayEventCounter, relayMessageCounter } from '@/metrics.ts';
|
import { relayConnectionsGauge, relayEventCounter, relayMessageCounter } from '@/metrics.ts';
|
||||||
import * as pipeline from '@/pipeline.ts';
|
import * as pipeline from '@/pipeline.ts';
|
||||||
|
|
@ -95,7 +96,7 @@ function connectStream(socket: WebSocket, ip: string | undefined) {
|
||||||
const pubsub = await Storages.pubsub();
|
const pubsub = await Storages.pubsub();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const event of await store.query(filters, { limit: FILTER_LIMIT, timeout: 1000 })) {
|
for (const event of await store.query(filters, { limit: FILTER_LIMIT, timeout: Conf.db.timeouts.relay })) {
|
||||||
send(['EVENT', subId, event]);
|
send(['EVENT', subId, event]);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -150,7 +151,7 @@ function connectStream(socket: WebSocket, ip: string | undefined) {
|
||||||
/** Handle COUNT. Return the number of events matching the filters. */
|
/** Handle COUNT. Return the number of events matching the filters. */
|
||||||
async function handleCount([_, subId, ...filters]: NostrClientCOUNT): Promise<void> {
|
async function handleCount([_, subId, ...filters]: NostrClientCOUNT): Promise<void> {
|
||||||
const store = await Storages.db();
|
const store = await Storages.db();
|
||||||
const { count } = await store.count(filters, { timeout: 100 });
|
const { count } = await store.count(filters, { timeout: Conf.db.timeouts.relay });
|
||||||
send(['COUNT', subId, { count, approximate: false }]);
|
send(['COUNT', subId, { count, approximate: false }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class EventsDB implements NStore {
|
||||||
await this.deleteEventsAdmin(event);
|
await this.deleteEventsAdmin(event);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.store.event(event, { ...opts, timeout: opts.timeout ?? 1000 });
|
await this.store.event(event, { ...opts, timeout: opts.timeout ?? Conf.db.timeouts.default });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message === 'Cannot add a deleted event') {
|
if (e.message === 'Cannot add a deleted event') {
|
||||||
throw new RelayError('blocked', 'event deleted by user');
|
throw new RelayError('blocked', 'event deleted by user');
|
||||||
|
|
@ -164,7 +164,7 @@ class EventsDB implements NStore {
|
||||||
|
|
||||||
this.console.debug('REQ', JSON.stringify(filters));
|
this.console.debug('REQ', JSON.stringify(filters));
|
||||||
|
|
||||||
return this.store.query(filters, { ...opts, timeout: opts.timeout ?? 1000 });
|
return this.store.query(filters, { ...opts, timeout: opts.timeout ?? Conf.db.timeouts.default });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Delete events based on filters from the database. */
|
/** Delete events based on filters from the database. */
|
||||||
|
|
@ -172,7 +172,7 @@ class EventsDB implements NStore {
|
||||||
if (!filters.length) return Promise.resolve();
|
if (!filters.length) return Promise.resolve();
|
||||||
this.console.debug('DELETE', JSON.stringify(filters));
|
this.console.debug('DELETE', JSON.stringify(filters));
|
||||||
|
|
||||||
return this.store.remove(filters, { ...opts, timeout: opts.timeout ?? 3000 });
|
return this.store.remove(filters, { ...opts, timeout: opts.timeout ?? Conf.db.timeouts.default });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get number of events that would be returned by filters. */
|
/** Get number of events that would be returned by filters. */
|
||||||
|
|
@ -185,7 +185,7 @@ class EventsDB implements NStore {
|
||||||
|
|
||||||
this.console.debug('COUNT', JSON.stringify(filters));
|
this.console.debug('COUNT', JSON.stringify(filters));
|
||||||
|
|
||||||
return this.store.count(filters, { ...opts, timeout: opts.timeout ?? 500 });
|
return this.store.count(filters, { ...opts, timeout: opts.timeout ?? Conf.db.timeouts.default });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return only the tags that should be indexed. */
|
/** Return only the tags that should be indexed. */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue