College Online
0%

Integrando ao Mesh

Modulo 6 · Aula 3 ~30 min de leitura Nivel: Avancado

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:

*
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.

  1. Implemente health check periodico (a cada 30s) entre todos os nodes
  2. Se um node falhar 3 health checks consecutivos, marque como unhealthy
  3. Implemente circuit breaker: apos 5 falhas, pare de enviar requests por 60s
  4. Adicione metricas: latencia media, error rate, throughput
  5. Implemente failover: se build.ai esta down, redirecione para marco.ai
  6. 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?

  • CLOSED
  • OPEN
  • HALF_OPEN
  • RECOVERY