Event Handling and Distribution

This outline provides an overview of the event handling and distribution system within the Go-Events library.

Event Handling

Go-Events utilizes the Go standard library’s built-in context package for event handling. This allows for:

  • Context Propagation: Events carry context information, enabling propagation of important data.
  • Cancellation: Events can be cancelled gracefully, allowing for coordinated shutdown.

Event Distribution

The Go-Events library provides flexibility in distributing events:

1. Event Bus

The EventBus is the primary mechanism for distributing events. It acts as a central hub where event producers publish events and consumers subscribe to receive them.

Source: eventbus/eventbus.go

Example:

import "github.com/docker/go-events"
          
          // Create an event bus.
          bus := events.NewEventBus()
          
          // Publish an event.
          bus.Publish(context.Background(), "my-event", "some data")
          
          // Subscribe to an event.
          bus.Subscribe("my-event", func(ctx context.Context, event events.Event) error {
              // Process the event.
              return nil
          })
          

2. Event Channels

Events can be directly published to specific channels using EventChan. This allows for more controlled and targeted event delivery.

Source: eventbus/eventbus.go

Example:

import (
              "context"
              "github.com/docker/go-events"
          )
          
          // Create an event channel.
          channel := events.NewEventChan()
          
          // Publish an event to the channel.
          channel.Publish(context.Background(), "my-event", "some data")
          
          // Subscribe to the channel.
          channel.Subscribe(func(ctx context.Context, event events.Event) error {
              // Process the event.
              return nil
          })
          

3. Event Loops

Event loops offer a mechanism for processing events asynchronously. This allows for non-blocking event handling and improved concurrency.

Source: eventloop/eventloop.go

Example:

import (
              "context"
              "github.com/docker/go-events"
          )
          
          // Create an event loop.
          loop := events.NewEventLoop()
          
          // Start the event loop.
          go loop.Start()
          
          // Publish an event to the event loop.
          loop.Publish(context.Background(), "my-event", "some data")
          
          // Subscribe to the event loop.
          loop.Subscribe("my-event", func(ctx context.Context, event events.Event) error {
              // Process the event.
              return nil
          })
          

4. Event Manager

The EventManager allows for managing multiple event sources and destinations. This provides a centralized control point for complex event systems.

Source: eventmanager/eventmanager.go

Example:

import (
              "context"
              "github.com/docker/go-events"
          )
          
          // Create an event manager.
          manager := events.NewEventManager()
          
          // Register an event source.
          manager.RegisterSource("source-1", events.NewEventBus())
          
          // Register an event destination.
          manager.RegisterDestination("destination-1", events.NewEventLoop())
          
          // Publish an event from the source.
          manager.PublishFrom("source-1", context.Background(), "my-event", "some data")
          
          // Subscribe to the destination.
          manager.SubscribeTo("destination-1", "my-event", func(ctx context.Context, event events.Event) error {
              // Process the event.
              return nil
          })
          

Error Handling

Events can carry errors. This allows for event producers to signal errors to consumers.

Source: eventbus/eventbus.go

Example:

import (
              "context"
              "errors"
              "github.com/docker/go-events"
          )
          
          // Publish an event with an error.
          bus.Publish(context.Background(), "my-event", errors.New("an error occurred"))
          
          // Subscribe to the event and handle the error.
          bus.Subscribe("my-event", func(ctx context.Context, event events.Event) error {
              if event.Error() != nil {
                  // Handle the error.
                  return event.Error()
              }
              return nil
          })
          

Event Types

Go-Events supports various event types:

  • Event: The base event type, carrying an optional error.
  • TypedEvent: An event with a defined type, useful for categorization.

Source: eventbus/eventbus.go

Example:

import (
              "context"
              "github.com/docker/go-events"
          )
          
          // Define a typed event.
          type MyEvent struct {
              Data string
          }
          
          // Publish a typed event.
          bus.Publish(context.Background(), "my-event", events.NewTypedEvent("my-type", MyEvent{Data: "some data"}))
          
          // Subscribe to the typed event.
          bus.Subscribe("my-event", func(ctx context.Context, event events.Event) error {
              // Retrieve the typed event data.
              typedEvent, ok := event.Payload().(events.TypedEvent)
              if ok {
                  data, ok := typedEvent.Data().(MyEvent)
                  if ok {
                      // Process the data.
                  }
              }
              return nil
          })
          

Event Serialization

Go-Events allows for event serialization, enabling interoperability between different components and systems.

Source: eventbus/eventbus.go

Example:

import (
              "context"
              "github.com/docker/go-events"
              "github.com/docker/go-events/encoding/json"
          )
          
          // Create a JSON encoder.
          encoder := json.NewEncoder()
          
          // Publish an event with JSON serialization.
          bus.Publish(context.Background(), "my-event", events.NewEvent(encoder.Encode("some data")))
          
          // Subscribe to the event and decode the data.
          bus.Subscribe("my-event", func(ctx context.Context, event events.Event) error {
              // Decode the data.
              data, err := encoder.Decode(event.Payload())
              if err != nil {
                  return err
              }
          
              // Process the data.
              return nil
          })
          

This outline provides a comprehensive overview of the event handling and distribution system within Go-Events. By leveraging the features outlined here, developers can build robust, scalable, and efficient event-driven systems.