Configuration System¶
Reference for all Pynenc configuration options, sources, and resolution order.
Configuration Sources¶
Configuration values resolve from these sources in priority order (highest first):
Direct assignment in the config instance
Environment variables (
PYNENC__FIELD_NAMEorPYNENC__CLASS__FIELD_NAME)Configuration file specified by
PYNENC__FILEPATHenvironment variableConfiguration file path passed to
Pynenc(config_filepath=...)(YAML, TOML, or JSON)pyproject.tomlunder[tool.pynenc]Default values defined in the
ConfigField
Environment Variables¶
Two naming conventions are supported:
# Default for all config classes
PYNENC__FIELD_NAME="value"
# Specific to a config class
PYNENC__CONFIGPYNENC__FIELD_NAME="value"
The specific form takes precedence over the default form.
Configuration Files¶
pyproject.toml¶
[tool.pynenc]
app_id = "my_application"
orchestrator_cls = "RedisOrchestrator"
broker_cls = "RedisBroker"
state_backend_cls = "RedisStateBackend"
runner_cls = "MultiThreadRunner"
serializer_cls = "JsonPickleSerializer"
queues = ["default", "payments", "reports"]
priority_rules = [
{ task_id = "billing.*", priority = 50.0 },
{ task_id = "reports.*", priority = -10.0 },
]
[tool.pynenc.orchestrator]
max_pending_seconds = 300
[tool.pynenc.runner]
min_threads = 2
max_threads = 8
queues = ["payments", "reports"]
[tool.pynenc.task]
running_concurrency = "task"
YAML¶
app_id: my_application
orchestrator_cls: RedisOrchestrator
orchestrator:
max_pending_seconds: 300
runner:
min_threads: 4
max_threads: 16
queues:
- payments
- reports
Load with:
from pynenc import Pynenc
app = Pynenc(config_filepath="/path/to/pynenc.yaml")
JSON¶
{
"app_id": "my_application",
"orchestrator_cls": "RedisOrchestrator"
}
ConfigPynenc Fields¶
Main application configuration (pynenc.conf.config_pynenc.ConfigPynenc).
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Application identifier |
|
|
|
Orchestrator implementation class name |
|
|
|
Trigger implementation class name |
|
|
|
Broker implementation class name |
|
|
|
State backend implementation class name |
|
|
|
Serializer implementation class name |
|
|
|
Client data store implementation class name |
|
|
|
Runner implementation class name |
|
|
|
Modules imported at runner startup for trigger-backed tasks |
|
|
|
Execute tasks synchronously in calling thread |
|
|
|
Logging level ( |
|
|
|
Print task arguments in log messages |
|
|
|
Maximum printed argument length |
|
|
|
Argument display mode: |
|
|
|
Invocation status cache TTL (seconds) |
|
|
|
Truncate IDs in log context for readability |
|
|
|
Emit ANSI colour codes in |
|
|
|
Log output stream: |
|
|
|
Log format: |
|
|
|
Cycle interval for atomic recovery services |
|
|
|
Safety margin for time-slot allocation |
|
|
|
Runner check interval for atomic services |
|
|
|
Retention window for atomic-service execution records (minutes) |
|
|
|
Capacity cap for atomic-service execution records; oldest are dropped first |
|
|
|
Cron expression for pending invocation recovery |
|
|
|
Maximum time an invocation can remain PENDING |
|
|
|
Cron expression for running invocation recovery |
|
|
|
Heartbeat timeout before runner is considered dead |
ConfigTrigger Fields¶
Trigger configuration (pynenc.conf.config_trigger.ConfigTrigger).
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Minimum interval for checking time-based triggers |
|
|
|
Enable or disable the time-based scheduler entirely |
|
|
|
Maximum number of events processed per event-loop iteration |
|
|
|
Maximum age, in days, of stored emitted events before auto-purge removes them |
|
|
|
When |
|
|
|
Soft cap on the total number of stored events ( |
|
|
|
Soft cap on the total number of stored trigger runs ( |
trigger_task_modules belongs to the main app configuration because the
runner uses it during startup. Normal task modules are loaded lazily when an
invocation first reaches a runner, but trigger-backed tasks need to be known
before any invocation exists: their conditions must already be registered
when the app-level atomic service decides whether to create that first
invocation.
Add every module that declares @app.task(triggers=...). Pynenc imports those
modules when the runner starts and continues to lazy-load task modules that are
not listed.
[tool.pynenc]
trigger_cls = "SQLiteTrigger"
trigger_task_modules = ["tasks"]
scheduler_interval_seconds = 60
ConfigBroker Fields¶
Broker configuration (pynenc.conf.config_broker.ConfigBroker).
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Broker-specific blocking timeout for polling transports |
|
|
|
Declared broker queues. |
|
|
|
Task-id wildcard rules that override task priority |
|
|
|
Log a warning when routing or consuming queues not declared in |
|
|
|
Raise |
Priority rules are structured values with task_id and priority.
task_id uses shell-style wildcards such as billing.*. Matching rules
override the task priority; the highest priority wins when several rules match.
When no rule matches, the task’s concrete priority is used.
[tool.pynenc]
queues = ["default", "payments", "reports"]
priority_rules = [
{ task_id = "billing.*", priority = 50.0 },
{ task_id = "reports.*", priority = -10.0 },
]
Priority is applied within one queue. The broker receives one queue per dequeue
request; if a runner consumes several queues, queue_selection_strategy decides
which queue the runner asks next. round_robin is the default and advances after
each successful dequeue, random shuffles queue attempts for each retrieval, and
ordered always starts from the configured queue order. With ordered, later
queues can starve if earlier queues keep receiving work.
Queue mismatches are flexible by default. A task can route to a queue that is not
currently listed in broker.queues, and a runner can consume an explicitly
named undeclared queue. Set raise_on_queue_mismatch = true for strict deployments.
ConfigTask Fields¶
Per-task configuration (pynenc.conf.config_task.ConfigTask). Configurable globally or per-task.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Batch size for |
|
|
|
Exception types that trigger a retry |
|
|
|
Maximum retry attempts (0 = no retries) |
|
|
|
Runtime concurrency control: |
|
|
|
Registration concurrency control: |
|
|
|
Arguments used for |
|
|
|
Raise error when non-key arguments differ in concurrency check |
|
|
|
Cache results by call arguments |
|
|
|
Arguments to exclude from cache key |
|
|
|
Internal marker used by |
|
|
|
Reroute blocked tasks instead of marking final |
|
|
|
Broker queue used to route invocations of this task |
|
|
|
Task-level priority; matching broker rules override this concrete value |
Important
is_workflow_task is documented because it is the internal switch that makes a
task define a workflow root or sub-workflow root. It enables workflow-defining
invocations and allows root-only APIs such as task.wf.root.execute_task(...),
task.wf.root.uuid(), task.wf.root.random(), and task.wf.root.utc_now().
Prefer @app.workflow instead of setting is_workflow_task through environment
variables, YAML, TOML, or direct config values. External configuration can mark a
task as a workflow at runtime, but it bypasses the clearer public API and the
WorkflowTask type returned by the decorator. Use that escape hatch only for
internal migration or controlled experiments.
Per-Task Configuration¶
Override settings for specific tasks using environment variables or config files:
Environment variables:
# Global task setting
PYNENC__CONFIGTASK__MAX_RETRIES="3"
# Task-specific (module#task separator)
PYNENC__CONFIGTASK__MYMODULE#MY_TASK__MAX_RETRIES="5"
Note
Use # (not __) to separate the module name from the task name in environment variables.
Configuration files:
task:
max_retries: 3
mymodule.my_task:
max_retries: 5
Task decorator:
@app.task(
max_retries=5,
running_concurrency="task",
queue="payments",
priority=75.0,
)
def charge_card(payment_id: str) -> str:
return payment_id
Task queue names are validated as portable queue names when configured. Queue
alignment with broker.queues is checked by the broker when routing or
consuming, according to warn_on_queue_mismatch and
raise_on_queue_mismatch.
Task and broker-rule priorities use finite floats from -100.0 through
100.0. Higher values run first within the same queue, and equal priorities
remain FIFO. Task priority is always concrete and defaults to 0.0. Matching
broker priority_rules override the task value; the highest matching rule wins.
Non-finite and out-of-range values are rejected before routing. Backends with a
narrower native priority model may normalize this range and must document the
resulting ordering precision.
ConfigRunner Fields¶
Base runner configuration (pynenc.conf.config_runner.ConfigRunner).
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Sleep time between result polling checks |
|
|
|
Sleep time between runner loop iterations |
|
|
|
Minimum parallel execution slots |
|
|
|
Queues consumed by this runner. Empty means current broker queues |
|
|
|
Queue selection across multiple consumed queues: |
Runner queue selection uses the same configuration and environment-variable
override mechanisms as other runner fields. Leave queues empty to consume the
current broker queues, or set explicit queue names for a dedicated worker.
The broker dequeues only one queue at a time. When queues resolves to multiple
queues, queue_selection_strategy controls the order in which the runner asks
for them. Prefer round_robin for general workers. Use ordered only when the
first configured queue should dominate; it can starve later queues if the first
queues are never empty.
For a runner-only environment override, use the class-qualified config name:
PYNENC__CONFIGRUNNER__QUEUES=payments,reports pynenc runner start
Runners may also consume queues that are no longer declared in broker config.
The broker applies the configured mismatch warning or error policy when those
queues are consumed, and Pynmon marks them as not configured; this keeps old
queues drainable after deployments.
ThreadRunner Configuration¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Minimum thread pool size |
|
|
|
Maximum thread pool size ( |
MultiThreadRunner Configuration¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Threads per child process |
|
|
|
Threads per child process |
|
|
|
Minimum worker processes |
|
|
|
Maximum worker processes ( |
|
|
|
Seconds idle before a process is terminated |
|
|
|
Always maintain |
PersistentProcessRunner Configuration¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
CPU count |
Number of persistent worker processes |
Plugin Configuration¶
Backend plugins add their own configuration sections. For example:
Redis Plugin¶
[tool.pynenc.redis]
redis_host = "localhost"
redis_port = 6379
redis_db = 0
MongoDB Plugin¶
[tool.pynenc.mongodb]
connection_string = "mongodb://localhost:27017"
database_name = "pynenc"
Hierarchical Resolution¶
Pynenc supports hierarchical configuration classes with inheritance. The most specific (child) configuration takes precedence:
[tool.pynenc]
test_field = "default"
[tool.pynenc.child]
test_field = "child_override"
See Architecture for how configuration fits within the architecture.
See PynencBuilder Reference for programmatic configuration with PynencBuilder.