appruntime

package
v0.2.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package appruntime implements the device-independent Application Runtime.

The runtime owns Application Instances (tenant/id/plugin/binding/state) and drives the Application Protocol v1 service through the SDK client: Initialize, Describe, ConfigureInstance, ValidateBinding, HandleEvents, HandleRequest, RunJob, Health and Shutdown. It never references a Driver ID, a serial port, or any concrete hardware field.

The design contract lives in docs/architecture/plugin-system.md (Application Protocol v1, permissions model, supervisor) and docs/architecture/capability-model.md (Application Binding and Invariants).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInstanceNotFound means no instance exists with the supplied id.
	ErrInstanceNotFound = errors.New("appruntime: instance not found")
	// ErrInstanceExists means an instance with the supplied id is already
	// registered.
	ErrInstanceExists = errors.New("appruntime: instance already exists")
	// ErrInstanceNotRunning means the instance exists but cannot accept the
	// operation in its current state.
	ErrInstanceNotRunning = errors.New("appruntime: instance not running")
	// ErrTenantMismatch means a caller-supplied request/effect tried to act as
	// a tenant different from the instance tenant.
	ErrTenantMismatch = errors.New("appruntime: tenant mismatch")
	// ErrRuntimeClosed means the runtime has been shut down.
	ErrRuntimeClosed = errors.New("appruntime: runtime closed")
)

Sentinel errors returned by the runtime.

View Source
var ErrCrossTenantEffect = errors.New("appruntime: cross-tenant application effect")

ErrCrossTenantEffect is returned when an effect targets another tenant or an unbound entity.

View Source
var ErrEffectNotImplemented = errors.New("appruntime: effect not implemented")

ErrEffectNotImplemented means a validated effect is recognized by the protocol but has no Core implementation yet.

View Source
var ErrInvalidEffect = errors.New("appruntime: invalid effect")

ErrInvalidEffect is the base error for malformed effects.

View Source
var ErrUnknownEffect = errors.New("appruntime: unknown application effect")

ErrUnknownEffect is returned when an SDK effect variant is outside the whitelist.

Functions

This section is empty.

Types

type BatchResult

type BatchResult struct {
	Results  []EffectResult
	Executed int
	Failed   int
}

BatchResult reports a batch execution. ExecuteEffects uses fail-fast semantics: execution stops at the first error. Effects before the failure have already been executed, so a failed batch is a partial-success fact.

type CancelJob added in v0.2.3

type CancelJob struct {
	ScheduleID string
}

CancelJob is the bounded payload for EffectCancelJob.

type CreateDomainRecord

type CreateDomainRecord struct {
	RecordType string
	RecordID   string
	DataJSON   string
	Version    string
}

CreateDomainRecord is the bounded payload for EffectCreateDomainRecord.

type Dialer

Dialer resolves a client for the complete instance target, not just plugin ID.

type Effect

type Effect struct {
	ID             string
	IdempotencyKey string
	TenantID       string
	// PluginInstanceID 标记效果来源实例(Executor 落领域记录/审计用;
	// 不参与授权——授权只看 TenantID 与绑定)。
	PluginInstanceID string
	Kind             EffectKind

	CreateDomainRecord *CreateDomainRecord `json:",omitempty"`
	RequestCommand     *RequestCommand     `json:",omitempty"`
	ScheduleJob        *ScheduleJob        `json:",omitempty"`
	CancelJob          *CancelJob          `json:",omitempty"`
	SendNotification   *SendNotification   `json:",omitempty"`
}

Effect is the runtime's validated, Core-approved effect model. Exactly one of the typed payloads must be set for its Kind. Unknown SQL/shell/file operations cannot be represented by this type; callers that bypass the closed union must set an invalid Kind and are rejected by Validate.

func EffectFromSDK

func EffectFromSDK(raw *sdkapplication.ApplicationEffect, src EffectSource) (Effect, error)

EffectFromSDK converts and authorizes a raw SDK ApplicationEffect against the instance source. It rejects unknown effect variants, effects that spoof another instance, and RequestCommand effects that target an unbound or cross-tenant entity.

func (Effect) Validate

func (e Effect) Validate() error

