mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
docs: clarify deletion retention tradeoffs
This commit is contained in:
@@ -286,6 +286,8 @@
|
||||
# start at relay-observed first_seen_at; used clocks start at last_used_at.
|
||||
# "Additional" periods begin after their corresponding served period ends.
|
||||
# Used requests remain served indefinitely when deletion-request-disrespector is true.
|
||||
# Seconds permit short tests; production periods should be at least one day and
|
||||
# comfortably exceed worst-case deletion/archive processing time.
|
||||
|
||||
# How long an unused request remains served from first_seen_at
|
||||
# CLI: --deletion-request-retention-unused-served-secs <seconds>
|
||||
|
||||
@@ -83,6 +83,18 @@ rejected under valid ownership, coordinate-cutoff, relay-targeting, and other
|
||||
NIP-09/NIP-62 rules. Merely matching a tag, inspecting the request, or discovering
|
||||
that a different author owns the target does not count as use.
|
||||
|
||||
The unserved gate is the deliberate observation period that establishes whether
|
||||
an apparently unused request still has practical value. While the request was
|
||||
served, clients that saw it could avoid sending the deleted target to this relay,
|
||||
even if copies of that target continued circulating elsewhere. Removing the
|
||||
request from relay queries gives those late copies an opportunity to reach the
|
||||
relay again. The retained Tombstone gate still rejects a covered target; that
|
||||
rejection is evidence of current utility, so the winning request becomes used,
|
||||
is promoted back to Main, and begins the longer used lifecycle. If no covered
|
||||
target arrives during the unserved period, the request has supplied no evidence
|
||||
that its gate is still needed and can expire. Replaying the deletion or vanish
|
||||
request itself is not such evidence and does not update `last_used_at`.
|
||||
|
||||
#### Used
|
||||
|
||||
When a request is used:
|
||||
@@ -115,6 +127,14 @@ physical removal from Main and Tombstones is asynchronous cleanup and may occur
|
||||
on the next scheduled pass. This bounded cleanup delay is intentional and does
|
||||
not extend admission-gate eligibility past the deadline.
|
||||
|
||||
Durations use seconds for configuration consistency and to permit short automated
|
||||
tests. Production values are expected to be at least one day and comfortably
|
||||
longer than the worst-case processing time for a deletion or vanish request,
|
||||
including repository archival and cascade work. Sub-day values are a testing
|
||||
facility, not a supported production operating point; cleanup is therefore not
|
||||
coordinated with an initial request handler across an artificially short total
|
||||
lifetime.
|
||||
|
||||
### Multiple matching requests
|
||||
|
||||
If several pending requests would independently reject the same arriving event,
|
||||
@@ -217,6 +237,16 @@ correctness, but their retention clocks do not change. This rule is independent
|
||||
of database iteration order and prevents one event arrival from extending an
|
||||
arbitrary number of duplicate requests.
|
||||
|
||||
This deterministic single-winner rule applies when one later target admission is
|
||||
matched against already-pending requests. Initial processing of distinct deletion
|
||||
requests is intentionally less strict: two requests processed concurrently may
|
||||
both observe the same stored target before either removal completes and may both
|
||||
receive use credit. The database deletion API does not report an authoritative
|
||||
per-event removed count, so eliminating that narrow race would require broader
|
||||
target-level serialization. The occasional extra used request is accepted: it is
|
||||
bounded by actual concurrency, does not change deletion correctness, and still
|
||||
expires through the normal used lifecycle.
|
||||
|
||||
### Simplification of target-set deduplication
|
||||
|
||||
The lifecycle replaces semantic target-set deduplication and supersession as the
|
||||
|
||||
@@ -1190,6 +1190,8 @@ These options govern the bounded lifecycle of accepted NIP-09 deletion requests
|
||||
|
||||
The relay derives unused deadlines from relay-observed `first_seen_at`, never from the client-controlled event `created_at`. It derives used deadlines from `last_used_at`. Each `...ADDITIONAL...` option begins only after its corresponding served period ends; it is not a total retention duration.
|
||||
|
||||
Seconds are used for configuration consistency and short automated tests. In production, configure every period to at least one day and keep each total lifecycle comfortably longer than the worst-case deletion processing time, including repository archival and cascade work. Sub-day values are intended only for tests.
|
||||
|
||||
#### `NGIT_DELETION_REQUEST_RETENTION_UNUSED_SERVED_SECS`
|
||||
|
||||
- **Description:** How long an unused deletion or vanish request remains served from relay-observed `first_seen_at`
|
||||
|
||||
+9
-4
@@ -198,7 +198,8 @@ let
|
||||
default = 2592000;
|
||||
description = ''
|
||||
Time in seconds an unused deletion or vanish request remains served
|
||||
from relay-observed first_seen_at (default: 30 days).
|
||||
from relay-observed first_seen_at (default: 30 days). Production
|
||||
periods should be at least one day; sub-day values are for tests.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -208,7 +209,8 @@ let
|
||||
description = ''
|
||||
Additional time in seconds after unused serving ends that a deletion
|
||||
or vanish request remains unserved but eligible to gate admission
|
||||
(default: 180 days).
|
||||
(default: 180 days). Production periods should be at least one day;
|
||||
sub-day values are for tests.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -219,7 +221,8 @@ let
|
||||
Normal-mode time in seconds a used deletion or vanish request
|
||||
remains served after last_used_at (default: 270 days, 9 fixed
|
||||
30-day months). Used requests remain served indefinitely when
|
||||
deletionRequestDisrespector is enabled.
|
||||
deletionRequestDisrespector is enabled. Production periods should
|
||||
be at least one day; sub-day values are for tests.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -230,7 +233,9 @@ let
|
||||
Additional normal-mode time in seconds after used serving ends that
|
||||
a deletion or vanish request remains unserved but continues gating
|
||||
admission (default: 90 days, 3 fixed 30-day months). This duration
|
||||
does not expire used requests when deletionRequestDisrespector is enabled.
|
||||
does not expire used requests when deletionRequestDisrespector is
|
||||
enabled. Production periods should be at least one day; sub-day
|
||||
values are for tests.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -453,6 +453,9 @@ pub struct Config {
|
||||
)]
|
||||
pub holding_cleanup_interval_secs: u64,
|
||||
|
||||
// Retention is expressed in seconds for configuration consistency and short
|
||||
// tests. Production deployments are expected to use periods of at least one
|
||||
// day, comfortably exceeding worst-case deletion/archive processing time.
|
||||
/// How long an unused deletion or vanish request remains served after relay-observed first_seen_at.
|
||||
#[arg(
|
||||
long = "deletion-request-retention-unused-served-secs",
|
||||
|
||||
@@ -447,6 +447,14 @@ impl DeletionPolicy {
|
||||
return outcome;
|
||||
}
|
||||
|
||||
// NostrDatabase::delete does not return a per-event removed count. Two
|
||||
// concurrently processed requests can therefore both have observed one
|
||||
// target and both receive use credit after successful delete calls. This
|
||||
// narrow over-credit race is accepted: avoiding it would require broad
|
||||
// target-level serialization, it cannot affect deletion correctness,
|
||||
// and any extra credited request still follows bounded used retention.
|
||||
// Deterministic single-winner attribution remains strict for the more
|
||||
// important case of one later admission matching many pending requests.
|
||||
let deleted_count = deletable.len();
|
||||
let delete_filter = Filter::new().ids(deletable);
|
||||
if let Err(e) = self.ctx.database.delete(delete_filter).await {
|
||||
|
||||
Reference in New Issue
Block a user