Class CaldavMirrorAnswerService
Reads the owner's answers off the copies in a collection nothing else reads (EXO-89814).
The defect this exists for. Where the copies go to eXo's own
exo-meetings collection — DEDICATED_CALENDAR, which is
the default — nothing ever reads that collection back in.
CaldavSyncService excludes it from materialisation
(isDedicatedMirror) and excludes the MIRROR pair from the inbound
loop, both deliberately and both for the same real reason: the collection is
eXo's own projection, and importing it would show the user a second, personal
copy of every space meeting they already have. The consequence nobody chose
is that EXO-89807 — which reads an answer off one of eXo's own copies at the
moment the collection's sync report names it as changed — has no pass to sit
on there, and EXO-89810's daily full read cannot reach those copies either.
The only reader left is the mirror verification's ETag gate, and on a server
that records an answer without moving the ETag (BlueMind, measured)
that gate never opens. On such a server, with the default destination, an
answer given in the copy reaches eXo by no route at all.
What this does, and the line it does not cross. It reads
answers, never events. The collection is asked what changed, the named
objects are fetched, and the one field the mirror allows back — the owner's
own PARTSTAT — is handed to CaldavAnswerAdoptionService, the same
narrow mapping EXO-89681 defined and the other two readers use. Nothing here
creates a calendar, imports an object, or writes to the server. The
duplicate-calendar failure the exclusion prevents is untouched, because the
exclusion is untouched: this pass never asks for the collection to be
materialised and never calls the import.
Why a sync report and not a wider look. The report is the only
evidence available on a server whose ETag does not move, and it is the one
EXO-89807 already rests on. It is also what bounds the cost: a collection
where nothing has happened answers with an empty list, so a converged account
pays one REPORT per sweep and fetches nothing. What it does cost is one fetch
per copy eXo itself writes, once, on the sweep after the write — eXo's own
push is a change the report reports, and no signal tells it from a client's.
That is honest and it is bounded by how much eXo writes, never by how large
the collection is; maxObjectsPerPass is the ceiling for the one case
that is not — a backfill burst — and it is spent on objects that carry
NEEDS-ACTION and adopt to nothing.
The token is established without reading anything. A blank or refused token means the next report is an initial sync, which names every object in the collection. Those bodies are deliberately not fetched: the burst of reads that shape produces is exactly what EXO-89810 refused to build, at the one moment a deployment can least absorb it. So the first pass takes the token and reads nothing, and every pass after it reads only what changed since. An answer given before this ships is therefore not healed by it — the same forward-looking limit EXO-89807 has, and for the same reason.
Only where nothing else reads the collection. Where the copies land in
the account's own calendar (MAIN_CALENDAR), that calendar is
materialised and read through its own binding, and EXO-89807 already adopts
every answer on that path. Running here as well would double a REPORT and a
fetch per sweep to reach a conclusion already reached. The condition is
therefore stated as what it actually is — no active binding reads this
collection — rather than as the destination setting, so a mirror pointed
at a collection whose binding is paused or tombstoned is covered too.
NEEDS-ACTION is refused, and that is load-bearing here more than anywhere. Every copy eXo pushes carries NEEDS-ACTION until somebody answers, and this pass meets those copies on the sweep after each push. A pass that adopted NEEDS-ACTION would walk an account erasing the answers its owner had given in eXo. The refusal lives in the adoption service and is pinned through this pass against the real one, never a mock.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionintreadAnswers(long userIdentityId, String username, org.exoplatform.caldav.model.CaldavUserSetting settings, org.exoplatform.caldav.model.CalendarSync mirror) Reads the owner's answers off the copies of a mirror collection that no binding reads.
-
Constructor Details
-
CaldavMirrorAnswerService
public CaldavMirrorAnswerService()
-
-
Method Details
-
readAnswers
public int readAnswers(long userIdentityId, String username, org.exoplatform.caldav.model.CaldavUserSetting settings, org.exoplatform.caldav.model.CalendarSync mirror) Reads the owner's answers off the copies of a mirror collection that no binding reads.Never throws at its caller. This runs inside the mirror pass, whose other halves — the relocation and the verification — must not lose a round because a report could not be made.
- Parameters:
userIdentityId- identity of the account's ownerusername- their eXo login, which the credentials provider maps to their account on the serversettings- the connected accountmirror- the binding recording where the copies are written- Returns:
- how many answers were recorded in agenda
-