Validate checks the closed union, tenant stamp, idempotency key and every payload bound. It returns an error wrapping ErrInvalidEffect on failure.

type EffectExecutor

type EffectExecutor interface {
	Execute(ctx context.Context, effect Effect) error
}

EffectExecutor is implemented by Core. It receives only effects that have already passed Effect.Validate and the instance tenant check.

type EffectKind

type EffectKind string

EffectKind is the closed set of operations an Application Effect may request from Core.

const (
	// EffectCreateDomainRecord creates or updates a namespaced domain record.
	EffectCreateDomainRecord EffectKind = "create_domain_record"
	// EffectRequestCommand asks Core to dispatch a command to a bound entity.
	EffectRequestCommand EffectKind = "request_command"
	// EffectScheduleJob asks Core to schedule a job.
	EffectScheduleJob EffectKind = "schedule_job"
	// EffectCancelJob asks Core to cancel a previously scheduled job.
	EffectCancelJob EffectKind = "cancel_job"
	// EffectSendNotification asks Core to send a notification.
	EffectSendNotification EffectKind = "send_notification"
)

func (EffectKind) Valid

func (k EffectKind) Valid() bool

Valid reports whether k is one of the allowed effect kinds.

type EffectResult

type EffectResult struct {
	Effect    Effect
	Executed  bool
	Duplicate bool
	Err       error
}

EffectResult reports the outcome of one effect in a batch.

type EffectSource

type EffectSource struct {
	PluginInstanceID string
	TenantID         string
	Bindings         []coreapplication.Binding
	Candidates       []coreapplication.Candidate
}

EffectSource is the instance context used to authorize an SDK effect. The tenant is never read from the plugin; it is stamped from this source.

type Instance

type Instance struct {
	ApplicationID    string
	PluginInstanceID string
	PluginID         string
	TenantID         string
	State            InstanceState
	Err              error

	Descriptor   *sdkapplication.ApplicationDescriptor
	Requirements []coreapplication.Requirement
	Bindings     []coreapplication.Binding
}

Instance is a point-in-time snapshot of an application instance.

type InstanceSpec

type InstanceSpec struct {
	ApplicationID    string
	PluginInstanceID string
	PluginID         string
	TenantID         string

	// PluginVersion is reported to the plugin during Initialize. When empty,
	// the runtime omits it rather than inventing a version.
	PluginVersion string
	// LaunchID is the host-generated launch identity used for the handshake.
	LaunchID string
	// NodeID identifies the node running the instance.
	NodeID string
	// HostInfo carries host metadata for the Initialize handshake.
	HostInfo map[string]string

	// Config and ConfigRevision are passed through to ConfigureInstance.
	Config         []byte
	ConfigRevision uint32

	// Candidates is the bindable view of entities for binding validation.
	Candidates []coreapplication.Candidate
	// Bindings is the proposed binding set for this instance.
	Bindings []coreapplication.Binding

	// EventQueueSize is the per-instance outbound event queue capacity. Zero
	// selects the runtime default.
	EventQueueSize int
}

InstanceSpec is the input for starting one application instance.

type InstanceState

type InstanceState string

InstanceState is the lifecycle state of one application instance.

const (
	// StateCreated means the instance record exists but startup has not begun.
	StateCreated InstanceState = "created"
	// StateStarting means the runtime is performing the startup sequence.
	StateStarting InstanceState = "starting"
	// StateRunning means the event stream is active and the instance serves
	// requests and jobs.
	StateRunning InstanceState = "running"
	// StateStopping means the runtime is performing the shutdown sequence.
	StateStopping InstanceState = "stopping"
	// StateStopped means the instance is fully shut down.
	StateStopped InstanceState = "stopped"
	// StateFailed means startup or the event stream failed with an error.
	StateFailed InstanceState = "failed"
)

type RequestCommand

type RequestCommand struct {
	EntityID       string
	Action         string
	ArgsJSON       string
	IdempotencyKey string
	Deadline       string
}

RequestCommand is the bounded payload for EffectRequestCommand.

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime manages Application Instances and their SDK service sessions. It is safe for concurrent use.

func NewRuntime

