Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion apis/tilebox/v1/id.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ edition = "2023";

package tilebox.v1;

import "buf/validate/validate.proto";

option features.field_presence = IMPLICIT;

// Bytes field (in message)
message ID {
bytes uuid = 1;
bytes uuid = 1 [(buf.validate.field).bytes = {
len: 16
not_in: [
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Nil UUID
Comment thread
corentinmusard marked this conversation as resolved.
]
}];
}
87 changes: 63 additions & 24 deletions apis/workflows/v1/automation.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ edition = "2023";

package workflows.v1;

import "buf/validate/validate.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "tilebox/v1/id.proto";
Expand All @@ -14,16 +15,28 @@ option features.field_presence = IMPLICIT;
// StorageType specifies a kind of storage bucket that we support.
enum StorageType {
STORAGE_TYPE_UNSPECIFIED = 0;
STORAGE_TYPE_GCS = 1; // Google Cloud Storage
STORAGE_TYPE_S3 = 2; // Amazon Web Services S3
STORAGE_TYPE_FS = 3; // Local filesystem
// Google Cloud Storage
STORAGE_TYPE_GCS = 1;
// Amazon Web Services S3
STORAGE_TYPE_S3 = 2;
// Local filesystem
STORAGE_TYPE_FS = 3;
}

// Storage location is some kind of storage that can contain data files or objects and be used as a trigger source.
message StorageLocation {
tilebox.v1.ID id = 1; // Unique identifier for the storage location
string location = 2; // A unique identifier for the storage location in the storage system
StorageType type = 3; // The type of the storage location, e.g. GCS, S3, FS
// Unique identifier for the storage location
tilebox.v1.ID id = 1 [(buf.validate.field).required = true];
// A unique identifier for the storage location in the storage system
string location = 2 [(buf.validate.field).string = {
min_bytes: 1
max_bytes: 512
}];
// The type of the storage location, e.g. GCS, S3, FS
StorageType type = 3 [(buf.validate.field).enum = {
defined_only: true
not_in: [0]
}];
}

