commandHandler method

  1. @override
Future<void> commandHandler(
  1. Command command
)
inherited

Process a command through the full pipeline This is the main entry point for command processing

Uses explicit locking to prevent race conditions when multiple commands arrive in rapid succession. This ensures that even if there are subtle timing issues in the async flow, commands are always processed sequentially.

Implementation

@override
Future<void> commandHandler(Command command) async {
  // Wrap entire command processing in a lock to guarantee sequential execution
  // This fixes the concurrency bug reported in EVENTADOR_CONCURRENCY_BUG.md
  return await _commandLock.synchronized(() async {
    try {
      // Ensure aggregate is initialized
      if (!isInitialized) {
        _currentState = createInitialState();
      }

      // Check optimistic concurrency control
      await _checkConcurrency(command);

      // Handle the command and generate events
      final events = await handleCommand(currentState, command);

      // Persist all generated events (this also updates state via eventHandler)
      if (events.isNotEmpty) {
        await persistEvents(events);
      }

      // Call command processing hook
      await onCommandProcessed(command, events);
    } catch (e) {
      await onCommandFailure(command, e);
      rethrow;
    }
  });
}