Integrando ao Mesh
Video da aula estara disponivel em breve
De prototipo a producao
Na aula anterior implementamos comunicacao basica entre dois nodes. Para um mesh de producao, precisamos de: health checks automaticos, failover, circuit breaker, e observabilidade.
Health checks e failover
Python
import asyncio
import time
class HealthChecker:
"""Monitor de saude dos nodes do mesh."""
def __init__(self, client, interval=30, timeout=5, max_failures=3):
self.client = client
self.interval = interval # segundos entre checks
self.timeout = timeout # timeout do check
self.max_failures = max_failures
self.failure_count = {} # node_id -> count
self.node_status = {} # node_id -> healthy/unhealthy
async def check_node(self, node_id, endpoint):
"""Verifica saude de um node."""
try:
healthy = await asyncio.wait_for(
self.client.health_check(endpoint),
timeout=self.timeout
)
if healthy:
self.failure_count[node_id] = 0
self.node_status[node_id] = "healthy"
return True
except (asyncio.TimeoutError, Exception):
pass
# Falha
self.failure_count[node_id] = self.failure_count.get(node_id, 0) + 1
if self.failure_count[node_id] >= self.max_failures:
self.node_status[node_id] = "unhealthy"
print(f"[ALERT] Node {node_id} marked UNHEALTHY")
return False
async def run(self, nodes):
"""Loop de health check periodico."""
while True:
tasks = [
self.check_node(nid, endpoint)
for nid, endpoint in nodes.items()
]
await asyncio.gather(*tasks)
await asyncio.sleep(self.interval)
Circuit breaker
O circuit breaker e um padrao que "abre o circuito" (para de fazer requests) quando um servico esta falhando, evitando sobrecarga. Apos um periodo de cooldown, tenta novamente.
Python
import time
from enum import Enum
class State(Enum):
CLOSED = "closed" # Normal: requests passam
OPEN = "open" # Falhou: requests bloqueados
HALF_OPEN = "half_open" # Testando: 1 request passa
class CircuitBreaker:
def __init__(self, failure_threshold=5, recovery_timeout=60):
self.state = State.CLOSED
self.failure_count = 0
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.last_failure_time = 0
def can_execute(self):
"""Verifica se request pode passar."""
if self.state == State.CLOSED:
return True
elif self.state == State.OPEN:
# Verificar se cooldown expirou
if time.time() - self.last_failure_time > self.recovery_timeout:
self.state = State.HALF_OPEN
return True
return False
else: # HALF_OPEN
return True
def record_success(self):
self.failure_count = 0
self.state = State.CLOSED
def record_failure(self):
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = State.OPEN
print(f"Circuit OPEN! (after {self.failure_count} failures)")
# Uso com mesh client
breakers = {} # node_id -> CircuitBreaker
async def safe_request(node_id, request_fn):
if node_id not in breakers:
breakers[node_id] = CircuitBreaker()
cb = breakers[node_id]
if not cb.can_execute():
print(f"Circuit OPEN for {node_id}, skipping")
return None
try:
result = await request_fn()
cb.record_success()
return result
except Exception as e:
cb.record_failure()
raise
Diagrama
Estados do Circuit Breaker:
CLOSED ──(failure threshold)──> OPEN
^ |
| (recovery timeout)
| |
+───(success)──── HALF_OPEN <───+
|
(failure) ──> OPEN
Monitoramento e observabilidade
Python
import time
from dataclasses import dataclass, field
@dataclass
class MeshMetrics:
"""Metricas de rede do mesh."""
requests_total: int = 0
requests_failed: int = 0
latencies: list = field(default_factory=list)
bytes_sent: int = 0
bytes_received: int = 0
def record_request(self, latency_ms, success, bytes_in, bytes_out):
self.requests_total += 1
if not success:
self.requests_failed += 1
self.latencies.append(latency_ms)
self.bytes_sent += bytes_out
self.bytes_received += bytes_in
def summary(self):
if not self.latencies:
return "No data"
return {
"total_requests": self.requests_total,
"error_rate": self.requests_failed / max(self.requests_total, 1),
"avg_latency_ms": sum(self.latencies) / len(self.latencies),
"p99_latency_ms": sorted(self.latencies)[int(len(self.latencies) * 0.99)],
"throughput_bytes": self.bytes_sent + self.bytes_received,
}
# Uso
metrics = MeshMetrics()
metrics.record_request(latency_ms=45, success=True, bytes_in=1024, bytes_out=256)
metrics.record_request(latency_ms=120, success=True, bytes_in=2048, bytes_out=512)
metrics.record_request(latency_ms=5000, success=False, bytes_in=0, bytes_out=256)
print(metrics.summary())
Arquitetura final do mesh
Diagrama
Arquitetura completa do harness.os mesh:
┌─────────────────────────────────┐
│ Mesh Registry │
│ (service discovery + routing) │
└──────────┬──────────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
┌──────────┴──────────┐ ┌┴──────────────┐ ┌┴──────────────┐
│ marco.ai │ │ build.ai │ │ cortex.ai │
│ ┌───────────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ MCP Server │ │ │ │ MCP Server│ │ │ │ MCP Server│ │
│ │ (Fly.io) │ │ │ │ (Fly.io) │ │ │ │ (Fly.io) │ │
│ ├───────────────┤ │ │ ├───────────┤ │ │ ├───────────┤ │
│ │ Health Check │ │ │ │ Health Chk│ │ │ │ Health Chk│ │
│ │ Circuit Brkr │ │ │ │ Circuit Bk│ │ │ │ Circuit Bk│ │
│ │ Metrics │ │ │ │ Metrics │ │ │ │ Metrics │ │
│ ├───────────────┤ │ │ ├───────────┤ │ │ ├───────────┤ │
│ │ JWT Auth │ │ │ │ JWT Auth │ │ │ │ JWT Auth │ │
│ │ TLS │ │ │ │ TLS │ │ │ │ TLS │ │
│ └───────┬───────┘ │ │ └─────┬─────┘ │ │ └─────┬─────┘ │
└──────────┼──────────┘ └───────┼───────┘ └───────┼───────┘
│ │ │
└──────────────────────┼─────────────────┘
│
┌──────────┴──────────┐
│ Neon Postgres │
│ (shared state) │
│ purple-cell-95681 │
└─────────────────────┘
Cada node tem:
- MCP Server: processa tool calls
- Health checker: monitora peers
- Circuit breaker: protege contra nodes falhos
- Metrics collector: observabilidade
- JWT auth: autenticacao entre nodes
- TLS: criptografia em transito
Conceitos de rede aplicados:
DNS resolution -> Slug -> UUID (aula 2.2)
HTTP/SSE transport -> MCP protocol (aula 2.1, 2.3)
TCP reliability -> Handoffs confiáveis (aula 3.2)
IP addressing -> UUID addressing (aula 4.1)
Routing -> Concern-based routing (aula 4.2)
Firewalls + TLS -> Seguranca (aula 4.3, 5.2)
Load balancing -> Agent orchestration (aula 5.3)
Service mesh -> Mesh node communication (aula 5.3)
Resumo do curso
Ao longo de 18 aulas, percorremos todas as camadas de uma rede de computadores e aplicamos cada conceito ao harness.os:
- Modulo 1: O que sao redes, modelos em camadas, metricas de desempenho
- Modulo 2: HTTP, DNS, protocolos de aplicacao (WebSocket, SSE, gRPC)
- Modulo 3: UDP (fire-and-forget), TCP (confiavel), controle de congestionamento
- Modulo 4: IP e enderecamento, roteamento, redes na pratica (firewalls, VPN, cloud)
- Modulo 5: Enlace de dados, seguranca (TLS, OAuth, JWT), redes distribuidas
- Modulo 6: Projeto: protocolo, implementacao e integracao do mesh harness.os
O mesh DO harness.os e uma rede
Cada conceito de networking que aprendemos tem aplicacao direta no harness.os. Agora voce sabe por que MCP usa HTTP/SSE, por que Neon precisa de TCP com TLS, por que slugs funcionam como DNS, e como projetar comunicacao entre mesh nodes com confiabilidade, seguranca e observabilidade.
Exercicio pratico (projeto final)
Adicione health check e failover ao prototipo de mesh.
- Implemente health check periodico (a cada 30s) entre todos os nodes
- Se um node falhar 3 health checks consecutivos, marque como unhealthy
- Implemente circuit breaker: apos 5 falhas, pare de enviar requests por 60s
- Adicione metricas: latencia media, error rate, throughput
- Implemente failover: se build.ai esta down, redirecione para marco.ai
- Apresente um dashboard (print no terminal) com status de todos os nodes
Verifique seu entendimento
Em que estado o circuit breaker permite exatamente um request de teste para verificar se o servico voltou?