Files
fpc-msgbase/docs
Ken Johnson 84e2efdd7e Add TMessageBase.Sync for crash-safe per-message acknowledgement
NR caught a real durability gap during migration prep: the
sequence

  base.WriteMessage(msg);
  source.MarkSent(srcMsg);

looks atomic, but the OS write buffer hasn't necessarily reached
the platter when MarkSent runs.  Crash in that window = silent
message drop.

Add `Sync` virtual on TMessageBase (default no-op for read-only
and in-memory backends).  Six writable backends override and
flush every open stream they own via SysUtils.FileFlush
(fpfsync on Unix, FlushFileBuffers on Windows):

  JAM       .JHR / .JDT / .JDX / .JLR
  Squish    .SQD / .SQI / .SQL
  Hudson    msginfo / msgidx / msghdr / msgtxt / msgtoidx / LASTREAD.BBS
  PCBoard   MSGS file + index
  EzyCom    header + text
  GoldBase  msginfo / msgidx / msghdr / msgtxt / msgtoidx / LASTREAD.DAT

MSG inherits no-op (per-write open/close — buffer flushes on
close, but dir entry isn't fsynced; future enhancement).
Wildcat inherits no-op (legacy `file` IO, not TFileStream).

Helper for backend authors: TMessageBase.FlushStream(S: TStream)
class method that handles the TFileStream cast + nil-safety.

`Sync` raises after Close (data is finalized; nothing to flush).

Test: TestSyncWriteable in test_consumer_round1 -- writes a
message via JAM and Squish, calls Sync (no raise), Close, calls
Sync again (raise expected).

docs/API.md: new "Sync (durability)" section explaining the
commit-after-fsync pattern with the canonical example.

Symmetric to fpc-ftn-transport TPktWriter.Sync (commit ee8c6ad)
that NR's review prompted on the transport side.

Suite: 48/48 (added TestSyncWriteable to test_consumer_round1).
2026-04-18 19:22:07 -07:00
..