handleColdStartIfNeeded method

Future<bool> handleColdStartIfNeeded(
  1. String? userId,
  2. Future<DatumSyncResult<DatumEntityInterface>> syncFunction(
    1. DatumSyncOptions<DatumEntityInterface>
    ), {
  3. String? entityType,
  4. bool synchronous = false,
})

Checks if this is a cold start and performs appropriate sync if needed. Now runs sync in background to prevent blocking app initialization.

Implementation

Future<bool> handleColdStartIfNeeded(
  String? userId,
  Future<DatumSyncResult> Function(DatumSyncOptions) syncFunction, {
  String? entityType,
  bool synchronous = false,
}) async {
  final entityInfo = entityType != null ? ' for $entityType' : '';

  // Guard against null userId - skip cold start sync if user is not authenticated
  if (userId == null || userId.isEmpty) {
    _logger.debug('Skipping cold start sync: user not authenticated$entityInfo');
    return false;
  }

  _logger.debug('Checking for cold start sync for user: $userId$entityInfo');

  // Initialize user state if not exists
  _isColdStart.putIfAbsent(userId, () => true);

  final isColdStart = _isColdStart[userId] ?? true;

  if (!isColdStart || _config.strategy == ColdStartStrategy.disabled) {
    if (_config.strategy == ColdStartStrategy.disabled) {
      _logger.debug('Cold start sync disabled by configuration$entityInfo');
    } else if (!isColdStart) {
      _logger.debug('Not a cold start, skipping cold start sync$entityInfo');
    }
    return false;
  }

  // Check if a cold start sync is already in progress for this user
  if (_isColdStartInProgress[userId] == true) {
    _logger.debug('Cold start sync already in progress for user: $userId$entityInfo');
    return false;
  }

  final shouldSync = await _shouldPerformColdStartSync(userId);
  if (!shouldSync) {
    _logger.debug('Cold start sync not needed based on strategy evaluation$entityInfo');
    _isColdStart[userId] = false;
    return false;
  }

  // Mark that a cold start sync is now in progress
  _isColdStartInProgress[userId] = true;

  if (synchronous) {
    // For testing: execute synchronously
    _logger.info('🚀 Starting synchronous cold start sync for user: $userId using strategy: ${_config.strategy}$entityInfo');
    try {
      await _performColdStartSync(userId, syncFunction, entityType: entityType);
      _isColdStart[userId] = false;
      _lastColdStartTime[userId] = DateTime.now();
      _logger.info('✅ Synchronous cold start sync completed successfully for user: $userId$entityInfo');
    } catch (e, stack) {
      _logger.error('❌ Synchronous cold start sync failed for user: $userId$entityInfo', stack);
      // On cold start sync failure, don't mark as completed
      // Allow retry on next app launch
      rethrow;
    } finally {
      // Always clear the in-progress flag when done
      _isColdStartInProgress[userId] = false;
    }
  } else {
    // Start cold start sync in background to prevent blocking app initialization
    // Use Future.delayed with zero duration to make it work with fakeAsync in tests
    _logger.info('🚀 Starting background cold start sync for user: $userId using strategy: ${_config.strategy}$entityInfo');
    unawaited(Future.delayed(Duration.zero, () async {
      try {
        await _performColdStartSync(userId, syncFunction, entityType: entityType);
        _isColdStart[userId] = false;
        _lastColdStartTime[userId] = DateTime.now();
        _logger.info('✅ Background cold start sync completed successfully for user: $userId$entityInfo');
      } catch (e, stack) {
        _logger.error('❌ Background cold start sync failed for user: $userId$entityInfo', stack);
        // On cold start sync failure, don't mark as completed
        // Allow retry on next app launch
      } finally {
        // Always clear the in-progress flag when done
        _isColdStartInProgress[userId] = false;
      }
    }));
  }

  // Return immediately without waiting for sync to complete (for async mode)
  // or after sync completion (for sync mode)
  return true;
}