Arquitetura Event-Driven com Zig

Arquitetura Event-Driven com Zig

Arquitetura orientada a eventos é a base de sistemas de alta performance — servidores web, processadores de mensagens e pipelines de dados. Zig, com controle explícito de I/O e suporte a io_uring no Linux, permite construir sistemas event-driven extremamente eficientes.

Event Loop Básico

const std = @import("std");

const Evento = struct {
    tipo: TipoEvento,
    dados: []const u8,
    timestamp: i64,
};

const TipoEvento = enum {
    requisicao_http,
    mensagem_recebida,
    timer_expirado,
    conexao_nova,
    conexao_fechada,
};

const EventHandler = *const fn (Evento) void;

const EventLoop = struct {
    handlers: std.AutoHashMap(TipoEvento, std.ArrayList(EventHandler)),
    fila: std.ArrayList(Evento),
    rodando: bool = false,
    allocator: std.mem.Allocator,

    pub fn init(allocator: std.mem.Allocator) EventLoop {
        return .{
            .handlers = std.AutoHashMap(TipoEvento, std.ArrayList(EventHandler)).init(allocator),
            .fila = std.ArrayList(Evento).init(allocator),
            .allocator = allocator,
        };
    }

    pub fn on(self: *EventLoop, tipo: TipoEvento, handler: EventHandler) !void {
        const result = try self.handlers.getOrPut(tipo);
        if (!result.found_existing) {
            result.value_ptr.* = std.ArrayList(EventHandler).init(self.allocator);
        }
        try result.value_ptr.append(handler);
    }

    pub fn emitir(self: *EventLoop, evento: Evento) !void {
        try self.fila.append(evento);
    }

    pub fn rodar(self: *EventLoop) void {
        self.rodando = true;
        while (self.rodando) {
            if (self.fila.items.len == 0) {
                std.time.sleep(1 * std.time.ns_per_ms);
                continue;
            }

            const evento = self.fila.orderedRemove(0);
            if (self.handlers.get(evento.tipo)) |handler_list| {
                for (handler_list.items) |handler| {
                    handler(evento);
                }
            }
        }
    }

    pub fn parar(self: *EventLoop) void {
        self.rodando = false;
    }
};

Fila de Mensagens Lock-Free

fn FilaMensagens(comptime T: type, comptime capacidade: usize) type {
    return struct {
        buffer: [capacidade]T = undefined,
        write_pos: std.atomic.Value(usize) = std.atomic.Value(usize).init(0),
        read_pos: std.atomic.Value(usize) = std.atomic.Value(usize).init(0),

        const Self = @This();

        pub fn publicar(self: *Self, msg: T) bool {
            const wp = self.write_pos.load(.acquire);
            const next = (wp + 1) % capacidade;
            if (next == self.read_pos.load(.acquire)) return false;
            self.buffer[wp] = msg;
            self.write_pos.store(next, .release);
            return true;
        }

        pub fn consumir(self: *Self) ?T {
            const rp = self.read_pos.load(.acquire);
            if (rp == self.write_pos.load(.acquire)) return null;
            const msg = self.buffer[rp];
            self.read_pos.store((rp + 1) % capacidade, .release);
            return msg;
        }
    };
}

Conclusão

Zig oferece os primitivos ideais para construir sistemas event-driven de alta performance: controle explícito de I/O, estruturas de dados lock-free com atomics, e integração com io_uring para I/O assíncrono no Linux. O resultado são sistemas que processam milhões de eventos por segundo com latência previsível.

Conteúdo Relacionado

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.