mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-22 10:12:25 +00:00
docs: channel multi-owner S3-min plan: closing check - open question on the relay roster-blob check, QCONT trigger for the undelivered-roster check
This commit is contained in:
1 parent
1839223688
commit
2a4d33befe
1 file changed
+3
-3
@@ -242,7 +242,7 @@ Single-owner channels keep `broadcastRoster`. Owners outside the roster: `proces
|
||||
|
||||
**Abandonment.** A version `r` by a departed author is abandoned (claim `r + 1` from own state; nobody received `r`) when `link_roster_seen_at` is older than `rosterAbandonTTL` (1 day) and a request sent to every current relay at least `rosterRequestTimeout` (5 minutes) earlier brought no blob matching the commitment. A re-sign that lacks the blob sends that request; before the TTL it forks one re-check at `link_roster_seen_at + rosterAbandonTTL`, which requests again and forks the last re-check `rosterRequestTimeout` later. Chat start runs the re-sign again. An owner that also missed earlier versions of that author (f < r − 1) drops them too, though some devices received them: only a departed author's committed version is accepted, and the alternative is a channel whose roles can never change again.
|
||||
|
||||
**Undelivered roster.** At main-app chat start, when a relay connection becomes ready (`CON`, `Subscriber.hs:889`) and when it resumes after a full queue (`SENT` with `continueSending`, `:1197-1199`): an owner that is the link's roster author at its stored version, when no relay has `SENT` the last chunk of its `x.grp.roster` at `stored_roster_version` (or there is no such message; its blob and events were dropped), makes an `RCResign` claim at `r + 1`: the blob and the event at `r + 1` make members that missed `r` see a gap and fetch. It never sends an event at a version it is re-sending.
|
||||
**Undelivered roster.** At main-app chat start, when a relay connection becomes ready (`CON`, `Subscriber.hs:889`) and when it resumes after a full queue (`continueSending` true on `SENT` or `QCONT`, `:1197-1199`, `:1291-1295`): an owner that is the link's roster author at its stored version, when no relay has `SENT` the last chunk of its `x.grp.roster` at `stored_roster_version` (or there is no such message; its blob and events were dropped), makes an `RCResign` claim at `r + 1`: the blob and the event at `r + 1` make members that missed `r` see a gap and fetch. It never sends an event at a version it is re-sending.
|
||||
|
||||
### 4.11 Subscriber count
|
||||
|
||||
@@ -266,7 +266,7 @@ In multi-owner mode the owner branch of `updatePublicGroupData` (`Internal.hs:16
|
||||
| `x.grp.info` with `linkVersion` | above `link_data_version` | `linkVersion` ≤ `link_data_version` and the sender is a current owner |
|
||||
| `x.grp.mem.role`, `x.grp.mem.del` with a roster version | above `link_roster_version` | the version ≤ `link_roster_version` and the sender is a current owner |
|
||||
|
||||
Roster blobs are tested at completion (§4.10). Members and owners get these events only through relays and keep today's checks. A post the new owner sends to a relay still checking its commit is refused there, as a post racing the commit can be today.
|
||||
Roster blobs are tested at completion (§4.10). Members and owners get these events only through relays and keep today's checks. A new owner's post can be refused at a relay still checking its commit, as a post racing the commit can be today.
|
||||
- **Deferred check.** The relay verifies and parses the message but does not save a waiting event; the other events of a batch are processed as today, and the waiting ones share one read and the message's ACK. It records `(connId, agentMsgId)` in `ChatController.relayLinkChecks :: TMap (ConnId, AgentMsgId) ()`, returns a new "defer" result from `withAckMessage` (`Subscriber.hs:1797-1832`; no ACK), and forks the read, retrying temporary errors with backoff. The deferred ACK holds that connection's later messages, keeping the sender's order. A `MSG` re-notified after an SMP reconnection (same ID, `Agent.hs:3767-3787`) with an entry is ignored. When the read returns, under the group lock: save the event, apply or reject it, create the delivery task, ack (`ackMessageAsync`), delete the entry. After a restart nothing was saved, so the redelivered message is checked again. A message notified 8 times over a day is dropped by the agent (`Agent/Env/SQLite.hs:271-272`), as any message.
|
||||
- **Activation.** The `LINK` handler body (`Subscriber.hs:1437-1477`) becomes `activateGroupRelays :: User -> GroupInfoKeys -> [ShortLinkContact] -> CM ()`, called by the handler and in the callback of a `CLCRelays` write; it reads `group_relays` and the group link row only when present. `CEvtGroupLinkDataUpdated` and `CRGroupRelaysAdded` carry `Maybe GroupLink` (`Controller.hs:862`, `:1035`).
|
||||
- **Publication** after a relay's acknowledgement (`Subscriber.hs:3661-3665`) and a pre-roster relay's connection (`:946-947`): a forked `CLCRelays [link] []`. Main-app chat start publishes acknowledged relays missing from the link.
|
||||
@@ -331,7 +331,6 @@ One migration `M20261015_channel_multi_owner` with `down_m20261015_channel_multi
|
||||
| A relay added while another is removed | the swap | `CLCRelays` | both kept |
|
||||
| A member removed or leaving while promoted | removal wins; self-revocation | §4.8 | the member ends departed |
|
||||
| A removed owner acting before relays learn | the relay's deferred link check | §4.13 | owner changes, deletion and counters above the link's refused; posts, and profile and role events at a version the relay holds, possible until it learns |
|
||||
| A relay restart or reconnection during a check | nothing saved before the check; pending checks by message | §4.13 | the redelivered message is checked again or ignored while its check runs |
|
||||
| A read older than a promotion applied after its commit | the commit's `linkVersion`, checked by relays | §4.6, §4.13 | the read is ignored; M stays an owner |
|
||||
| A party that was offline | link data on every read | §4.4 | converges at its next read |
|
||||
| A single-owner write queued before the first promotion | `LSET` refused on a multi-key queue | §4.1 | the late write gets `AUTH`; nothing is overwritten |
|
||||
@@ -445,6 +444,7 @@ Questions 1–3, decided by the user: role changes in multi-owner channels need
|
||||
|
||||
4. `LSWP` sends only the user data. Recommended: as planned; otherwise owners are capped at about 6.
|
||||
5. `LSET` is refused on queues with several recipient keys (a server behaviour change at v24). Recommended: as planned; it is what stops stale or downgraded single-owner writes from erasing other owners.
|
||||
6. A relay's test of a current author's blob (§4.10) forks a read after the final chunk is acked, so a failed read loses the blob while the version's events still apply, and the events can overtake the blob. Recommended (S12, ~30 lines): when completion needs a read, defer the final chunk's ACK with §4.13's mechanism and apply or discard the blob when the read returns; a redelivered final chunk of a pending roster transfer re-runs completion (`RcvChunkDuplicate`, `Subscriber.hs:1407`, does nothing today); T17 adds a relay whose first read fails during a role change, still storing the blob and serving it to a joiner. Otherwise: no relay test of current authors' blobs, so a removed owner's inflated blob version can freeze a relay's roles.
|
||||
|
||||
## 10. Out of scope
|
||||
|
||||
|
||||
Reference in new issue
Block a user