Overviewâ
The task domain has three types of entry points:
| Entry Point | User | Description |
|---|---|---|
services.Jobs() | Source plugins | Reads the visible scheduled task view |
services.Admin().Jobs() | Trusted source plugins | Triggers tasks or modifies task status |
JobsRegistrar, pluginbridge.NewDeclarations().Jobs() | Source plugin registration phase, dynamic plugin discovery phase | Declares the plugin's own scheduled tasks |
Jobs() focuses on the view of tasks already under host management; JobsRegistrar and jobs.register focus on submitting task declarations to the host during plugin registration or discovery. The two should not be conflated into the same runtime call surface.
Capability phase: Runtime
Type support: Source plugins, dynamic plugins
Capability Designâ
Separation of Read and Registrationâ
The task capability follows a read/registration separation pattern: Jobs() reads the view of tasks already under host management, JobsRegistrar declares tasks during the source plugin registration phase, and pluginbridge.NewDeclarations().Jobs().Register declares tasks through the jobs.register host service during the dynamic plugin discovery phase.
Task View Modelâ
Jobs() returns a task view for reading the status of tasks already under host management:
| Field | Description |
|---|---|
ID | Task identifier |
Name | Task display name |
Group | Task grouping |
Status | Task lifecycle state |
Registration Timingâ
Source plugins declare scheduled tasks through JobsRegistrar during the compile-time registration flow. Dynamic plugins submit JobContract through jobs.register during the discovery phase. Registration requests only take effect during the host discovery and collection phase, and are not task execution interfaces that can be called at arbitrary business times.
Interface Definitionsâ
Source Plugin Interfaceâ
| Entry Point | Method | Description |
|---|---|---|
Jobs() | BatchGetJobs | Batch reads visible task views |
Admin().Jobs() | RunJob | Triggers execution of a visible task |
Admin().Jobs() | SetJobStatus | Changes the status of a visible task |
Source plugin registration interface (accessed through the JobsRegistrar returned by SourcePluginDefinition.GetJobRegistrars()):
// Use JobsRegistrar inside the JobHandlerRegistration.Handler callback
func(ctx context.Context, registrar pluginhost.JobsRegistrar) error {
return registrar.Add(ctx, "0 2 * * *", "daily-report", func(ctx context.Context) error {
// Execute scheduled task logic
return nil
})
}
Dynamic Plugin Interfaceâ
| Dynamic Method | Description |
|---|---|
jobs.batch_get | Batch reads visible scheduled task views |
jobs.register | Submits a scheduled task declaration during the discovery phase |
Usageâ
Source Plugin Usageâ
Source plugins read task views through services.Jobs():
// Batch read task views
result, err := services.Jobs().BatchGetJobs(ctx, capabilityCtx, jobIDs)
Trusted source plugins execute management commands:
// Trigger task execution
err := services.Admin().Jobs().RunJob(ctx, capabilityCtx, jobID)
// Change task status
err := services.Admin().Jobs().SetJobStatus(ctx, capabilityCtx, jobID, "disabled")
Source plugins declare scheduled tasks through JobsRegistrar during the registration phase:
// Register in the callback returned by SourcePluginDefinition.GetJobRegistrars()
func(ctx context.Context, registrar pluginhost.JobsRegistrar) error {
return registrar.AddWithMetadata(ctx, "0 2 * * *", "daily-report", "Daily Report", "Generate report at 2 AM daily",
func(ctx context.Context) error {
// Execute scheduled task logic
return nil
},
)
}
Dynamic Plugin Usageâ
Dynamic plugins declare the jobs service in plugin.yaml:
hostServices:
- service: jobs
methods:
- jobs.batch_get
- jobs.register
jobs is a none resource type and does not declare resource fields. Dynamic plugins submit task declarations through the declaration-phase entry during discovery:
decl := pluginbridge.NewDeclarations()
// Register a scheduled task during WASM guest discovery via jobs.register
err := decl.Jobs().Register(&protocol.JobContract{
Name: "cleanup-temp",
DisplayName: "Temp File Cleanup",
Description: "Clean up expired temporary files at 3 AM daily",
Pattern: "0 3 * * *",
Timezone: "Asia/Shanghai",
Scope: protocol.JobScopeAllNode,
Concurrency: protocol.JobConcurrencySingleton,
TimeoutSeconds: 300,
RequestType: "CleanupTempReq",
})
Dynamic plugin registration requests only take effect during the host discovery and collection phase, and are not task execution interfaces that can be called at arbitrary business times.
Design Constraintsâ
- Read and registration are separated.
Jobs()reads task views;JobsRegistrarandjobs.registerdeclare task contracts. Neither takes on the other's responsibility. - Execution is a management command.
RunJobandSetJobStatusmust go throughAdmin().Jobs()and domain governance. - Dynamic
jobs.registeris for the discovery phase. Dynamic plugins should not use it as a business-side on-demand scheduling interface. - Task tables are not exposed to plugins. Plugins cannot read host task logs, scheduler internal state, or database table structures through the task capability.
- Task status is defined by the host. Plugins should not write status values that the host state machine does not accept.