task

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 13 Imported by: 0

README

task — async background task execution engine

task is the core of tasking: an embedding application submits a task — a unit of background work — and the engine reliably runs it, retries it on failure, times it out on a deadline, and cancels it on request, surviving process restarts and worker crashes.

tasking is a library embedded by other applications, and this package follows that posture: it orchestrates execution, but it does not own multi-tenancy, access control, or scheduler leader election — those belong to the embedding application (see DESIGN.md for the rationale).

For the design record — the Task vs. TaskExecution distinction, the state machines, the reliable-queue IPC model, the maintenance backstop, and the deferred pieces — see DESIGN.md. This README covers what the package provides and how to use it.

The core idea in one paragraph

A Task is what you submit; a TaskExecution is one attempt at running it. A task has one or more executions (extra ones come from retries), and workers process executions, not tasks. The engine is split into four components that never call each other directly — they exchange messages over Redis IPC queues and share a database. The database is the source of truth; every IPC message is a best-effort poke that lets a component act sooner than the periodic maintenance scan would. Lose a poke and work is delayed, never lost.

Components

Component What it does Lifecycle
Client Task API — define, cancel, query, and delete tasks construct, then call
Scheduler The state machine — owns every Task/TaskExecution transition Start / Stop; single-active
Receiver Per-worker-host consumer — claims executions, runs them, reports back Initialize → Start → Stop
Executor Worker pool for one queue — runs your TaskExecutionProcessor created started; Stop

You wire these together in your application, injecting the Redis-backed factory callbacks (common.NewRedisIPCMessage*, NewExecutor). Tests inject mocks instead.

Submitting work (Client)

client, err := task.NewClient(ctx, task.NewClientParams{
    Name:             "my-app",
    DefaultCreator:   "my-app",          // opaque; the notify routing key
    Persistence:      dbClient,          // db.Client
    Config:           clientConfig,      // models.TaskClientConfig
    Redis:            redisClient,       // goutilsRedis.Client
    IPCSenderFactory: common.NewRedisIPCMessageSend,
})

// Immediate one-shot
t, err := client.DefineAndRunImmediateOneShotTask(ctx, task.DefineTaskParams{
    Name:       "resize-image",          // matched to a registered processor
    Parameters: myParams,                // arbitrary, JSON-serialized
    Deadline:   &someDeadline,           // optional
}, nil /* or an active db.Database txn to join */)

// Scheduled one-shot
t, err = client.DefineAndRunScheduledOneShotTask(ctx, params, targetRunTime, nil)

// Cancel
err = client.CancelTask(ctx, t.ID, nil)

Error contract (inspect with errors.As):

  • models.PersistenceError — the task row was not created; nothing happened.
  • models.IPCMessageQueueError — the task row was created, but the scheduler poke failed. The task is not lost: the scheduler's maintenance sweep will pick it up. (Same contract for CancelTask.)

Querying work (Client)

The same client reads and deletes tasks, so an application never has to reach into the db package for ordinary lifecycle work:

// List — the filter is db.TaskQueryFilter, reused as-is
limit := 50
tasks, err := client.ListTasks(ctx, db.TaskQueryFilter{
    CommonListEntryQueryFilter: db.CommonListEntryQueryFilter{Limit: &limit},
    TaskNames:                  []string{"resize-image"},
    TaskStates:                 []models.TaskStateENUM{models.TaskStateFailed},
}, nil /* or an active db.Database txn to join */)

// Get one task, and the attempts it took
t, err := client.GetTask(ctx, taskID, nil)
attempts, err := client.ListTaskExecutions(ctx, taskID, db.TaskExecutionQueryFilter{}, nil)
attempt, err := client.GetTaskExecution(ctx, attempts[0].ID, nil)

// Delete — only once the task is terminal
err = client.DeleteTask(ctx, taskID, nil)

