Packages

macula

0.8.3
15.0.0-rc.2 15.0.0-rc.1 14.10.0 14.9.0 14.8.2 14.8.1 14.8.0 14.7.0 14.6.0 14.5.0 14.4.0 14.3.0 14.2.1 14.2.0 14.1.0 14.0.0 13.6.0 13.5.0 13.4.0 13.3.0 13.2.2 13.2.1 13.2.0 13.1.0 13.0.1 13.0.0 12.12.0 12.11.1 12.11.0 12.10.0 12.9.1 12.9.0 12.8.0 12.7.0 12.6.0 12.5.1 12.5.0 12.4.0 12.3.0 12.2.1 12.2.0 12.1.0 12.0.0 11.5.0 11.4.0 11.3.1 11.3.0 11.2.0 11.1.0 11.0.0 10.25.0 10.24.0 10.23.0 10.22.0 10.21.0 10.20.3 10.20.2 10.20.0 10.19.2 10.19.1 10.19.0 10.18.0 10.17.0 10.16.0 10.15.0 10.14.5 10.14.4 10.14.2 10.14.1 10.14.0 10.13.2 10.13.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 10.9.0 10.8.0 10.7.0 10.5.8 10.5.7 10.5.6 10.5.5 10.5.4 10.5.3 10.5.2 10.5.1 10.5.0 10.4.0 10.2.0 10.1.1 10.1.0 10.0.2 10.0.1 10.0.0 9.13.8 9.8.2 9.8.1 9.8.0 9.5.0 9.4.0 9.3.1 9.3.0 9.2.0 9.1.1 9.1.0 9.0.0 8.7.0 8.6.0 8.5.0 8.4.1 8.4.0 8.3.0 8.2.0 8.1.0 8.0.2 8.0.1 8.0.0 7.1.0 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 README.md
Raw

README.md

<div align="center">
  <img src="artwork/macula-alt-logo.svg" alt="Macula Logo" width="500"/>

  <h1>Macula HTTP/3 Mesh</h1>
  <p><em>Self-organizing distributed mesh for decentralized applications</em></p>

  <p>
    <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"/></a>
    <a href="https://www.erlang.org"><img src="https://img.shields.io/badge/Erlang%2FOTP-26+-brightgreen" alt="Erlang/OTP"/></a>
    <a href="https://hex.pm/packages/macula"><img src="https://img.shields.io/hexpm/v/macula.svg" alt="Hex.pm"/></a>
  </p>
</div>

---

<div align="center">
  <img src="assets/macula-architecture-overview.svg" alt="Macula Architecture Overview" width="800"/>
</div>

<div align="center">
  <p><strong>BEAM-Native • HTTP/3 (QUIC) • Kademlia DHT • Direct P2P • Multi-Tenant • 50% Faster (v0.8.0)</strong></p>
</div>

---

## Table of Contents

