Committer
June 1, 2026 ยท View on GitHub
Committer
Go implementation of Two-Phase Commit (2PC) and Three-Phase Commit (3PC) protocols for distributed systems.
Architecture
The system consists of two types of nodes: Coordinator and Cohorts. The Coordinator is responsible for initiating and managing the commit protocols (2PC or 3PC), while the Cohorts participate in the protocol by responding to the coordinator's requests. The communication between nodes is handled using gRPC, and the state of each node is managed using a state machine.
Monitoring & Visualization
Pass -viz-port=<port> to enable the web dashboard with live charts for throughput, commit/abort rates, latency, and node health:
./committer -nodeaddr=localhost:3000 -cohorts=localhost:3001 -viz-port=8080
Then open http://localhost:8080 in a browser.
Atomic Commit Protocols
Two-Phase Commit (2PC)
The Two-Phase Commit protocol ensures atomicity in distributed transactions through two distinct phases:
Phase 1: Voting Phase (Propose)
- Coordinator sends a
PROPOSErequest to all cohorts with transaction data - Each Cohort validates the transaction locally and responds:
ACK(Yes) - if ready to commitNACK(No) - if unable to commit
- Coordinator waits for all responses
Phase 2: Commit Phase
- If all cohorts voted
ACK:- Coordinator sends
COMMITto all cohorts - Each Cohort commits the transaction and responds with
ACK
- Coordinator sends
- If any cohort voted
NACK:- Coordinator sends
ABORTto all cohorts - Each Cohort aborts the transaction
- Coordinator sends
Three-Phase Commit (3PC)
The Three-Phase Commit protocol extends 2PC with an additional phase to reduce blocking scenarios:
Phase 1: Voting Phase (Propose)
- Coordinator sends
PROPOSErequest to all cohorts - Cohorts respond with
ACK/NACK(same as 2PC)
Phase 2: Preparation Phase (Precommit)
- If all cohorts voted
ACK:- Coordinator sends
PRECOMMITto all cohorts - Cohorts acknowledge they're prepared to commit
- Timeout mechanism: If cohort doesn't receive
COMMITwithin timeout, it auto-commits
- Coordinator sends
- If any cohort voted
NACK:- Coordinator sends
ABORTto all cohorts
- Coordinator sends
Phase 3: Commit Phase
- Coordinator sends
COMMITto all cohorts - Cohorts perform the actual commit operation
Configuration
| Flag | Description | Default |
|---|---|---|
nodeaddr | Address of the current node | localhost:3050 |
coordinator | Coordinator address (cohorts only) | "" |
committype | two-phase or three-phase | three-phase |
timeout | Timeout (ms) for unacknowledged messages (3PC only) | 1000 |
cohorts | Comma-separated cohort addresses (presence implies coordinator role) | "" |
viz-port | Port for web dashboard (0 = disabled) | 0 |
Usage
# Coordinator
./committer -nodeaddr=localhost:3000 -cohorts=localhost:3001 -committype=three-phase
# Cohort
./committer -nodeaddr=localhost:3001 -coordinator=localhost:3000 -committype=three-phase
Hooks
Custom validation and business logic for the Propose and Commit stages. Hooks run in registration order; returning false rejects the operation.
committer := commitalgo.NewCommitter(database, "three-phase", wal, timeout,
hooks.NewMetricsHook(),
hooks.NewValidationHook(100, 1024),
hooks.NewAuditHook("audit.log"),
)
// or register later
committer.RegisterHook(myCustomHook)
Testing
make tests
To test with the example client:
make prepare
make run-example-coordinator # terminal 1
make run-example-cohort # terminal 2
make run-example-client # terminal 3
Contributions
PRs and issues are welcome.