// Buckets is a list of storage buckets
Expand All @@ -34,16 +47,33 @@ message StorageLocations {
// AutomationPrototype is a task prototype that can result in many submitted tasks. Task submissions are triggered by
// NRT triggers, such as bucket triggers or cron triggers.
message AutomationPrototype {
tilebox.v1.ID id = 1; // Unique identifier for the trigger
string name = 2; // A human-readable name for the trigger
TaskSubmission prototype = 3; // The task submission to trigger

repeated StorageEventTrigger storage_event_triggers = 4; // The storage event triggers that will trigger the task
repeated CronTrigger cron_triggers = 5; // The cron triggers that will trigger the task

bool disabled = 6; // Whether the automation is disabled (paused) or not.
option (buf.validate.message).oneof = {
fields: [
"storage_event_triggers",
"cron_triggers"
]
required: true
};

// Unique identifier for the trigger
tilebox.v1.ID id = 1;
// A human-readable name for the trigger
string name = 2 [(buf.validate.field).string = {
min_bytes: 1
max_bytes: 1024
}];
// The task submission to trigger
TaskSubmission prototype = 3;

// The storage event triggers that will trigger the task
repeated StorageEventTrigger storage_event_triggers = 4 [(buf.validate.field).repeated.max_items = 32];
// The cron triggers that will trigger the task
repeated CronTrigger cron_triggers = 5 [(buf.validate.field).repeated.max_items = 32];

// Whether the automation is disabled (paused) or not.
// the field is named disabled rather than enabled (with the semantics flipped) to make sure not setting the field at
// all results in the automation being enabled by default.
bool disabled = 6;
}

// Automations is a list of automations
Expand All @@ -54,15 +84,20 @@ message Automations {
// StorageEventTrigger is a trigger that will trigger a task submission when an object matching the glob pattern is
// created in a storage location.
message StorageEventTrigger {
tilebox.v1.ID id = 1; // Unique identifier for the trigger
StorageLocation storage_location = 2; // The storage location to watch for events
string glob_pattern = 3; // A glob pattern to match objects/files in the storage location
// Unique identifier for the trigger
tilebox.v1.ID id = 1;
// The storage location to watch for events
StorageLocation storage_location = 2;
// A glob pattern to match objects/files in the storage location
string glob_pattern = 3 [(buf.validate.field).string.min_bytes = 1];
}

// CronTrigger is a trigger that will trigger a task submission on a schedule.
message CronTrigger {
tilebox.v1.ID id = 1; // Unique identifier for the trigger
string schedule = 2; // A cron schedule for the trigger, e.g. "0 0 * * *" (every day at midnight)
// Unique identifier for the trigger
tilebox.v1.ID id = 1;
// A cron schedule for the trigger, e.g. "0 0 * * *" (every day at midnight)
string schedule = 2 [(buf.validate.field).string.min_bytes = 1];
}

// Automation is an actual submitted task that was triggered by a automation prototype.
Expand All @@ -71,7 +106,8 @@ message Automation {
// Details of the event that triggered the task. This is a serialized protobuf message. The type of the message
// depends on the type of the trigger, either StorageEventTriggerEvent or CronTriggerEvent.
bytes trigger_event = 1;
bytes args = 2; // Additional, user-defined arguments for the task, to be deserialized by the task itself
// Additional, user-defined arguments for the task, to be deserialized by the task itself
bytes args = 2;
}

// StorageEventType specifies the type of event that triggered the task.
Expand All @@ -82,21 +118,24 @@ enum StorageEventType {

// TriggeredStorageEvent contains the details of the concrete event that triggered a storage event trigger.
message TriggeredStorageEvent {
tilebox.v1.ID storage_location_id = 1; // The storage location that triggered the task
StorageEventType type = 2; // The type of the storage event, e.g. created
// The storage location that triggered the task
tilebox.v1.ID storage_location_id = 1;
// The type of the storage event, e.g. created
StorageEventType type = 2;
// The object that triggered the task, e.g. a file name in a directory or object name in a bucket
string location = 3;
}

// TriggeredCronEvent contains the details of a concrete event that triggered a cron trigger.
message TriggeredCronEvent {
google.protobuf.Timestamp trigger_time = 1; // The time the cron trigger fired
// The time the cron trigger fired
google.protobuf.Timestamp trigger_time = 1;
}

// DeleteAutomationRequest requests the deletion of an automation.
message DeleteAutomationRequest {
// The ID of the automation to delete.
tilebox.v1.ID automation_id = 1;
tilebox.v1.ID automation_id = 1 [(buf.validate.field).required = true];
// Whether to cancel all jobs that have been created by this automation.
bool cancel_jobs = 2;
}
Expand Down
85 changes: 60 additions & 25 deletions apis/workflows/v1/core.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ edition = "2023";

package workflows.v1;

import "buf/validate/validate.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "tilebox/v1/id.proto";
Expand All @@ -13,9 +14,13 @@ option features.field_presence = IMPLICIT;
// A cluster is a grouping of tasks that are related.
message Cluster {
// 1 is reserved for a potential id field in the future.
string slug = 2; // The unique slug of the cluster within the namespace.
string display_name = 3; // The display name of the cluster.
bool deletable = 4; // Where the cluster is deletable

// The unique slug of the cluster within the namespace.
string slug = 2;
// The display name of the cluster.
string display_name = 3;
// Where the cluster is deletable
bool deletable = 4;
}

// A job is a logical grouping of tasks that are related.
Expand All @@ -24,12 +29,18 @@ message Job {
string name = 2;
string trace_parent = 3;
reserved 4;
bool canceled = 5; // Whether the job has been canceled.
JobState state = 6; // The current state of the job.
google.protobuf.Timestamp submitted_at = 7; // The time the job was submitted.
google.protobuf.Timestamp started_at = 8; // The time the job started running.
repeated TaskSummary task_summaries = 9; // The task' summaries of the job.
tilebox.v1.ID automation_id = 10; // The automation that submitted the job.
// Whether the job has been canceled.
bool canceled = 5;
// The current state of the job.
JobState state = 6;
// The time the job was submitted.
google.protobuf.Timestamp submitted_at = 7;
// The time the job started running.
google.protobuf.Timestamp started_at = 8;
// The task' summaries of the job.
repeated TaskSummary task_summaries = 9;
// The automation that submitted the job.
tilebox.v1.ID automation_id = 10;
}

// The state of a job.
Expand All @@ -56,18 +67,26 @@ message TaskSummary {

// A task is a single unit of work.
message Task {
tilebox.v1.ID id = 1; // The id of the task instance. Contains the submission timestamp as the time part of the ULID.
// The id of the task instance. Contains the submission timestamp as the time part of the ULID.
tilebox.v1.ID id = 1;
// Unique identifier for the task. Used by runners to match tasks to specific functions.
TaskIdentifier identifier = 2;
TaskState state = 3; // The current state of the task.
bytes input = 4 [features.field_presence = EXPLICIT]; // The serialized input parameters for the task in the format that this task expects.
// The current state of the task.
TaskState state = 3;
// The serialized input parameters for the task in the format that this task expects.
bytes input = 4 [features.field_presence = EXPLICIT];
Comment thread
lukasbindreiter marked this conversation as resolved.
// Display is a human readable representation of the Task used for printing or visualizations
string display = 5 [features.field_presence = EXPLICIT];
Job job = 6; // The job that this task belongs to.
tilebox.v1.ID parent_id = 7; // The id of the parent task.
repeated tilebox.v1.ID depends_on = 8; // The ids of the tasks that this task depends on.
TaskLease lease = 9; // The lease of the task.
int64 retry_count = 10; // The number of times this task has been retried.
// The job that this task belongs to.
Job job = 6;
// The id of the parent task.
tilebox.v1.ID parent_id = 7;
// The ids of the tasks that this task depends on.
repeated tilebox.v1.ID depends_on = 8;
// The lease of the task.
TaskLease lease = 9;
// The number of times this task has been retried.
int64 retry_count = 10;
}

// The state of a task.
Expand All @@ -88,8 +107,16 @@ enum TaskState {

// An identifier for a task.
message TaskIdentifier {
string name = 1; // A unique name of a task (unique within a namespace).
string version = 2; // Version of the task.
// A unique name of a task (unique within a namespace).
string name = 1 [(buf.validate.field).string = {
min_bytes: 1
max_bytes: 256
}];
// Version of the task.
string version = 2 [(buf.validate.field).string = {
min_bytes: 1
pattern: "^v(\\d+)\\.(\\d+)$"
}];
}

// A list of tasks.
Expand All @@ -99,13 +126,21 @@ message Tasks {

// TaskSubmission is a message of a task that is just about to be submitted, either by submitting a job or as a subtask.
message TaskSubmission {
string cluster_slug = 1; // The cluster that this task should be run on
TaskIdentifier identifier = 2; // The task identifier
bytes input = 3; // The serialized task instance
string display = 4; // A human-readable description of the task
// The cluster that this task should be run on
string cluster_slug = 1;
// The task identifier
TaskIdentifier identifier = 2;
// The serialized task instance
bytes input = 3 [(buf.validate.field).bytes.max_len = 1024];
// A human-readable description of the task
string display = 4 [(buf.validate.field).string.min_bytes = 1];
// A list of indices, corresponding to tasks in the list of sub_tasks that this SubTask is part of.
repeated int64 dependencies = 5;
int64 max_retries = 6; // The maximum number of retries for this task.
repeated int64 dependencies = 5 [(buf.validate.field).repeated.items.int64 = {
gte: 0
lte: 63
}];
// The maximum number of retries for this task.
int64 max_retries = 6 [(buf.validate.field).int64.gte = 0];
}

// A lease for a task.
Expand Down
25 changes: 20 additions & 5 deletions apis/workflows/v1/diagram.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,28 @@ edition = "2023";

package workflows.v1;

import "buf/validate/validate.proto";

option features.field_presence = IMPLICIT;
Comment thread
lukasbindreiter marked this conversation as resolved.

// Request to render a diagram
message RenderDiagramRequest {
string diagram = 1; // The diagram graph in the D2 syntax
RenderOptions render_options = 2; // The options for rendering the diagram
// The diagram graph in the D2 syntax
string diagram = 1;
// The options for rendering the diagram
RenderOptions render_options = 2;
}

// Options for rendering the diagram
message RenderOptions {
// The layout to use for rendering the diagram: https://d2lang.com/tour/layouts/.
// "dagre" or "elk". Defaults to "dagre"
string layout = 1;
string layout = 1 [(buf.validate.field).string = {
in: [
"dagre",
"elk"
]
}];

// The D2 theme to use when rendering the diagram: https://d2lang.com/tour/themes/
int64 theme_id = 2 [features.field_presence = EXPLICIT];
Expand All @@ -28,8 +37,14 @@ message RenderOptions {
int64 padding = 4;

// Set explicitly the direction of the diagram: https://d2lang.com/tour/layouts/#direction.
// "up", "down", "right", "left".
string direction = 5;
string direction = 5 [(buf.validate.field).string = {
in: [
"up",
"down",
"right",
"left"
]
}];
}

// A rendered diagram
Expand Down
Loading