Creator scoping. Every read and delete above is scoped to the client's DefaultCreator. ListTasks fills in filters.Creators with it when the caller leaves that field empty; setting it explicitly overrides the scope. The single-entry methods (GetTask, DeleteTask, ListTaskExecutions, GetTaskExecution, and CancelTask) report another creator's task as goutils.NotFoundError — indistinguishable from a task that does not exist, so the client never discloses one it does not own. This also keeps the workflow engine's internal step-runner tasks out of your listings. A client constructed without a DefaultCreator has no scope to apply, so a ListTasks that does not carry an explicit Creators is rejected with a goutils.BadInputError rather than silently listing every creator's tasks.

Use db.Database directly if you genuinely need an unscoped, cross-creator view.

Deleting. Only a terminal task (COMPLETE / FAILED / TIMED_OUT / CANCELLED) may be deleted — cancel a live one first. A task that executed a workflow step is refused outright: it is that workflow's execution history and leaves only with its workflow. Both refusals are a goutils.ConsistencyError. Deleting a task cascades away its execution history.

Running work (Receiver + Executor + a processor)

Implement models.TaskExecutionProcessor for each task name and let the receiver drive it. Processors are supplied declaratively at construction — there is no runtime registration call. Each one is declared on its task, inside the queue that runs it, so the config states once which queue runs which task and with what. The receiver builds each queue's task name → processor map from that and hands it to the queue's Executor through your ExecutorFactory, which just forwards it to task.NewExecutor. The mapping is fixed at construction and immutable thereafter:

type resizeProcessor struct{}

func (p resizeProcessor) ProcessTaskExecution(
    ctx context.Context, taskEntry models.Task, exec models.TaskExecution,
) error {
    // do the work; honor ctx (it carries the execution's deadline)
    return nil // or an error → the execution FAILS (and may be retried)
}

// Queues and the tasks they run. Processor is excluded from serialization, so load the rest from
// your config file and fill the processors in here. A nil processor is rejected by NewExecutor.
receiverConfig := models.TaskReceiverConfig{
    Name:           "worker-01",
    SchedulerQueue: "task-scheduler",
    TaskQueues: []models.TaskQueueConfig{
        {
            Name:           "default-queue",
            Workers:        4,
            BufferRequests: 16,
            SupportedTasks: []models.TaskDefinition{
                {
                    TaskName:  "resize-image",
                    Retry:     models.RetryParam{InitialDelaySec: 5, MaxRetries: 3},
                    Processor: resizeProcessor{},
                },
            },
        },
    },
}

// The factory just forwards the per-queue processor map to NewExecutor.
executorFactory := func(
    parentCtx context.Context, queue string, workers, bufLen int,
    support task.ExecutorSupport, queueProcessors map[string]models.TaskExecutionProcessor,
) (task.Executor, error) {
    return task.NewExecutor(parentCtx, queue, workers, bufLen, support, queueProcessors)
}

receiver, err := task.NewReceiver(ctx, task.NewReceiverParams{
    Support:            task.ExecutorSupport{Persistence: dbClient /* OnCompleteCB set internally */},
    Config:             receiverConfig,
    ExecutorFactory:    executorFactory,
    Redis:              redisClient,
    IPCReceiverFactory: common.NewRedisIPCMessageReceive,
    IPCSenderFactory:   common.NewRedisIPCMessageSend,
})

// Reconcile buffered work, then start consuming:
if err := receiver.Initialize(ctx, nil); err != nil { /* ... */ }
if err := receiver.Start(ctx); err != nil { /* ... */ }
defer receiver.Stop(ctx)

Initialize must run before Start: it reconciles any execution requests left buffered by a previous run (re-queue, fail, or ignore, based on their DB state) so a crash doesn't strand work.

Running the scheduler

Exactly one scheduler runs against a given database (it is the sole writer of state):

