appendEntry method

  1. @override
Future<void> appendEntry(
  1. SessionRecord record
)
override

Appends record to the file and the in-memory index.

Implementation

@override
Future<void> appendEntry(SessionRecord record) async {
  // Serialize with every other in-process writer of this file (a
  // full-open JsonlSessionStorage on the same path — issue #135
  // round-4 review): concurrent bursts must never interleave bytes
  // mid-record. Same contract as [JsonlSessionStorage].
  final line = jsonEncode(record.toJson());
  await withSessionFileLock(_filePath, () async {
    // Issue #427: the app-chat submit path appends here; a transient
    // ENOENT rides the capped retry instead of killing the submit.
    _fsOrThrow(
      await retryTransientSessionFileIo(
        () => _fs.appendFile(_filePath, '$line\n'),
        op: 'append',
        path: _filePath,
        config: _ioRetry,
      ),
      'Failed to append session entry ${record.id}',
    );
    final info = await _reader.stat();
    final start = info == null
        ? _knownFileBytes
        : info.size - line.length - 1;
    _fileSize = start + line.length + 1;
    _fileMtimeMs = info?.mtimeMs ?? _fileMtimeMs;
    _offsetById[record.id] = start;
    final leaf = leafIdAfterSessionRecord(record);
    if (_knownFileBytes == start) {
      // Window bottom is the file tail: the record extends it.
      final chained =
          record.parentId == _branchBottomId ||
          record is LeafRecord && record.parentId == _branchBottomId;
      _indexEntry(record, start: start, end: _fileSize);
      _knownFileBytes = _fileSize;
      if (chained) _branchBottomId = leaf;
    } else if (_belowCount != null) {
      // Deep-paged: the record lands below the window and pages in later.
      _belowCount = _belowCount! + 1;
      _appendedBelow[record.id] = record;
    }
    _currentLeafId = leaf;
  });
  _evictToBound(newestSide: false);
}