Ddonisgo
Framework

Events & Request–Reply

Event bus async, pola request–reply untuk sinkronisasi data antar plugin, dan pola deadline.

Event bus

internal/events menyediakan bus ringan. Handler dijalankan async di goroutine terpisah secara default.

// subscribe (return unsubscribe func)
unsub := events.Subscribe("user.created", func(ctx context.Context, payload interface{}) {
    // payload bisa nilai apa pun
})
defer unsub()

// publish (async ke semua subscriber)
events.Publish("user.created", map[string]interface{}{"id": "user123"})

Request–Reply (pola aman untuk sync)

Untuk sinkronisasi data synchronous antar plugin, gunakan events.RequestReply. Ia membuat reply topic unik per request, publish request dengan field ReplyTo, dan menunggu (dengan timeout) satu reply.

deadline := time.Now().Add(2 * time.Second).UnixNano()
req := map[string]interface{}{ "id": "42", "Deadline": deadline }
resp, err := events.RequestReply(ctx, "user.query", req, 2*time.Second)

Subscriber harus baca ReplyTo dan publish response ke topic itu.

Deadline / cancellation pattern

Karena Publish memakai background context, handler bisa selesai setelah caller timeout. Untuk menghindari proses reply basi:

  • Sertakan Deadline (Unix nano) di request payload
  • Subscriber cek deadline sebelum kerja berat & sebelum publish reply
events.Subscribe("user.query", func(ctx context.Context, payload interface{}) {
    m, _ := payload.(map[string]interface{})
    if d, ok := m["Deadline"].(int64); ok && time.Now().UnixNano() > d {
        return // terlalu telat
    }
    replyTo, _ := m["ReplyTo"].(string)
    events.Publish(replyTo, map[string]interface{}{"ok": true})
})