Skip to main content

A strongly-typed cybernetic kernel for building durable event-driven systems in Python.

Project description

BussDCC

License Python

bussdcc is a strongly-typed cybernetic kernel for building durable, event-driven systems in Python.

It provides a minimal but complete coordination core for systems that manage:

  • Devices (hardware, boundaries, external resources)
  • Processes (event-driven logic)
  • Interfaces (human/network adapters)
  • Services (time-driven supervised workers)

The kernel defines contracts, lifecycle, dispatch authority, and supervision — but leaves application policy to you.

Why BussDCC?

Modern Python systems often grow into tangled combinations of:

  • Threads
  • Callbacks
  • Background loops
  • Signal handlers
  • Implicit global state

bussdcc enforces:

  • Explicit lifecycles
  • Authoritative message dispatch
  • Typed events
  • Supervised background services
  • Deterministic boot and shutdown

It is not an application framework.

It is a coordination kernel.

Quick Start

from bussdcc import Runtime, Device, Process, Service, message

class MySensor(Device):
    kind = "sensor"

    def connect(self):
        print("Sensor online")

    def disconnect(self):
        print("Sensor offline")


class Logger(Process):
    name = "logger"

    def handle_event(self, ctx, evt):
        print(evt.payload.name, evt.payload.to_dict())


class Heartbeat(Service):
    name = "heartbeat"
    interval = 2.0

    def tick(self, ctx):
        ctx.emit(message.SystemSignal(signal=0, action="heartbeat"))


rt = Runtime()
rt.attach_device(MySensor(id="sensor-1"))
rt.register_process(Logger())
rt.register_service(Heartbeat())

rt.boot()

Architectural Model

At its core, bussdcc is built around a single invariant:

All coordination flows through typed Message events. The Runtime is the authoritative dispatcher.

Everything else supports that invariant.

Core Concepts

Runtime

The Runtime is the coordination authority.

It:

  • Owns the Context

  • Owns the event dispatch loop

  • Controls boot and shutdown order

  • Supervises services

  • Routes every Message to:

    • Processes
    • Interfaces
    • Services (event-driven side)

Boot order is deterministic:

  1. Devices attach
  2. Processes attach and start
  3. Interfaces attach and start
  4. Services attach and begin supervised execution

Shutdown reverses this order.

The runtime emits lifecycle messages:

  • runtime.booting
  • runtime.booted
  • runtime.shutting_down
  • runtime.shutdown

The runtime is also usable as a context manager:

with Runtime() as rt:
    ...

Context

The Context is a minimal capability container.

It exposes:

  • clock — time abstraction
  • events — event bus
  • state — thread-safe hierarchical state
  • runtime — runtime access
  • emit(message) — authoritative message emission

The context is intentionally small and infrastructure-focused.

Messages

Messages are:

  • Frozen dataclasses
  • Strictly typed
  • Assigned a severity level

Example:

@dataclass(slots=True, frozen=True)
class ProcessError(Message):
    name = "process.error"
    severity = Severity.ERROR

Every message becomes an Event[Message] when emitted.

Severity levels:

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

Severity protects the system from infinite error recursion during failure cascades.

Event Engine

The EventBus is:

  • Synchronous
  • Thread-safe
  • In-process
  • Typed

Handlers run in the emitter’s thread.

Subscriber failures are isolated and converted into event.subscriber_error messages (unless already error-level).

This is coordination — not distributed messaging middleware.

Devices

Devices represent hardware or external boundaries.

Lifecycle:

attach(ctx) → connect()
detach()   → disconnect()

Devices emit:

  • device.attached
  • device.detached
  • device.failed

Devices are expected to fail honestly.

Processes

Processes are synchronous, event-driven logic units.

They:

  • Attach to the runtime
  • Start during boot
  • Receive every emitted Message
  • React via handle_event

Lifecycle:

  • attach(ctx)
  • start(ctx)
  • handle_event(ctx, evt)
  • stop(ctx)
  • detach()

Errors are isolated and converted into process.error.

Interfaces

Interfaces are processes by role.

They typically:

  • Translate external input (HTTP, CLI, UI, network) into Messages
  • Present system state outward

They follow the same lifecycle as processes but are registered separately for clarity.

Services

Services are supervised, time-driven components.

They:

  • Run in dedicated threads
  • Execute tick(ctx) on an interval
  • May restart automatically
  • May be marked critical

Execution model:

start()
loop:
    tick()
    sleep(interval)
stop()

Supervisor messages:

  • service.started
  • service.stopped
  • service.error
  • service.restart
  • service.failure

Critical failures can halt the supervisor.

State

The StateStore is:

  • Thread-safe
  • Hierarchical
  • Dot-path addressable

Example:

ctx.state.set("system.clock.uptime", 42)
value = ctx.state.get("system.clock.uptime")

It intentionally provides:

  • No schema
  • No persistence
  • No policy

It is coordination state — not storage.

Clock Abstraction

Time is abstracted via ClockProtocol.

Default: SystemClock

Provides:

  • now_utc()
  • monotonic()
  • sleep(seconds, cancel=Event)

Custom clocks (simulated, deterministic, test clocks) can be injected.

Runtime Variants

Runtime

Standard synchronous kernel.

ThreadedRuntime

Owns a background execution thread. Provides .run() which blocks until shutdown.

SignalRuntime

Adds POSIX signal supervision:

  • SIGINT → shutdown
  • SIGTERM → shutdown
  • SIGHUP → reload
  • SIGUSR1, SIGUSR2 → user-defined message events

Signals are converted into typed system messages.

Design Principles

  • Authoritative dispatch — only the runtime routes messages.
  • Typed contracts over inheritance depth
  • Infrastructure replaceable by protocol
  • Explicit lifecycle ordering
  • Failure isolation
  • mypy --strict compatibility

What BussDCC Is

  • A cybernetic (feedback-driven) coordination kernel

  • A durable event-driven runtime

  • Suitable for:

    • IoT systems
    • Robotics
    • Hardware control
    • Automation engines
    • Control planes
    • Edge services

What BussDCC Is Not

  • Not Django
  • Not FastAPI
  • Not Celery
  • Not a rules engine
  • Not a persistence layer
  • Not a distributed system

It is the thing you build those systems on top of.

Status

Alpha

Core architecture is stabilizing. APIs may evolve, but the dispatch model and lifecycle ordering are solidifying.

Installation

pip install bussdcc

Requires Python 3.11+

License

MIT License

Durable systems start with explicit contracts, supervised execution, and honest failure boundaries.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bussdcc-0.41.0.tar.gz (28.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bussdcc-0.41.0-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file bussdcc-0.41.0.tar.gz.

File metadata

  • Download URL: bussdcc-0.41.0.tar.gz
  • Upload date:
  • Size: 28.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for bussdcc-0.41.0.tar.gz
Algorithm Hash digest
SHA256 a9d9377a2fd736271f979ac28321fcdababd8348fc2e18d4f30f6093845727f5
MD5 bd6256578486b03a3130fb40d2fb7e65
BLAKE2b-256 3c7662e633f65888e953b0b918b5d96147d7a54394c685dd10cd65083d939347

See more details on using hashes here.

File details

Details for the file bussdcc-0.41.0-py3-none-any.whl.

File metadata

  • Download URL: bussdcc-0.41.0-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for bussdcc-0.41.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42e7eb5e6622e62a827859dcfc17ca2c8a543c2355325c3af73c7d175e879231
MD5 3ddc434a27ab0cf488e4f7e819d456f0
BLAKE2b-256 051e5145b1ce9b2ca00c5c30241db79789c1557d5e6a5298c8e814595583b4a2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page