factory_key Configuration
Language: 中文
1. Summary
factory_key is a task factory key in YAML configuration. Its value is the name shared by the configuration file and Rust code, such as api_server. It connects a declarative worker child to a TaskFactory registered in Rust code.
The configuration file stores only declarations. It does not store executable closures. The real task startup logic must be supplied by Rust code.
2. Problem
A Supervisor task tree can declare children through configuration files. However, async_worker and blocking_worker children need an executable TaskFactory when they actually start. A TaskFactory contains Rust code and usually a closure, so it cannot be safely stored directly in YAML.
factory_key defines the boundary. The configuration file writes an agreed key, and Rust code registers a task factory under the same key. Before startup, the system binds the declaration to the executable factory.
3. Configuration
children.yaml can declare workers like this:
- name: api
kind: async_worker
factory_key: api_server
- name: exporter
kind: blocking_worker
factory_key: report_exporter
api_server and report_exporter are not function names. They are configuration-level task factory keys. Rust code must register matching TaskFactory values.
4. Rust Registration
Rust code uses TaskFactoryRegistry to map keys to TaskFactory values.
#![allow(unused)]
fn main() {
use rust_supervisor::spec::child::TaskKind;
use rust_supervisor::task::factory::{TaskResult, service_fn};
use rust_supervisor::task::factory_registry::{
TaskFactoryDescriptor, TaskFactoryRegistry,
};
use std::sync::Arc;
let mut registry = TaskFactoryRegistry::new();
registry.register(TaskFactoryDescriptor::new(
"api_server",
"API Server",
"Runs the API service.",
[TaskKind::AsyncWorker],
Arc::new(service_fn(|_ctx| async { TaskResult::Succeeded })),
))?;
registry.register(TaskFactoryDescriptor::new(
"report_exporter",
"Report Exporter",
"Runs blocking export work.",
[TaskKind::BlockingWorker],
Arc::new(service_fn(|_ctx| async { TaskResult::Succeeded })),
))?;
}
TaskFactoryDescriptor stores 3 kinds of data:
key: The task factory key used by configuration files.titleanddescription: Metadata shown by schema-backed editor completion.allowed_kinds: The task kinds that may use this factory, such asTaskKind::AsyncWorkerorTaskKind::BlockingWorker.
5. Startup Binding
After configuration loading, factory_key is still only a string. Before startup, the string must be resolved to a real TaskFactory.
The current binding path is:
ConfigStatereads child declarations from YAML.to_supervisor_spec_with_factoriesusesTaskFactoryRegistryto bind workers.bind_task_factorieschecks every worker’sfactory_key.- The registry resolves the matching
TaskFactoryand writes it intoChildSpec. Supervisorstarts with already-bound executable task factories.
Binding rules:
- Worker children must declare
factory_key. - Supervisor child nodes must not declare
factory_key. - An unknown
factory_keycauses a configuration error. - A factory that does not support the current
TaskKindcauses a configuration error.
6. Completion Generation
Editor completion depends on JSON Schema. The current implementation does not rewrite the rust-config-tree schema generator. Instead, it post-processes the base schema generated by rust-config-tree.
The flow is:
generate-templateorgenerate-schemaasks rust-config-tree to generate the base schema.supervisor_schema_targets_with_factory_registryreceives the root schema and split-section schemas.- Each schema is parsed into
serde_json::Value. inject_factory_key_completions_if_presentfinds thefactory_keyfield.- The system writes keys from
TaskFactoryRegistryintooneOf. - The schema is serialized again and written to the target file.
After generation, children.schema.json contains a factory_key field like this:
{
"factory_key": {
"description": "TaskFactory registry key used to bind worker children before startup.",
"oneOf": [
{
"const": "api_server",
"description": "Runs the API service.",
"title": "API Server"
},
{
"const": "report_exporter",
"description": "Runs blocking export work.",
"title": "Report Exporter"
}
],
"type": [
"string",
"null"
]
}
}
When an editor reads the yaml-language-server schema directive at the top of children.yaml, it can offer factory_key candidates.
7. Commands
Generate templates:
target/debug/rust-tokio-supervisor generate-template
This command writes configuration templates and schemas with completion metadata.
Generate schemas only:
target/debug/rust-tokio-supervisor generate-schema
This command writes schemas only, and the generated schema also contains factory_key candidates in oneOf.
8. Current Boundaries
factory_keyis a configuration declaration, not executable code.- Completion candidates come from the
TaskFactoryRegistryused by the command. - If Rust code does not register a key, a configuration file using that key cannot start.
- Schema-backed completion helps editors suggest valid candidates, but it does not replace startup binding validation.
- Runtime child addition goes through the same kind of binding validation, so dynamic additions cannot bypass the registry.