reconcilePendingNonDurableSessionStarts static method

Future<bool> reconcilePendingNonDurableSessionStarts(
  1. Future<bool?> lookupEventPresence(
    1. String eventName,
    2. int tsMillis
    ),
  2. Future<void> persistEvent(
    1. Event event
    ), {
  3. required bool allowReplayWithoutSignal,
})

Implementation

static Future<bool> reconcilePendingNonDurableSessionStarts(
  Future<bool?> Function(String eventName, int tsMillis) lookupEventPresence,
  Future<void> Function(Event event) persistEvent, {
  required bool allowReplayWithoutSignal,
}) async {
  bool allReconciled = true;
  final replayedTimestamps = <int>{};

  for (final pending in _getPendingSessionStarts()) {
    if (pending.durable || !replayedTimestamps.add(pending.ts)) {
      continue;
    }

    final existing = await lookupEventPresence('session_start', pending.ts);
    if (existing == true) {
      if (pending.isLegacyAmbiguous || !pending.locallyStored) {
        await _markSessionStartLocallyStored(pending.ts);
      }
      continue;
    }
    if (existing == null) {
      allReconciled = false;
      continue;
    }
    if (!allowReplayWithoutSignal &&
        pending.hasLocalStoreProvenance &&
        pending.locallyStored) {
      try {
        await markSessionStartDelivered(pending.ts);
      } catch (e, st) {
        dbLogger.warning(
          'SessionHelper: failed to repair pending session_start delivery marker without a storage recovery signal',
          e,
          st,
        );
        allReconciled = false;
      }
      continue;
    }

    if (!allowReplayWithoutSignal && pending.isLegacyAmbiguous) {
      await _markSessionStartLegacyAmbiguousUnresolved(pending.ts);
      dbLogger.warning(
        'SessionHelper: leaving legacy ambiguous pending session_start unresolved because the storage row is missing and no recovery replay signal is armed',
      );
      allReconciled = false;
      continue;
    }

    if (pending.isLegacyAmbiguous) {
      await _markSessionStartNotLocallyStored(pending.ts);
    }

    try {
      final sessionStartEvent = await Event.createWithContext(
        'session_start',
        pending.ts,
        sessionStartOverride: pending.ts,
        sessionNumberOverride: pending.number,
      );
      await persistEvent(sessionStartEvent);
      await _confirmPendingSessionStartStored(
        pending.ts,
        lookupEventPresence: lookupEventPresence,
      );
    } catch (e, st) {
      dbLogger.severe(
        'SessionHelper: reconcilePendingNonDurableSessionStarts failed',
        e,
        st,
      );
      allReconciled = false;
      continue;
    }

    if (await lookupEventPresence('session_start', pending.ts) != true) {
      allReconciled = false;
    }
  }

  return allReconciled;
}