scheduler, err := task.NewScheduler(ctx, task.NewSchedulerParams{
    Persistence:        dbClient,
    Config:             schedulerConfig,   // models.TaskSchedulerConfig
    Redis:              redisClient,
    IPCReceiverFactory: common.NewRedisIPCMessageReceive,
    IPCSenderFactory:   common.NewRedisIPCMessageSend,
})
if err := scheduler.Start(ctx); err != nil { /* ... */ }
defer scheduler.Stop(ctx)

Start first recovers any messages stranded in the scheduler queue buffer, then starts the worker, the maintenance timer, and the queue consumer.

Reliability model (what you can rely on)

  • At-least-once, self-healing execution. Work is driven by IPC pokes and a periodic maintenance sweep that re-scans the DB for anything a lost poke would strand. A dropped message delays work; it never loses it. Scheduled and retry executions fire from this sweep.
  • Crash-safe queues. IPC uses reliable Redis queues: a message stays buffered until the reader is done with it, and both consumers reconcile their buffers at startup.
  • Idempotent handlers. Duplicate or racing deliveries collapse to safe no-ops.
  • Poison messages are quarantined. Unprocessable messages become INVALID_TASK_IPC_MESSAGE audit events and are dropped — never a crash loop.
  • Retries with backoff. Failed executions retry per the task's policy (exponential, clamped); exhausting retries fails the task.
  • Engine failures don't retry. If the framework itself can't run an instance (ENGINE_FAILED), the task fails and an audit event is written for the app to review.

Configuration

All three components describe task queues with the same []models.TaskQueueConfig: each entry carries a queue's name, worker count, buffer length, and its SupportedTasks — the tasks that queue runs, each with its retry parameters and its processor.

  • models.TaskClientConfig — scheduler queue name; task queues (optional; read only for the per-task retry overrides).
  • models.TaskSchedulerConfig — maintenance interval (≥ 10s); scheduler queue name; task queues (read only for which queue serves which task name).
  • models.TaskReceiverConfig — receiver name; scheduler queue name; task queues, which it alone reads in full.

The task-name → queue mapping is the routing fabric: the scheduler dispatches an execution to the queue configured for its task name, and the receiver serving that queue runs it. Declaring a task inside its queue states that fabric once, so the three components cannot drift apart — the tradeoff being that the scheduler and client carry fields they never read (Workers, BufferRequests, Processor) but must still supply.

Queue names must be unique within a config, and task names unique across the whole config: a repeated name silently overwrites rather than merges, so it is rejected during validation.

Notifications

Every state change is recorded as a durable, creator-tagged SystemEventAudit row in the same transaction as the change. The notify package turns those rows into a best-effort Redis pub/sub notification stream. This package produces the events; it does not broadcast them.

Not yet supported

Periodic/recurring tasks (only immediate and scheduled one-shot exist today), multi-tenancy isolation, and scheduler leader election are out of scope here — see DESIGN.md §11.

Documentation

Overview

