feat(11-01): run job workers in serve and queue:work, add queue:clear
- Manager gains the apparatus JobManager surface: StartJob, UpdateJobState, UpdateMetadata, FailJob, CancelJob (is_canceled + STOPPED + River JobCancel), StopJob (STOPPED only), CheckIfCanceled and GetMetadata, all raw column writes so updated_at is untouched - serve starts the in-process worker unless queue.work_in_serve is false and stops it on shutdown; an app without jobs gets an idle worker - queue:work runs a foreground worker with repeatable --queue filters; queue:clear deletes available, scheduled and retryable jobs of one queue - the generated main appends conga.RuntimeCommands; summer delegates queue:work and queue:clear; make:job scaffolds a conga.Job
This commit is contained in:
@@ -192,7 +192,8 @@ func MakeCommand(ctx context.Context, startDir, pluginID, name string) (Artifact
|
||||
return ArtifactResult{PluginDir: plugin.Dir, Files: []string{path}, Hint: plugin.Hint}, nil
|
||||
}
|
||||
|
||||
// MakeJob writes a pact.Job stub without importing River.
|
||||
// MakeJob writes a typed job wrapped in conga.Job; the plugin never
|
||||
// imports River.
|
||||
func MakeJob(ctx context.Context, startDir, pluginID, name string) (ArtifactResult, error) {
|
||||
plugin, err := resolvePlugin(startDir, pluginID)
|
||||
if err != nil {
|
||||
@@ -210,10 +211,9 @@ func MakeJob(ctx context.Context, startDir, pluginID, name string) (ArtifactResu
|
||||
return ArtifactResult{}, err
|
||||
}
|
||||
src, err := renderStub("job.go", artifactData{
|
||||
Ident: name,
|
||||
Func: fn,
|
||||
Worker: unexportedIdent(name) + "Job",
|
||||
Kind: plugin.ID + "." + toSnake(name),
|
||||
Ident: name,
|
||||
Func: fn,
|
||||
Kind: plugin.ID + "." + toSnake(name),
|
||||
})
|
||||
if err != nil {
|
||||
return ArtifactResult{}, err
|
||||
|
||||
@@ -89,6 +89,7 @@ func generateMain(m Manifest) ([]byte, error) {
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/bonfire\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/cabana\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/compass\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/conga\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/lagoon\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/pact\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/party\"\n")
|
||||
@@ -111,6 +112,7 @@ func generateMain(m Manifest) ([]byte, error) {
|
||||
b.WriteString("\t\treturn err\n")
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("\tcommands := lagoon.RuntimeCommands(app, plugins)\n")
|
||||
b.WriteString("\tcommands = append(commands, conga.RuntimeCommands(app, plugins)...)\n")
|
||||
b.WriteString("\tcommands = append(commands, surf.ServeCommand(app, plugins))\n")
|
||||
b.WriteString("\tcommands = append(commands, surf.RouteListCommand(app, plugins))\n")
|
||||
b.WriteString("\tcommands = append(commands, cabana.RuntimeCommands(app)...)\n")
|
||||
|
||||
@@ -128,6 +128,20 @@ func TestGenerateMainRegistersCabanaRuntimeCommands(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateMainRegistersCongaRuntimeCommands(t *testing.T) {
|
||||
mainSrc, err := generateMain(Manifest{Module: "example.com/app", Binary: "hello"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := []byte("commands = append(commands, conga.RuntimeCommands(app, plugins)...)")
|
||||
if n := bytes.Count(mainSrc, line); n != 1 {
|
||||
t.Fatalf("conga.RuntimeCommands line count = %d, want 1\n%s", n, mainSrc)
|
||||
}
|
||||
if !bytes.Contains(mainSrc, []byte(`"git.golem15.com/golem15/summercms/modules/conga"`)) {
|
||||
t.Fatalf("generated main does not import conga:\n%s", mainSrc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteIfChangedSkipsIdenticalBytes(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "out.go")
|
||||
@@ -696,9 +710,9 @@ func TestScaffoldAllArtifacts(t *testing.T) {
|
||||
for _, want := range []string{
|
||||
"func (ReindexArgs) Kind()",
|
||||
`Kind() string { return "golem15.demo.reindex" }`,
|
||||
"func (reindexJob) Work(",
|
||||
"unexpected args type",
|
||||
"func ReindexJob()",
|
||||
"func ReindexJob() pact.Job",
|
||||
"conga.Job(func(ctx context.Context, args ReindexArgs) error",
|
||||
`"git.golem15.com/golem15/summercms/modules/conga"`,
|
||||
} {
|
||||
if !bytes.Contains(jobSrc, []byte(want)) {
|
||||
t.Fatalf("job.go missing %s:\n%s", want, jobSrc)
|
||||
|
||||
@@ -66,8 +66,8 @@ package jobs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/conga"
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
)
|
||||
|
||||
@@ -76,17 +76,12 @@ type {{.Ident}}Args struct{}
|
||||
|
||||
func ({{.Ident}}Args) Kind() string { return {{printf "%q" .Kind}} }
|
||||
|
||||
type {{.Worker}} struct{}
|
||||
|
||||
func ({{.Worker}}) Work(ctx context.Context, args pact.JobArgs) error {
|
||||
if _, ok := args.({{.Ident}}Args); !ok {
|
||||
return fmt.Errorf("jobs: unexpected args type %T", args)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// {{.Func}} returns the {{.Kind}} job.
|
||||
func {{.Func}}() pact.Job { return {{.Worker}}{} }
|
||||
func {{.Func}}() pact.Job {
|
||||
return conga.Job(func(ctx context.Context, args {{.Ident}}Args) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "admin_controller.go"}}// Code generated by summer make. DO NOT EDIT.
|
||||
|
||||
Reference in New Issue
Block a user