Eveline Anderson 830c3fe794 Rename worker 'clusters' to 'tags'
As it was decided that the name "tags" would be better for the clarity
of the feature, all files and code named "cluster" or "worker cluster"
have been removed and replaced with "tag" and "worker tag". This is only
a name change, no other features were touched.

This addresses part of #104204.

Reviewed-on: https://projects.blender.org/studio/flamenco/pulls/104223

As a note to anyone who already ran a pre-release version of Flamenco
and configured some worker clusters, with the help of an SQLite client
you can migrate the clusters to tags. First build Flamenco Manager and
start it, to create the new database schema. Then run these SQL queries
via an sqlite commandline client:

```sql
insert into worker_tags
    (id, created_at, updated_at, uuid, name, description)
  select id, created_at, updated_at, uuid, name, description
  from worker_clusters;

insert into worker_tag_membership (worker_tag_id, worker_id)
  select worker_cluster_id, worker_id from worker_cluster_membership;
```
2023-07-10 11:11:03 +02:00

141 lines
3.4 KiB
Go

package job_compilers
// SPDX-License-Identifier: GPL-3.0-or-later
import (
"errors"
"strings"
"time"
"github.com/dop251/goja"
"github.com/rs/zerolog/log"
"git.blender.org/flamenco/internal/uuid"
"git.blender.org/flamenco/pkg/api"
)
// Author allows scripts to author tasks and commands.
type Author struct {
runtime *goja.Runtime
}
type AuthoredJob struct {
JobID string
WorkerTagUUID string
Name string
JobType string
Priority int
Status api.JobStatus
Created time.Time
Settings JobSettings
Metadata JobMetadata
Storage JobStorageInfo
Tasks []AuthoredTask
}
type JobSettings map[string]interface{}
type JobMetadata map[string]string
type JobStorageInfo struct {
ShamanCheckoutID string
}
type AuthoredTask struct {
// Tasks already get their UUID in the authoring stage. This makes it simpler
// to store the dependencies, as the code doesn't have to worry about value
// vs. pointer semantics. Tasks can always be unambiguously referenced by
// their UUID.
UUID string
Name string
Type string
Priority int
Commands []AuthoredCommand
// Dependencies are tasks that need to be completed before this one can run.
Dependencies []*AuthoredTask `json:"omitempty" yaml:"omitempty"`
}
type AuthoredCommand struct {
Name string
Parameters AuthoredCommandParameters
}
type AuthoredCommandParameters map[string]interface{}
func (a *Author) Task(name string, taskType string) (*AuthoredTask, error) {
name = strings.TrimSpace(name)
taskType = strings.TrimSpace(taskType)
if name == "" {
return nil, errors.New("author.Task(name, type): name is required")
}
if taskType == "" {
return nil, errors.New("author.Task(name, type): type is required")
}
at := AuthoredTask{
uuid.New(),
name,
taskType,
50, // TODO: handle default priority somehow.
make([]AuthoredCommand, 0),
make([]*AuthoredTask, 0),
}
return &at, nil
}
func (a *Author) Command(cmdName string, parameters AuthoredCommandParameters) (*AuthoredCommand, error) {
ac := AuthoredCommand{cmdName, parameters}
return &ac, nil
}
// AuthorModule exports the Author module members to Goja.
func AuthorModule(r *goja.Runtime, module *goja.Object) {
a := &Author{
runtime: r,
}
obj := module.Get("exports").(*goja.Object)
mustExport := func(name string, value interface{}) {
err := obj.Set(name, value)
if err != nil {
log.Panic().Err(err).Msgf("unable to register '%s' in Goja 'author' module", name)
}
}
mustExport("Task", a.Task)
mustExport("Command", a.Command)
}
func (aj *AuthoredJob) AddTask(at *AuthoredTask) {
// Construct a task without dependencies, and a separate list of dependency
// UUIDs, just for logging. Simply logging `at` would recursively include all
// dependent tasks, which gets way too big to log.
if log.Debug().Enabled() {
deps := make([]string, len(at.Dependencies))
for i := range at.Dependencies {
deps[i] = at.Dependencies[i].UUID
}
logTask := *at
logTask.Dependencies = nil
log.Debug().
Str("job", aj.Name).
Strs("depTaskIDs", deps).
Interface("task", logTask).Msg("add task")
}
aj.Tasks = append(aj.Tasks, *at)
}
func (at *AuthoredTask) AddCommand(ac *AuthoredCommand) {
at.Commands = append(at.Commands, *ac)
}
func (at *AuthoredTask) AddDependency(dep *AuthoredTask) error {
// TODO: check for dependency cycles, return error if there.
at.Dependencies = append(at.Dependencies, dep)
return nil
}