Package task - task processing engine

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client interface {
	/*
		DefineAndRunImmediateOneShotTask define and submit an immediate one-shot class task.

		The task entry is defined in a database transaction, then submitted to the scheduler for
		execution. The submit happens after the entry is persisted and is not part of that
		transaction. On error, inspect the returned error with `errors.As`: a
		`models.PersistenceError` means the database operation failed and no task was created; a
		`models.IPCMessageQueueError` means the task was created but could not be submitted to the
		scheduler.

			@param ctx context.Context - execution context
			@param params DefineTaskParams - the task definition parameters
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the newly defined task entry
	*/
	DefineAndRunImmediateOneShotTask(
		ctx context.Context,
		params DefineTaskParams,
		activeDBClient db.Database,
	) (models.Task, error)

	/*
		DefineAndRunScheduledOneShotTask define and submit a scheduled one-shot class task.

		The task entry is defined in a database transaction, then submitted to the scheduler for
		execution. The submit happens after the entry is persisted and is not part of that
		transaction. On error, inspect the returned error with `errors.As`: a
		`models.PersistenceError` means the database operation failed and no task was created; a
		`models.IPCMessageQueueError` means the task was created but could not be submitted to the
		scheduler.

			@param ctx context.Context - execution context
			@param params DefineTaskParams - the task definition parameters
			@param targetRuntime time.Time - target time when the task should run
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the newly defined task entry
	*/
	DefineAndRunScheduledOneShotTask(
		ctx context.Context,
		params DefineTaskParams,
		targetRuntime time.Time,
		activeDBClient db.Database,
	) (models.Task, error)

	/*
		DefineImmediateOneShotTask define (but do NOT submit) an immediate one-shot class task.

		This is the define-only half of DefineAndRunImmediateOneShotTask: it persists the task
		entry and returns it, without poking the scheduler. The caller is responsible for calling
		SubmitTask afterwards to actually dispatch it. This split lets a caller commit its own
		additional state between the define and the submit - e.g. the workflow scheduler links the
		step to this task and marks the step RUNNING in the same transaction, then submits only
		after that commits (state-before-poke). On error the returned error `errors.As` a
		`models.PersistenceError`: the DB define failed and no task was created.

			@param ctx context.Context - execution context
			@param params DefineTaskParams - the task definition parameters
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the newly defined task entry
	*/
	DefineImmediateOneShotTask(
		ctx context.Context,
		params DefineTaskParams,
		activeDBClient db.Database,
	) (models.Task, error)

	/*
		DefineScheduledOneShotTask define (but do NOT submit) a scheduled one-shot class task.

		The define-only half of DefineAndRunScheduledOneShotTask; see DefineImmediateOneShotTask
		for the define/submit split rationale. On error the returned error `errors.As` a
		`models.PersistenceError`: the DB define failed and no task was created.

			@param ctx context.Context - execution context
			@param params DefineTaskParams - the task definition parameters
			@param targetRuntime time.Time - target time when the task should run
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the newly defined task entry
	*/
	DefineScheduledOneShotTask(
		ctx context.Context,
		params DefineTaskParams,
		targetRuntime time.Time,
		activeDBClient db.Database,
	) (models.Task, error)

	/*
		SubmitTask submit an already-defined task to the scheduler for execution.

		This is the submit-only half of the DefineAndRun* methods: it pokes the scheduler queue for
		a task whose entry has already been persisted (via DefineImmediateOneShotTask /
		DefineScheduledOneShotTask). It runs no database work. A failed submit `errors.As` a
		`models.IPCMessageQueueError`: the task entry still exists and the scheduler's own
		maintenance will eventually pick it up, so a caller following state-before-poke may treat a
		submit failure as a lost poke rather than a lost task.

			@param ctx context.Context - execution context
			@param taskID string - ID of the already-defined task to submit
	*/
	SubmitTask(ctx context.Context, taskID string) error

	/*
		CancelTask request scheduler cancel a task

		The task is read in a database transaction to confirm it exists and that this client's
		creator owns it (see the Client doc), then a cancel request is submitted to the scheduler.
		The submit happens after the read and is not part of that transaction. On error, inspect the
		returned error with `errors.As`: a `models.PersistenceError` means the task could not be
		read; a `goutils.NotFoundError` means the task does not exist or belongs to another creator;
		a `models.IPCMessageQueueError` means the cancel request could not be submitted to the
		scheduler.

			@param ctx context.Context - execution context
			@param taskID string - ID of task to cancel
			@param activeDBClient db.Database - an existing open data base transaction to continue in
	*/
	CancelTask(ctx context.Context, taskID string, activeDBClient db.Database) error

	/*
		ListTasks list tasks belonging to this client's creator.

		The query is creator-scoped (see the Client doc): when `filters.Creators` is empty it is
		filled in with the client's DefaultCreator; when the caller sets it explicitly that set is
		used verbatim. A client with neither a DefaultCreator nor an explicit `filters.Creators`
		has no scope to apply and the call is rejected with a `goutils.BadInputError` rather than
		silently listing every creator's tasks. A failed read `errors.As` a
		`models.PersistenceError`.

			@param ctx context.Context - execution context
			@param filters db.TaskQueryFilter - query filtering conditions
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the matching task entries
	*/
	ListTasks(
		ctx context.Context, filters db.TaskQueryFilter, activeDBClient db.Database,
	) ([]models.Task, error)

	/*
		GetTask fetch a task by ID.

		Creator-scoped (see the Client doc): a task belonging to another creator `errors.As` a
		`goutils.NotFoundError`, indistinguishable from a task which does not exist. Any other
		read failure `errors.As` a `models.PersistenceError`.

			@param ctx context.Context - execution context
			@param taskID string - task ID
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the task entry
	*/
	GetTask(ctx context.Context, taskID string, activeDBClient db.Database) (models.Task, error)

	/*
		DeleteTask delete a task and its execution history.

		Creator-scoped (see the Client doc). Only a terminal task (COMPLETE / FAILED / TIMED_OUT /
		CANCELLED) may be deleted; a live one must be cancelled first. A task executing a workflow
		step is refused outright - it is the workflow's execution history and leaves only with its
		workflow. Both refusals `errors.As` a `goutils.ConsistencyError`; a task belonging to
		another creator `errors.As` a `goutils.NotFoundError`.

			@param ctx context.Context - execution context
			@param taskID string - task ID
			@param activeDBClient db.Database - an existing open data base transaction to continue in
	*/
	DeleteTask(ctx context.Context, taskID string, activeDBClient db.Database) error

	/*
		ListTaskExecutions list the execution instances (attempts) of one task.

		The parent task is read first and creator-scoped (see the Client doc), so a task belonging
		to another creator `errors.As` a `goutils.NotFoundError` and no execution history is
		disclosed. `filters.ParentTaskID` is not consulted; the parent is the `taskID` argument.

			@param ctx context.Context - execution context
			@param taskID string - the parent task ID
			@param filters db.TaskExecutionQueryFilter - query filtering conditions
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the matching task execution instances
	*/
	ListTaskExecutions(
		ctx context.Context,
		taskID string,
		filters db.TaskExecutionQueryFilter,
		activeDBClient db.Database,
	) ([]models.TaskExecution, error)

	/*
		GetTaskExecution fetch a task execution instance by ID.

		The instance is read, then its parent task is read and creator-scoped (see the Client
		doc); an instance whose parent belongs to another creator `errors.As` a
		`goutils.NotFoundError`.

			@param ctx context.Context - execution context
			@param instanceID string - task execution instance ID
			@param activeDBClient db.Database - an existing open data base transaction to continue in
			@return the task execution instance entry
	*/
	GetTaskExecution(
		ctx context.Context, instanceID string, activeDBClient db.Database,
	) (models.TaskExecution, error)
}

