Documentation
¶
Overview ¶
Package scriptbgdraft is the long draft run (#2117): an administrator can run_draft an unsaved script past the 60 seconds a draft is held to, up to the deployment's scripts.draft.max_seconds, for a flow a short draft cannot get through -- driving a slow web app, a long export. A draft longer than the inline wait runs in the background and answers with its run id at once; get_run reads its log and progress as it goes, and the draft's whole result once it ends. It still runs as the caller, writes only with allow_writes and is recorded for tests, exactly as an inline draft is.
A background draft is kept in script_draft_runs, so get_run answers it on any replica. The replica executing it writes what it has reported every few seconds; a draft whose replica stopped reads as failed once its deadline has passed.
Index ¶
- Constants
- Variables
- type Config
- type Execution
- type Launcher
- func (l *Launcher) Answer(ctx context.Context, id, caller string, admin bool) (out map[string]any, ok bool, err error)
- func (l *Launcher) Begin(ctx context.Context, owner, script string, limit time.Duration, exec Execution) (map[string]any, error)
- func (l *Launcher) Max() time.Duration
- func (l *Launcher) Plan(seconds int, admin bool) (limit time.Duration, background bool, err error)
- func (l *Launcher) Read(ctx context.Context, id, caller string, admin bool) (out *Run, ok bool, err error)
- func (l *Launcher) Start(ctx context.Context, owner, script string, limit time.Duration, exec Execution) (string, error)
- type Run
- type Store
Constants ¶
const ( StatusRunning = "running" StatusSucceeded = "succeeded" StatusFailed = "failed" )
Status values a background draft has.
const CeilingSeconds = 3600
CeilingSeconds is the most scripts.draft.max_seconds may be.
const DefaultSeconds = int(scriptrun.DraftTimeout / time.Second)
DefaultSeconds is a draft's time limit when the deployment sets none, which is also the longest a draft is waited on inline.
const MaxBackground = 4
MaxBackground is how many background drafts one replica runs at once. A draft is an administrator's, but each holds a run's memory for up to an hour, so the next one waits for a slot rather than piling on.
const MaxSecondsKey = "scripts.draft.max_seconds"
MaxSecondsKey names the setting in a refusal.
Variables ¶
var ErrBusy = fmt.Errorf("%d background drafts are already running on this replica; "+ "read one with get_run and start the next when it ends", MaxBackground)
ErrBusy is a background draft refused because the replica runs MaxBackground already.
var ErrNotFound = errors.New("no background draft has that id")
ErrNotFound is a run id no background draft has.
var ErrTooLong = errors.New("the draft time limit asked for is not available")
ErrTooLong is a timeout_seconds the caller may not be given.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// MaxSeconds is the longest an administrator's run_draft may ask for with
// timeout_seconds. Zero is DefaultSeconds, which no draft may pass.
MaxSeconds int `yaml:"max_seconds,omitempty"`
}
Config is the scripts.draft section.
func (Config) Decide ¶
Decide reads run_draft's timeout_seconds for a caller: the draft's time limit, and whether it runs in the background because it is longer than a draft is waited on. Zero is the default limit.
type Execution ¶
type Execution func(ctx context.Context, long scriptdraft.Long) (draft map[string]any, failed bool, err error)
Execution runs one draft with long's id, reporter and time limit, and returns what run_draft would have answered inline and whether the script failed. err is the platform's own failure.
type Launcher ¶
type Launcher struct {
// contains filtered or unexported fields
}
Launcher starts background drafts and reads them back.
func NewLauncher ¶
NewLauncher returns the launcher over store under cfg, or nil without a store: a deployment with nowhere to keep a background draft runs every draft inline, held to the default limit.
func (*Launcher) Answer ¶
func (l *Launcher) Answer(ctx context.Context, id, caller string, admin bool) (out map[string]any, ok bool, err error)
Answer renders get_run for a background draft. ok is false when the run id is not one, so get_run reads its runs as before; err is what the caller is told instead of an answer.
func (*Launcher) Begin ¶
func (l *Launcher) Begin(ctx context.Context, owner, script string, limit time.Duration, exec Execution) (map[string]any, error)
Begin starts a background draft and renders what run_draft answers: its run id and where to read it.
func (*Launcher) Read ¶
func (l *Launcher) Read(ctx context.Context, id, caller string, admin bool) (out *Run, ok bool, err error)
Read answers get_run for a background draft: ok is false when id is not one, so get_run reads its runs as before. A draft is its caller's and an administrator's, as an inline draft's answer is the caller's alone.
type Run ¶
type Run struct {
ID string `json:"run_id"`
Owner string `json:"-"`
Script string `json:"script"`
Status string `json:"status"`
Log string `json:"log"`
Progress json.RawMessage `json:"progress,omitempty"`
Error string `json:"error,omitempty"`
Draft json.RawMessage `json:"draft,omitempty"`
StartedAt time.Time `json:"started_at"`
Deadline time.Time `json:"deadline"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
// ReportedAt is when the executing replica last wrote the draft.
ReportedAt time.Time `json:"-"`
}
Run is one background draft as get_run reads it.