Skip to main content
Version: 0.4.x(Latest)

Overview​

The task domain has three types of entry points:

Entry PointUserDescription
services.Jobs()Source pluginsReads the visible scheduled task view
services.Admin().Jobs()Trusted source pluginsTriggers tasks or modifies task status
JobsRegistrar, pluginbridge.NewDeclarations().Jobs()Source plugin registration phase, dynamic plugin discovery phaseDeclares 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:

FieldDescription
IDTask identifier
NameTask display name
GroupTask grouping
StatusTask 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 PointMethodDescription
Jobs()BatchGetJobsBatch reads visible task views
Admin().Jobs()RunJobTriggers execution of a visible task
Admin().Jobs()SetJobStatusChanges 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 MethodDescription
jobs.batch_getBatch reads visible scheduled task views
jobs.registerSubmits 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; JobsRegistrar and jobs.register declare task contracts. Neither takes on the other's responsibility.
  • Execution is a management command. RunJob and SetJobStatus must go through Admin().Jobs() and domain governance.
  • Dynamic jobs.register is 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.