func NewRuntime(opts RuntimeOptions) (*Runtime, error)

NewRuntime builds a Runtime and validates the required options.

func (*Runtime) Close

func (r *Runtime) Close(ctx context.Context) error

Close shuts down the runtime and every instance. It is idempotent.

func (*Runtime) Describe

func (r *Runtime) Describe(tenantID, instanceID string) (*sdkapplication.ApplicationDescriptor, error)

Describe returns the plugin descriptor recorded during startup.

func (*Runtime) DispatchEvent

func (r *Runtime) DispatchEvent(ctx context.Context, tenantID, instanceID string, event *sdkapplication.ApplicationEvent) error

DispatchEvent enqueues one event for the instance's event stream. It blocks while the queue is full (backpressure) and returns on ctx cancellation or instance shutdown.

func (*Runtime) ExecuteEffects

func (r *Runtime) ExecuteEffects(ctx context.Context, tenantID, instanceID string, effects []Effect) (BatchResult, error)

ExecuteEffects runs a batch with fail-fast semantics. It returns the partial-success facts on failure so callers can observe which effects ran before the first failure.

func (*Runtime) GetInstance

func (r *Runtime) GetInstance(tenantID, instanceID string) (*Instance, error)

GetInstance returns a point-in-time snapshot of one instance.

func (*Runtime) HandleRequest

func (r *Runtime) HandleRequest(ctx context.Context, tenantID, instanceID string, req *sdkapplication.PluginHTTPRequest) (*sdkapplication.PluginHTTPResponse, error)

HandleRequest forwards an HTTP subroute request to the instance's plugin and injects the authoritative tenant/instance context.

func (*Runtime) Health

func (r *Runtime) Health(ctx context.Context, tenantID, instanceID string) (*sdkapplication.HealthResponse, error)

Health forwards a health probe to the instance's plugin.

func (*Runtime) RunJob

func (r *Runtime) RunJob(ctx context.Context, tenantID, instanceID string, req *sdkapplication.RunJobRequest) (*sdkapplication.RunJobResponse, error)

RunJob forwards a job invocation to the instance's plugin.

func (*Runtime) StartInstance

func (r *Runtime) StartInstance(ctx context.Context, spec InstanceSpec) (*Instance, error)

StartInstance performs Initialize, Describe, ConfigureInstance, SDK ValidateBinding and authoritative Binder validation, then starts the event stream. It never starts an instance whose binding is invalid or whose required capabilities are missing.

func (*Runtime) StopInstance

func (r *Runtime) StopInstance(ctx context.Context, tenantID, instanceID, reason string, grace time.Duration) error

StopInstance gracefully shuts one instance down.

func (*Runtime) StopInstanceStreamOnly added in v0.2.6

func (r *Runtime) StopInstanceStreamOnly(tenantID, instanceID string) error

StopInstanceStreamOnly 只拆除本实例的会话(事件流 + 运行记录),不发 进程级 Shutdown RPC。共享插件进程里停掉一个实例时必须用它:Shutdown RPC 会终止插件进程,对共享进程上的任一实例发送都会连带杀死全部兄弟实例。

type RuntimeOptions

type RuntimeOptions struct {
	// Dialer resolves the exact tenant/instance process for the requested
	// definition, including plugin identity and version.
	Dialer Dialer
	// Executor is the Core-provided EffectExecutor.
	Executor EffectExecutor
	// Logger receives structured diagnostics. A discard logger is used when nil.
	Logger *slog.Logger

	// EventQueueSize is the default per-instance event queue capacity.
	EventQueueSize int
	// ShutdownTimeout bounds one graceful instance shutdown.
	ShutdownTimeout time.Duration
	// Context is the parent context for all instance event loops.
	Context context.Context
}

RuntimeOptions configures a Runtime. Dialer and Executor are required.

type ScheduleJob

type ScheduleJob struct {
	ScheduleID  string
	Cron        string
	PayloadJSON string
}

ScheduleJob is the bounded payload for EffectScheduleJob.

type SendNotification

type SendNotification struct {
	Title    string
	Body     string
	Severity string
}

SendNotification is the bounded payload for EffectSendNotification.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL