Packages

macula

0.20.23
7.0.0 6.0.0 5.2.2 5.2.1 5.2.0 5.1.0 5.0.0 4.8.0 4.7.1 4.7.0 4.6.0 4.5.0 4.4.10 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.1 4.3.0 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.1 4.1.0 4.0.0 3.16.0 3.15.3 3.15.2 3.15.1 3.14.0 3.13.0 3.12.1 3.12.0 3.11.1 3.11.0 3.10.3 3.10.2 3.10.1 3.9.0 3.8.0 3.7.0 3.5.0 3.4.0 3.3.0 3.2.0 3.1.0 3.0.0 2.1.1 2.1.0 2.0.0 1.5.2 1.5.1 1.4.30 1.4.29 1.4.28 1.4.27 1.4.26 1.4.25 1.4.24 1.4.23 1.4.22 1.4.21 1.4.20 1.4.19 1.4.18 1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.1 1.3.0 1.2.0 1.1.0 1.0.10 1.0.9 1.0.8 1.0.7 1.0.6 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 0.48.6 0.48.5 0.48.4 0.48.3 0.48.2 0.48.1 0.48.0 0.47.1 0.47.0 0.46.3 0.46.1 0.46.0 0.45.3 0.45.2 0.45.1 0.45.0 0.44.2 0.44.1 0.44.0 0.43.3 0.43.2 0.43.1 0.43.0 0.42.9 0.42.8 0.42.7 0.42.6 0.42.5 0.42.4 0.42.3 0.42.2 0.42.1 0.42.0 0.41.1 0.41.0 0.40.1 0.40.0 0.39.9 0.39.8 0.39.7 0.39.6 0.39.5 0.39.4 0.39.3 0.39.2 0.39.1 0.39.0 0.38.8 0.38.7 0.38.6 0.38.5 0.38.4 0.38.3 0.38.2 0.38.1 0.38.0 0.37.7 0.37.6 0.37.5 0.37.4 0.37.3 0.37.2 0.37.1 0.37.0 0.36.6 0.36.5 0.36.4 0.36.3 0.36.2 0.36.1 0.36.0 0.35.4 0.35.3 0.35.2 0.35.1 0.35.0 0.34.1 0.34.0 0.33.1 0.33.0 0.32.5 0.32.4 0.32.3 0.32.2 0.32.1 0.32.0 0.31.9 0.31.8 0.31.7 0.31.6 0.31.5 0.31.4 0.31.3 0.31.2 0.31.1 0.31.0 0.30.10 0.30.9 0.30.8 0.30.7 0.30.6 0.30.5 0.30.4 0.30.3 0.30.2 0.30.1 0.30.0 0.29.0 0.28.3 0.28.2 0.28.1 0.28.0 0.27.1 0.27.0 0.26.1 0.26.0 0.25.6 0.25.5 0.25.4 0.25.3 0.25.2 0.25.1 0.25.0 0.24.6 0.24.5 0.24.4 0.24.3 0.24.2 0.24.1 0.24.0 0.23.3 0.23.2 0.23.1 0.23.0 0.22.12 0.22.11 0.22.10 0.22.9 0.22.8 0.22.7 0.22.6 0.22.5 0.22.4 0.22.3 0.22.2 0.22.1 0.22.0 0.21.7 0.21.6 0.21.5 0.21.4 0.21.2 0.21.1 0.21.0 0.20.25 0.20.24 0.20.23 0.20.22 0.20.21 0.20.20 0.20.19 0.20.18 0.20.17 0.20.16 0.20.15 0.20.14 0.20.13 0.20.12 0.20.11 0.20.10 0.20.9 0.20.8 0.20.7 0.20.6 0.20.5 0.20.3 0.20.2 0.20.1 0.20.0 0.19.2 0.19.1 0.19.0 0.18.1 0.18.0 0.17.4 0.17.3 0.17.2 0.17.1 0.17.0 0.16.6 0.16.5 0.16.4 0.16.3 0.16.2 0.16.1 0.16.0 0.15.1 0.15.0 0.14.3 0.14.2 0.14.1 0.14.0 0.12.6 0.12.5 0.12.3 0.11.3 0.10.2 0.10.1 0.10.0 0.9.2 0.9.1 0.9.0 0.8.25 0.8.24 0.8.23 0.8.22 0.8.21 0.8.20 0.8.19 0.8.18 0.8.17 0.8.16 0.8.15 0.8.14 0.8.13 0.8.12 0.8.11 0.8.10 0.8.9 0.8.8 0.8.7 0.8.6 0.8.5 0.8.4 0.8.3 0.8.2 0.8.1 0.8.0 0.7.30 0.7.29 0.7.28 0.7.27 0.7.26 0.7.25 0.7.24 0.7.23 0.7.22 0.7.21 0.7.20 0.7.19 0.7.18 0.7.17 0.7.16 0.7.15 0.7.14 0.7.13 0.7.12 0.7.11 0.7.10 0.7.9 0.7.8 0.7.7 0.7.6 0.7.5 0.7.4 0.7.3 0.7.2 0.7.1 0.7.0 0.6.7 0.6.6 0.6.5 0.6.4 0.6.3 0.6.2 0.6.1 0.6.0 0.5.0 0.4.4 0.4.3 0.4.2 0.4.1 0.4.0 0.3.4 0.3.3 0.3.2 0.3.1