Client task engine client.

Creator scoping

Every read and delete on this interface is scoped to the client's creator: the per-call override where one is offered, otherwise the client's DefaultCreator. A task belonging to another creator is reported as not-found rather than as a permission failure, so the client never discloses the existence of a task it does not own. The scope also keeps the workflow engine's internal step-runner tasks (creator models.WorkflowExecutionTaskCreator) out of an application's view. `db.Database` remains the unscoped escape hatch for an application that genuinely needs to see across creators.

func NewClient

func NewClient(
	parentCtx context.Context, params NewClientParams,
) (Client, error)

NewClient define new task client

@param parentCtx context.Context - the parent execution context
@param params NewClientParams - parameters of the new client
@returns the new task client

type DefineTaskParams

type DefineTaskParams struct {
	// Name the task name. This is used to match the task with the appropriate task execution
	// processor to run the task.
	Name string `validate:"required"`
	// Parameters task processing parameters
	Parameters any
	// Metadata associated metadata
	Metadata any
	// Creator optional per-task creator override; nil uses the client's DefaultCreator. The
	// resolved value must be non-empty or the submit fails validation.
	Creator *string
	// Deadline if specified, the task must complete by this dead line.
	Deadline *time.Time
	// Retry optional per-task retry policy, carried in full (Factor included). When nil the client
	// resolves retry the usual way (the by-task-name policy from the client config, else the
	// default). When non-nil it is used verbatim, overriding both. This is the escape hatch for
	// callers whose retry policy is per-submission rather than a static property of the task name -
	// e.g. the workflow engine, where every step task shares the one name __EXECUTE_WORKFLOW_STEP__
	// but each step carries its own TaskRetryParameters.
	Retry *models.TaskRetryParameters
}

