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 a framework.

It is a coordination kernel.

Quick Start

from bussdcc import Runtime
from bussdcc.device import Device
from bussdcc.process import Process
from bussdcc.service import Service

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 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.36.0.tar.gz (27.9 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.36.0-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for bussdcc-0.36.0.tar.gz
Algorithm Hash digest
SHA256 98846c1ad1e6cfd0ab53e8065f6ba47126c80dd2c31fd85c6f823c0d0f80b489
MD5 db2f81c348a0169e7c1a81025ee2f387
BLAKE2b-256 ce24aba50d1857829be221b55a33e39dab3019df54a00bcb42b3fac19a786afc

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for bussdcc-0.36.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2cb95cac1eb010daa222b86f1b36bde410a18b402c16cc69061d31d41a7ad4e1
MD5 48cbb45fd0d808c987955d16eb7086a2
BLAKE2b-256 6c8629d598cc93a15fc42d18f102184d8f692e90d619e5de4ecf8df381173baa

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