From ebfe721eb065be1d33a13e03e40426c4b3adfad0 Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Sat, 22 Aug 2026 14:14:59 -0400 Subject: pim: answer an invitation by writing to a file echo ACCEPTED >events/uuid//partstat now does it, on a backend that can. caldav/fs fetches the object, rewrites only our own ATTENDEE line and PUTs it back with If-Match; fastmail advertises calendar-auto-schedule, so that single PUT both updates the copy and sends the iMIP to the organiser. caps says read rsvp schedule and means all three. Two things that cost an hour between them. go-webdav strips the quotes off an ETag when it parses the header, but If-Match wants an entity-tag: a bare hex string gets 412, which reads exactly like losing a race to another client. And the tree kept serving the old answer right after a successful write, because RSVP resynced the backend without rebuilding anything; a file that lies immediately after you wrote it is worse than one that is slow. -R uid:PARTSTAT answers one invitation without serving, which is what a pim/rsvp wrapper wants to call. Co-Authored-By: Claude Opus 5 --- pim/lib/cal/tree.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'pim/lib/cal/tree.go') diff --git a/pim/lib/cal/tree.go b/pim/lib/cal/tree.go index f78f2eb..4c65877 100644 --- a/pim/lib/cal/tree.go +++ b/pim/lib/cal/tree.go @@ -269,6 +269,12 @@ func (s *Server) addPartstat(dir *fs.StaticDir, e *Event) { if err := rsvp.RSVP(uid, time.Time{}, want); err != nil { return 0, err } + // The tree still holds the old answer until it is rebuilt, + // and a file that lies right after you wrote it is worse + // than one that is slow. + if err := s.Reload(); err != nil { + Warnf("rsvp: reload: %v", err) + } return uint32(len(data)), nil }, }) -- cgit v1.2.3