DefineTaskParams the per-task parameters shared by the task submission entry points. It carries everything needed to define a task except the execution context, the active DB transaction, and (for scheduled tasks) the target runtime, which are passed separately so this struct stays reusable across the immediate and scheduled variants.

type ExecutionCompleteCallback

type ExecutionCompleteCallback func(
	ctx context.Context, instanceID string, err error, timestamp time.Time,
)

ExecutionCompleteCallback callback to upon completing execution instance processing

type Executor

type Executor interface {
	/*
		ProcessExecutionInstance submit a new task execution instance for processing

			@param ctx context.Context - execution context
			@param instanceID string - execution instance ID
	*/
	ProcessExecutionInstance(ctx context.Context, instanceID string) error

	/*
		Stop the queue executor

			@param ctx context.Context - execution context
	*/
	Stop(ctx context.Context) error
}

Executor process task execution instances

func NewExecutor

func NewExecutor(
	parentCtx context.Context,
	taskQueue string,
	workerCount int,
	requestBufferLen int,
	support ExecutorSupport,
	processors map[string]models.TaskExecutionProcessor,
) (Executor, error)

NewExecutor define new task executor for a particular task queue

@param parentCtx context.Context - the parent execution context
@param taskQueue string - task queue being supported
@param workerCount int - number of workers to spawn
@param requestBufferLen int - number of execution requests to buffer for the worker pool
@param support ExecutorSupport - execution support package
@param processors map[string]models.TaskExecutionProcessor - task-name to processor mapping
    this executor supports. Fixed at construction; must contain no nil processors.
@returns new task executor

type ExecutorFactoryCB

type ExecutorFactoryCB func(
	parentCtx context.Context,
	taskQueue string,
	workerCount int,
	requestBufferLen int,
	support ExecutorSupport,
	processors map[string]models.TaskExecutionProcessor,
) (Executor, error)

ExecutorFactoryCB factory function signature for defining new task executors

type ExecutorSupport

type ExecutorSupport struct {
	// Persistence persistence client
	Persistence db.Client `validate:"required"`

	// OnCompleteCB completion callback
	OnCompleteCB ExecutionCompleteCallback `validate:"required"`
}

ExecutorSupport task executor support data

type IPCMsgReceiverFactoryCB

type IPCMsgReceiverFactoryCB func(
	ctx context.Context, queueName string, redis goutilsRedis.Client, reader string,
) (common.IPCMessageReceive, error)

IPCMsgReceiverFactoryCB factory function signature for defining new Redis based IPC message receivers

type IPCMsgSenderFactoryCB

type IPCMsgSenderFactoryCB func(
	ctx context.Context, queueName string, redis goutilsRedis.Client, sender string,
) (common.IPCMessageSend, error)

IPCMsgSenderFactoryCB factory function signature for defining new Redis based IPC message senders

type NewClientParams

type NewClientParams struct {
	// Name of the client
	Name string `validate:"required"`
	// DefaultCreator opaque creator identity stamped on tasks submitted through this
	// client when the submit call does not provide a per-task override. tasking never
	// interprets it; it is the notification routing key (see notify/DESIGN.md).
	DefaultCreator string
	// Persistence persistence client
	Persistence db.Client `validate:"required"`
	// Config task client config
	Config models.TaskClientConfig `validate:"required"`
	// Redis REDIS client
	Redis goutilsRedis.Client `validate:"required"`
	// IPCSenderFactory factory function to define Redis based IPC message senders
	IPCSenderFactory IPCMsgSenderFactoryCB `validate:"required"`
}