- 🏗️ [Architecture Overview](ARCHITECTURE.md) - **Visual guide with diagrams** (C4, supervision trees, deployment topologies)
- 🚀 [Quick Start](#quick-start) - Get started in minutes
- 💡 [What's New in v0.8.0](#whats-new-in-v080) - Latest features
- 📚 [Core Concepts](#core-concepts) - Understanding the mesh
- 🔧 [API Overview](#api-overview) - Using Macula in your application
- 📄 [Changelog](CHANGELOG.md) - Version history and migration guides
- 🐛 [Issues](https://github.com/macula-io/macula/issues) - Report bugs and request features

---

## What is Macula?

Macula is infrastructure for building **decentralized applications and services** that operate autonomously at the edge, without dependency on centralized cloud infrastructure.

**Key Features:**

✅ **BEAM-native** (Erlang/Elixir OTP supervision and fault tolerance)
✅ **HTTP/3 (QUIC)** transport (modern, encrypted, NAT-friendly)
✅ **Edge-first design** (works through firewalls and NAT)
✅ **Built-in pub/sub & RPC** (no external message broker needed)
✅ **Multi-tenancy** (realm isolation for SaaS and shared infrastructure)
✅ **Self-organizing mesh** (DHT-based service discovery, O(log N) routing)
✅ **Production-ready patterns** (OTP behaviors, comprehensive testing, memory management)

---

## Architecture at a Glance

**System Context** - How your application uses Macula:

```
┌──────────────┐
│     Your     │
│ Application  │
└──────┬───────┘
       │ macula_peer API
       ▼
┌──────────────┐     QUIC/HTTP3      ┌──────────────┐
│ Macula Peer  │◄───────────────────►│   Gateway    │
│ (Local Node) │    Or Direct P2P    │ (Relay Node) │
└──────┬───────┘                     └──────┬───────┘
       │                                    │
       └────────────► DHT ◄─────────────────┘
                 (Service Discovery)
```

**Message Flow** (v0.8.0 Direct P2P):

```
Client ──1. Query DHT──► DHT (Find Service)
Client ◄─2. Endpoint──── DHT Returns "192.168.1.50:9443"
Client ──3. Direct────► Provider (1-hop, 50ms)
Client ◄─4. Response─── Provider (50% faster than relay!)
```

**📊 [See Full Architecture Guide](ARCHITECTURE.md)** with:
- C4 diagrams (context, container views)
- Deployment topologies (edge, microservices, hybrid)
- Supervision trees (OTP fault tolerance)
- DHT architecture (Kademlia routing)
- Performance characteristics
- When to use Macula

---

## Installation

**Elixir (mix.exs):**

```elixir
def deps do
  [
    {:macula, "~> 0.8"}
  ]
end
```

**Erlang (rebar.config):**

```erlang
{deps, [
    {macula, "0.8.3"}
]}.
```

**Latest Release**: v0.8.3 (2025-11-17) - Fixed hex docs landing page redirect (v0.8.0: Direct P2P with DHT propagation)

---

##  What's New in v0.8.0

**Major Features:**
- ✅ Direct P2P QUIC connections via `macula_peer_connector`
- ✅ DHT propagation to k=20 closest nodes (Kademlia-based)
- ✅ RPC via direct P2P (50% latency improvement)
- ✅ PubSub via direct P2P (50% latency improvement)
- ✅ 21/21 integration tests passing (100% coverage)

**Performance:**
- 1-hop direct connections vs 2+ hop relay routing
- Reduced gateway load
- Better scalability for large meshes

**Breaking Changes:** None - fully backward compatible with v0.7.x

---

## Quick Start

### 1. Connect to a Gateway

```erlang
%% Start a peer connection
{ok, Peer} = macula_peer:start_link(<<"https://gateway.example.com:9443">>, #{
    realm => <<"com.example.app">>
}).
```

### 2. Publish/Subscribe

```erlang
%% Subscribe to events
ok = macula_peer:subscribe(Peer, <<"sensor.temperature">>, self()).

%% Publish an event
ok = macula_peer:publish(Peer, <<"sensor.temperature">>, #{
    device_id => <<"sensor-001">>,
    celsius => 21.5,
    timestamp => erlang:system_time(millisecond)
}).

%% Receive events
receive
    {macula_event, <<"sensor.temperature">>, Payload} ->
        io:format("Temperature: ~p°C~n", [maps:get(celsius, Payload)])
end.
```

### 3. RPC (Remote Procedure Calls)

```erlang
%% Call a remote service
{ok, Result} = macula_peer:call(Peer, <<"calculator.add">>, #{
    a => 5,
    b => 3
}).
%% Result: #{result => 8}
```

### 4. Advertise Services (Providers)

```erlang
%% Advertise a service handler
ok = macula_peer:advertise(Peer, <<"calculator.add">>, fun(Args) ->
    A = maps:get(a, Args),
    B = maps:get(b, Args),
    #{result => A + B}
end, #{ttl => 300}).
```

---

## Core Concepts

### Mesh Architecture
Macula creates a self-organizing mesh network where nodes communicate over HTTP/3 (QUIC). Each node can act as:
- **Peer** - Application client/server participating in the mesh
- **Gateway** - Relay node for NAT-traversed peers (optional)
- **Registry** - DHT participant storing service advertisements

### Multi-Tenancy via Realms
Realms provide logical isolation for different applications sharing the same physical mesh:
```erlang
%% App 1
{ok, Peer1} = macula_peer:start_link(GatewayUrl, #{realm => <<"com.app1">>}).

%% App 2 (completely isolated from App 1)
{ok, Peer2} = macula_peer:start_link(GatewayUrl, #{realm => <<"com.app2">>}).
```

### DHT-Based Service Discovery
Services are discovered via a Kademlia DHT with k=20 replication:
1. Provider advertises: `advertise(<<"my.service">>, Handler)`
2. DHT propagates to k=20 closest nodes
3. Consumer discovers: `call(<<"my.service">>, Args)`
4. Direct P2P connection established (v0.8.0+)

### Direct P2P Connections (v0.8.0)
Instead of relaying through gateways, v0.8.0 establishes direct QUIC connections:
- Discovered endpoint → Direct connection
- 50% latency reduction (1-hop vs 2+ hops)
- Reduced gateway load

---

## API Overview

### Main Modules

**`macula_peer`** - High-level mesh participant API
- `start_link/2` - Connect to gateway
- `publish/3`, `subscribe/3` - Pub/sub messaging
- `call/3`, `advertise/4` - RPC and service registration

**`macula_gateway`** - Gateway/relay node
- Embedded or standalone gateway deployment
- Client lifecycle management
- Message routing and forwarding

**`macula_peer_connector`** - Direct P2P connections (v0.8.0)
- Establishes outbound QUIC connections
- Fire-and-forget message delivery

### Configuration Options

```erlang
Opts = #{
    realm => <<"com.example.app">>,        %% Required: Realm for isolation
    node_id => <<"my-node-001">>,         %% Optional: Custom node ID
    cert_file => "cert.pem",               %% Optional: TLS certificate
    key_file => "key.pem"                  %% Optional: TLS private key
}
```

---

## Development Setup

```bash
# Clone the repository
git clone https://github.com/macula-io/macula.git
cd macula

# Fetch dependencies
rebar3 get-deps

# Compile
rebar3 compile

# Run tests
rebar3 eunit

# Start a shell with Macula loaded
rebar3 shell
```

---

## Testing

```bash
# Run unit tests
rebar3 eunit

# Run integration tests (requires Docker)
rebar3 ct --suite=test/integration/multi_hop_rpc_SUITE
rebar3 ct --suite=test/integration/multi_hop_pubsub_SUITE
```

---

## License

Macula is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.

---

## Community & Support

- **Issues**: [GitHub Issues](https://github.com/macula-io/macula/issues)
- **Hex Package**: [hex.pm/packages/macula](https://hex.pm/packages/macula)
- **Source Code**: [github.com/macula-io/macula](https://github.com/macula-io/macula)

---

**Built with ❤️ for the BEAM community**