-
Notifications
You must be signed in to change notification settings - Fork 0
Event System
TheMinecraftGuyGuru edited this page Jun 8, 2026
·
6 revisions
Event-driven everything. Do NOT tightly couple modules.
MuxCore uses events as the primary integration pattern. Modules publish events when state changes; other modules subscribe to react.
MuxCore provides an in-memory event bus by default. NATS is available as an optional module (eventbus-nats) for distributed messaging.
Core defines only module-lifecycle and cluster-lifecycle event types. Domain event types (download.*, playback.*, transcode.*, etc.) are defined in their respective contract repos.
type Event struct {
ID string
Type string // e.g., "download.completed" (defined in contracts-downloader)
Source string // e.g., "module:downloader-qbittorrent"
Payload []byte // JSON or protobuf
Metadata map[string]string
Timestamp time.Time
}| Event | Description |
|---|---|
module.registered |
Module discovered and registered |
module.unregistered |
Module removed |
module.degraded |
Module running with reduced capabilities |
cluster.node.joined |
Node joined the cluster |
cluster.node.left |
Node left the cluster |
cluster.leader.changed |
Cluster leader changed |
Domain event types and payloads are defined in their respective contract repos:
| Contract Repo | Example Events |
|---|---|
contracts-media |
library.item.added, library.item.removed
|
contracts-downloader |
download.started, download.completed, download.failed
|
contracts-playback |
playback.started, playback.stopped, stream.*
|
contracts-transcoder |
transcode.started, transcode.completed, transcode.failed
|
contracts-metadata |
metadata.fetched |
contracts-artwork |
artwork.fetched |
contracts-content |
content.missing, content.fetched
|
contracts-discovery |
discovery.updated |
contracts-quality |
quality.decision, format.matched
|
contracts-mediainfo |
media.analyzed |
import dl "github.com/Muxcore-Media/contracts-downloader"
payload, _ := json.Marshal(dl.DownloadCompletedPayload{
DownloadID: id,
Title: title,
})
deps.EventBus.Publish(ctx, contracts.Event{
Type: dl.EventDownloadCompleted,
Source: "my-downloader",
Payload: payload,
})import dl "github.com/Muxcore-Media/contracts-downloader"
deps.EventBus.Subscribe(ctx, dl.EventDownloadCompleted,
func(ctx context.Context, event contracts.Event) error {
var payload dl.DownloadCompletedPayload
json.Unmarshal(event.Payload, &payload)
return nil
})User clicks "Request Movie"
-> publishes media.requested (from contracts-media)
Workflow Engine receives media.requested
-> starts "movie-request" workflow
Step 1: Metadata Lookup -> request/reply to metadata provider
Step 2: Indexer Search -> request/reply to indexer modules
Step 3: Download -> downloader publishes download.completed when done
Step 4: Import -> publishes library.item.added
Step 5: Notify -> notification module sends alert
Each step is an event. The workflow engine orchestrates but doesn't implement any step directly.
// BAD: Tight coupling
client := downloader.NewClient()
client.AddMagnet(magnet)// GOOD: Loose coupling
bus.Publish(ctx, Event{
Type: dl.EventDownloadApproved,
Payload: payload,
})