NewClientParams init parameters for a task client

type NewReceiverParams

type NewReceiverParams struct {
	// Persistence persistence client
	Persistence db.Client `validate:"required"`
	// Config task receiver config
	Config models.TaskReceiverConfig `validate:"required"`
	// ExecutorFactory factory function to define task executors
	ExecutorFactory ExecutorFactoryCB `validate:"required"`
	// Redis REDIS client
	Redis goutilsRedis.Client `validate:"required"`
	// IPCReceiverFactory factory function to define Redis based IPC message receivers
	IPCReceiverFactory IPCMsgReceiverFactoryCB `validate:"required"`
	// IPCSenderFactory factory function to define Redis based IPC message senders
	IPCSenderFactory IPCMsgSenderFactoryCB `validate:"required"`
	// OnFatal, when set, is invoked (at most once) when a queue-processing goroutine hits an
	// unrecoverable fault instead of terminating the process. reporter identifies the faulting
	// queue thread; err carries the cause (with code position in its chain); timestamp is when it
	// was detected. When nil, the default logs and calls log.Fatal, preserving prior behavior. The
	// goroutine exits after the callback runs.
	OnFatal models.OnFatalCB
}

NewReceiverParams init parameters for a task receiver

type NewSchedulerParams

type NewSchedulerParams struct {
	// Persistence persistence client
	Persistence db.Client `validate:"required"`
	// Config task scheduler config
	Config models.TaskSchedulerConfig `validate:"required"`
	// Redis REDIS client
	Redis goutilsRedis.Client `validate:"required"`
	// IPCReceiverFactory factory function to define Redis based IPC message receivers
	IPCReceiverFactory IPCMsgReceiverFactoryCB `validate:"required"`
	// IPCSenderFactory factory function to define Redis based IPC message senders
	IPCSenderFactory IPCMsgSenderFactoryCB `validate:"required"`
	// OnFatal, when set, is invoked (at most once) when the processing goroutine hits an
	// unrecoverable fault instead of terminating the process. reporter identifies the faulting
	// thread; err carries the cause (with code position in its chain); timestamp is when it was
	// detected. When nil, the default logs and calls log.Fatal, preserving prior behavior. The
	// goroutine exits after the callback runs.
	OnFatal models.OnFatalCB
}

NewSchedulerParams init parameters for a task scheduler

type Receiver

type Receiver interface {
	/*
		Initialize perform complete initialization of a task worker instance.
		It consist of several steps.

			@param ctx context.Context - execution context
			@param activeDBClient db.Database - active database client session
	*/
	Initialize(ctx context.Context, activeDBClient db.Database) error

	/*
		Start the task queue processing threads

			@param ctx context.Context - execution context
	*/
	Start(ctx context.Context) error

	/*
		Stop the task queue processing threads

			@param ctx context.Context - execution context
	*/
	Stop(ctx context.Context) error
}

Receiver receive task execution instances

func NewReceiver

func NewReceiver(
	parentCtx context.Context, params NewReceiverParams,
) (Receiver, error)

NewReceiver define new task receiver

@param parentCtx context.Context - the parent execution context
@param params NewReceiverParams - parameters of the task receiver
@returns new task receiver

type Scheduler

type Scheduler interface {
	/*
		Start the scheduler processing units

			@param ctx context.Context - execution context
	*/
	Start(ctx context.Context) error

	/*
		Stop the task scheduler processing units

			@param ctx context.Context - execution context
	*/
	Stop(ctx context.Context) error
}

Scheduler task scheduler

func NewScheduler

func NewScheduler(
	parentCtx context.Context,
	params NewSchedulerParams,
) (Scheduler, error)

NewScheduler define new scheduler

@param parentCtx context.Context - the parent execution context
@param params NewSchedulerParams - parameters of the task scheduler
@returns new task scheduler

Jump to

Keyboard shortcuts

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