Macula HTTP/3 Mesh SDK — connect, subscribe, publish, call, advertise

Current section

Files

Jump to
macula src macula_platform_system README.md
Raw

src/macula_platform_system/README.md

# Platform System
The Platform System provides masterless state management using Conflict-free Replicated Data Types (CRDTs). As of v0.14.0, Macula uses CRDTs instead of Raft consensus for distributed state.
## Module Table
| Module | Purpose | LOC |
|--------|---------|-----|
| `macula_platform_system` | Supervisor for platform subsystem (currently empty) | 2.7k |
| `macula_crdt` | CRDT implementations (LWW-Register, OR-Set, G-Counter, PN-Counter) | 12k |
## Architecture Decision: No Raft
**v0.14.0**: Ra/Raft removed in favor of CRDTs.
> Raft adds operational complexity for consistency guarantees Macula doesn't need.
> - No quorum management
> - No leader election
> - State converges eventually (CRDTs + Gossip)
Macula operates in **eventually-consistent mode** (AP in CAP theorem):
- Nodes operate during network partitions
- No need for strong consensus
- CRDTs provide automatic conflict resolution
- Simpler operational model
## CRDT Types
### LWW-Register (Last-Writer-Wins Register)
Single value with timestamp-based conflict resolution:
```erlang
%% Create new register
Reg1 = macula_crdt:new_lww(<<"initial_value">>).
%% Update value (automatically timestamps)
Reg2 = macula_crdt:lww_set(Reg1, <<"new_value">>).
%% Get current value
{ok, Value} = macula_crdt:lww_get(Reg2).
%% Merge two registers (last writer wins)
Merged = macula_crdt:lww_merge(RegA, RegB).
```
### OR-Set (Observed-Remove Set)
Add/remove set with tombstone-based conflict resolution:
```erlang
%% Create new set
Set1 = macula_crdt:new_or_set().
%% Add elements
Set2 = macula_crdt:or_add(Set1, <<"element1">>).
Set3 = macula_crdt:or_add(Set2, <<"element2">>).
%% Remove element
Set4 = macula_crdt:or_remove(Set3, <<"element1">>).
%% Check membership
true = macula_crdt:or_contains(Set4, <<"element2">>).
false = macula_crdt:or_contains(Set4, <<"element1">>).
%% Get all elements
[<<"element2">>] = macula_crdt:or_elements(Set4).
%% Merge two sets
Merged = macula_crdt:or_merge(SetA, SetB).
```
### G-Counter (Grow-only Counter)
Counter that can only increment:
```erlang
%% Create new counter
Counter1 = macula_crdt:new_gcounter().
%% Increment (default by 1)
Counter2 = macula_crdt:gcounter_increment(Counter1).
%% Increment by specific amount
Counter3 = macula_crdt:gcounter_increment(Counter2, 5).
%% Get current value
6 = macula_crdt:gcounter_value(Counter3).
%% Merge counters
Merged = macula_crdt:gcounter_merge(CounterA, CounterB).
```
### PN-Counter (Positive-Negative Counter)
Counter that can increment and decrement:
```erlang
%% Create new counter
Counter1 = macula_crdt:new_pncounter().
%% Increment
Counter2 = macula_crdt:pncounter_increment(Counter1, 10).
%% Decrement
Counter3 = macula_crdt:pncounter_decrement(Counter2, 3).
%% Get current value
7 = macula_crdt:pncounter_value(Counter3).
%% Merge counters
Merged = macula_crdt:pncounter_merge(CounterA, CounterB).
```
## CRDT Properties
All CRDTs in Macula satisfy:
1. **Commutativity**: merge(A, B) = merge(B, A)
2. **Associativity**: merge(merge(A, B), C) = merge(A, merge(B, C))
3. **Idempotency**: merge(A, A) = A
These properties ensure:
- Order of merge operations doesn't matter
- Repeated merges are safe
- State converges to consistent value
## Test Coverage
| CRDT Type | Tests | Coverage |
|-----------|-------|----------|
| LWW-Register | 14 | Full API coverage |
| OR-Set | 17 | Add/remove/merge/concurrent ops |
| G-Counter | 9 | Increment/merge/value |
| PN-Counter | 8 | Inc/dec/merge/value |
| **Total** | **48** | |
## Supervision Tree
```
macula_platform_system (supervisor)
└── (empty - CRDTs are stateless)
```
The Platform System supervisor is intentionally empty. CRDTs are pure data structures - they don't need background processes. State is stored in application-level processes and merged on demand.
## Future Work (v0.14.1+)
- **Gossip Protocol**: Automatic CRDT state synchronization between nodes
- **DHT Integration**: Store CRDTs in the DHT for global access
- **Delta-CRDTs**: Optimized sync using deltas instead of full state
## Migration from Ra/Raft
v0.14.0 removed the following modules:
- `macula_leader_election.erl` (deleted)
- `macula_leader_machine.erl` (deleted)
- `ra` dependency removed from rebar.config
If your code referenced leader election:
```erlang
%% Old (pre-v0.14.0)
{ok, Leader} = macula_leader_election:get_leader().
%% New (v0.14.0+) - No leader, use local state
%% State converges via CRDT merge during gossip
```
## Related Documentation
- [Roadmap - SuperMesh v3.0](../../architecture/ROADMAP.md)
- [CRDT Foundation Architecture](../../architecture/v0.14.0-CRDT_FOUNDATION.md)