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.42.0.tar.gz (28.3 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.42.0-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for bussdcc-0.42.0.tar.gz
Algorithm Hash digest
SHA256 44747541fc22c3c5007e7665d212506394d11f44288c09a7ce81b5e32d8148a8
MD5 18fd7047b3c012166b352813314c4c83
BLAKE2b-256 06c654c8520ea831928f102731d82ed51f8ca8951341b9a2c09ddfd8b13a6aa7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bussdcc-0.42.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.42.0-py3-none-any.whl
Algorithm Hash digest
SHA256 24747ca9e95f2c1f83a7c100dccc8fbc854e5afbbbc37023b285b9cbc2305e38
MD5 26c9fb0197cfff346014d6a06d2c2798
BLAKE2b-256 36edfe7ecec40d6af8ef5c132dd2a287fb13ba79b33afc289ea3e303bcfa0574

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