Documentation
¶
Index ¶
Constants ¶
const ( // TypeNone ... TypeNone = "" // TypeSync ... TypeSync = "sync" // TypeAsync ... TypeAsync = "async" )
const ( // FormatDefault ... FormatDefault = "default" // FormatHTTP ... FormatHTTP = "http" )
Variables ¶
var ( ErrAppsAlreadyExists = errors.New("App already exists") ErrAppsCreate = errors.New("Could not create app") ErrAppsGet = errors.New("Could not get app from datastore") ErrAppsList = errors.New("Could not list apps from datastore") ErrAppsMissingNew = errors.New("Missing new application") ErrAppsNameImmutable = errors.New("Could not update app - name is immutable") ErrAppsNotFound = errors.New("App not found") ErrAppsNothingToUpdate = errors.New("Nothing to update") ErrAppsRemoving = errors.New("Could not remove app from datastore") ErrAppsUpdate = errors.New("Could not update app") ErrDeleteAppsWithRoutes = errors.New("Cannot remove apps with routes") ErrUsableImage = errors.New("Image not found") )
var ( ErrAppsValidationMissingName = errors.New("Missing app name") ErrAppsValidationTooLongName = fmt.Errorf("App name must be %v characters or less", maxAppName) ErrAppsValidationInvalidName = errors.New("Invalid app name") )
var ( ErrDatastoreEmptyAppName = errors.New("Missing app name") ErrDatastoreEmptyRoutePath = errors.New("Missing route name") ErrDatastoreEmptyApp = errors.New("Missing app") ErrDatastoreEmptyRoute = errors.New("Missing route") ErrDatastoreEmptyKey = errors.New("Missing key") )
var ( ErrInvalidPayload = errors.New("Invalid payload") ErrRoutesAlreadyExists = errors.New("Route already exists") ErrRoutesCreate = errors.New("Could not create route") ErrRoutesGet = errors.New("Could not get route from datastore") ErrRoutesList = errors.New("Could not list routes from datastore") ErrRoutesMissingNew = errors.New("Missing new route") ErrRoutesNotFound = errors.New("Route not found") ErrRoutesPathImmutable = errors.New("Could not update route - path is immutable") ErrRoutesRemoving = errors.New("Could not remove route from datastore") ErrRoutesUpdate = errors.New("Could not update route") )
var ( ErrRoutesValidationFoundDynamicURL = errors.New("Dynamic URL is not allowed") ErrRoutesValidationInvalidPath = errors.New("Invalid Path format") ErrRoutesValidationInvalidType = errors.New("Invalid route Type") ErrRoutesValidationInvalidFormat = errors.New("Invalid route Format") ErrRoutesValidationMissingAppName = errors.New("Missing route AppName") ErrRoutesValidationMissingImage = errors.New("Missing route Image") ErrRoutesValidationMissingName = errors.New("Missing route Name") ErrRoutesValidationMissingPath = errors.New("Missing route Path") ErrRoutesValidationMissingType = errors.New("Missing route Type") ErrRoutesValidationPathMalformed = errors.New("Path malformed") ErrRoutesValidationNegativeTimeout = errors.New("Negative timeout") ErrRoutesValidationNegativeIdleTimeout = errors.New("Negative idle timeout") ErrRoutesValidationNegativeMaxConcurrency = errors.New("Negative MaxConcurrency") )
var ( ErrRunnerRouteNotFound = errors.New("Route not found on that application") ErrRunnerInvalidPayload = errors.New("Invalid payload") ErrRunnerRunRoute = errors.New("Couldn't run this route in the job server") ErrRunnerAPICantConnect = errors.New("Couldn`t connect to the job server API") ErrRunnerAPICreateJob = errors.New("Could not create a job in job server") ErrRunnerInvalidResponse = errors.New("Invalid response") ErrRunnerTimeout = errors.New("Timed out") )
var (
ErrInvalidJSON = errors.New("Invalid JSON")
)
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
Name string `json:"name"`
Routes Routes `json:"routes,omitempty"`
Config `json:"config"`
}
func (*App) UpdateConfig ¶
UpdateConfig adds entries from patch to a.Config, and removes entries with empty values.
type AppWrapper ¶
type AppWrapper struct {
App *App `json:"app"`
}
func (*AppWrapper) Validate ¶
func (m *AppWrapper) Validate() error
type Complete ¶
type Complete struct {
/* Time when task was completed. Always in UTC.
*/
CompletedAt strfmt.DateTime `json:"completed_at,omitempty"`
/* Error message, if status=error. Only used by the /error endpoint.
*/
Error string `json:"error,omitempty"`
/* Machine readable reason failure, if status=error. Only used by the /error endpoint.
*/
Reason string `json:"reason,omitempty"`
}
Complete complete
swagger:model Complete
type Datastore ¶
type Datastore interface {
// GetApp gets an App by name.
// Returns ErrDatastoreEmptyAppName for empty appName.
// Returns ErrAppsNotFound if no app is found.
GetApp(ctx context.Context, appName string) (*App, error)
// GetApps gets a slice of Apps, optionally filtered by name.
// Missing filter or empty name will match all Apps.
GetApps(ctx context.Context, filter *AppFilter) ([]*App, error)
// InsertApp inserts an App. Returns ErrDatastoreEmptyApp when app is nil, and
// ErrDatastoreEmptyAppName when app.Name is empty.
// Returns ErrAppsAlreadyExists if an App by the same name already exists.
InsertApp(ctx context.Context, app *App) (*App, error)
// UpdateApp updates an App's Config. Returns ErrDatastoreEmptyApp when app is nil, and
// ErrDatastoreEmptyAppName when app.Name is empty.
// Returns ErrAppsNotFound if an App is not found.
UpdateApp(ctx context.Context, app *App) (*App, error)
// RemoveApp removes the App named appName. Returns ErrDatastoreEmptyAppName if appName is empty.
// Returns ErrAppsNotFound if an App is not found.
//TODO remove routes automatically? #528
RemoveApp(ctx context.Context, appName string) error
// GetRoute looks up a matching Route for appName and the literal request route routePath.
// Returns ErrDatastoreEmptyAppName when appName is empty, and ErrDatastoreEmptyRoutePath when
// routePath is empty.
// Returns ErrRoutesNotFound when no matching route is found.
GetRoute(ctx context.Context, appName, routePath string) (*Route, error)
// GetRoutes gets a slice of Routes, optionally filtered by filter.
GetRoutes(ctx context.Context, filter *RouteFilter) (routes []*Route, err error)
// GetRoutesByApp gets a slice of routes for a appName, optionally filtering on filter (filter.AppName is ignored).
// Returns ErrDatastoreEmptyAppName if appName is empty.
GetRoutesByApp(ctx context.Context, appName string, filter *RouteFilter) (routes []*Route, err error)
// InsertRoute inserts a route. Returns ErrDatastoreEmptyRoute when route is nil, and ErrDatastoreEmptyAppName
// or ErrDatastoreEmptyRoutePath for empty AppName or Path.
// Returns ErrRoutesAlreadyExists if the exact route.Path already exists, or ErrRoutesCreate if a conflicting
// route already exists.
InsertRoute(ctx context.Context, route *Route) (*Route, error)
// UpdateRoute updates route's Config and Header fields. Returns ErrDatastoreEmptyRoute when route is nil, and
// ErrDatastoreEmptyAppName or ErrDatastoreEmptyRoutePath for empty AppName or Path.
UpdateRoute(ctx context.Context, route *Route) (*Route, error)
// RemoveRoute removes a route. Returns ErrDatastoreEmptyAppName when appName is empty, and
// ErrDatastoreEmptyRoutePath when routePath is empty. Returns ErrRoutesNotFound when no route exists.
RemoveRoute(ctx context.Context, appName, routePath string) error
// The following provide a generic key value store for arbitrary data, can be used by extensions to store extra data
// todo: should we namespace these by app? Then when an app is deleted, it can delete any of this extra data too.
Put(context.Context, []byte, []byte) error
Get(context.Context, []byte) ([]byte, error)
}
type ErrorBody ¶
type IDStatus ¶
type IDStatus struct {
/* Unique identifier representing a specific task.
Read Only: true
*/
ID string `json:"id,omitempty"`
/* States and valid transitions.
+---------+
+---------> delayed <----------------+
+----+----+ |
| |
| |
+----v----+ |
+---------> queued <----------------+
+----+----+ *
| *
| retry * creates new task
+----v----+ *
| running | *
+--+-+-+--+ |
+---------|-|-|-----+-------------+
+---|---------+ | +-----|---------+ |
| | | | | |
+-----v---^-+ +--v-------^+ +--v---^-+
| success | | cancelled | | error |
+-----------+ +-----------+ +--------+
* delayed - has a delay.
* queued - Ready to be consumed when it's turn comes.
* running - Currently consumed by a runner which will attempt to process it.
* success - (or complete? success/error is common javascript terminology)
* error - Something went wrong. In this case more information can be obtained
by inspecting the "reason" field.
- timeout
- killed - forcibly killed by worker due to resource restrictions or access
violations.
- bad_exit - exited with non-zero status due to program termination/crash.
* cancelled - cancelled via API. More information in the reason field.
- client_request - Request was cancelled by a client.
Read Only: true
*/
Status string `json:"status,omitempty"`
}
IDStatus Id status
swagger:model IdStatus
type MessageQueue ¶
type MessageQueue interface {
// Push a Task onto the queue. If any error is returned, the Task SHOULD not be
// queued. Note that this does not completely avoid double queueing, that is
// OK, Titan will perform a check against the datastore after a dequeue.
//
// If the job's Delay value is > 0, the job should NOT be enqueued. The job
// should only be available in the queue after at least Delay seconds have
// elapsed. No ordering is required among multiple jobs queued with similar
// delays. That is, if jobs {A, C} are queued at t seconds, both with Delay
// = 5 seconds, and the same priority, then they may be available on the
// queue as [C, A] or [A, C].
Push(context.Context, *Task) (*Task, error)
// Remove a job from the front of the queue, reserve it for a timeout and
// return it. MQ implementations MUST NOT lose jobs in case of errors. That
// is, in case of reservation failure, it should be possible to retrieve the
// job on a future reservation.
Reserve(context.Context) (*Task, error)
// If a reservation is pending, consider it acknowledged and delete it. If
// the job does not have an outstanding reservation, error. If a job did not
// exist, succeed.
Delete(context.Context, *Task) error
}
When a job is required to be restored to the queue, it should maintain it's approximate order in the queue. That is, for jobs [A, B, C], with A being the head of the queue: Reserve() leads to A being passed to a consumer, and timeout started. Next Reserve() leads to B being dequeued. This consumer finishes running the task, leading to Delete() being called. B is now permanently erased from the queue. A's timeout occurs before the job is finished. At this point the ordering should be [A, C] and not [C, A].
type NewTask ¶
type NewTask struct {
/* Number of seconds to wait before queueing the task for consumption for the first time. Must be a positive integer. Tasks with a delay start in state "delayed" and transition to "running" after delay seconds.
*/
Delay int32 `json:"delay,omitempty"`
/* Name of Docker image to use. This is optional and can be used to override the image defined at the route level.
Required: true
*/
Image *string `json:"image"`
/* "Number of automatic retries this task is allowed. A retry will be attempted if a task fails. Max 25. Automatic retries are performed by titan when a task reaches a failed state and has `max_retries` > 0. A retry is performed by queueing a new task with the same image id and payload. The new task's max_retries is one less than the original. The new task's `retry_of` field is set to the original Task ID. The old task's `retry_at` field is set to the new Task's ID. Titan will delay the new task for retries_delay seconds before queueing it. Cancelled or successful tasks are never automatically retried."
*/
MaxRetries int32 `json:"max_retries,omitempty"`
/* Payload for the task. This is what you pass into each task to make it do something.
*/
Payload string `json:"payload,omitempty"`
/* Priority of the task. Higher has more priority. 3 levels from 0-2. Tasks at same priority are processed in FIFO order.
Required: true
*/
Priority *int32 `json:"priority"`
/* Time in seconds to wait before retrying the task. Must be a non-negative integer.
*/
RetriesDelay *int32 `json:"retries_delay,omitempty"`
/* Maximum runtime in seconds. If a consumer retrieves the
task, but does not change it's status within timeout seconds, the task
is considered failed, with reason timeout (Titan may allow a small
grace period). The consumer should also kill the task after timeout
seconds. If a consumer tries to change status after Titan has already
timed out the task, the consumer will be ignored.
*/
Timeout *int32 `json:"timeout,omitempty"`
/* Hot function idle timeout in seconds before termination.
*/
IdleTimeout *int32 `json:"idle_timeout,omitempty"`
}
NewTask new task
swagger:model NewTask
type Reason ¶
type Reason string
Reason Machine usable reason for job being in this state. Valid values for error status are `timeout | killed | bad_exit`. Valid values for cancelled status are `client_request`. For everything else, this is undefined.
swagger:model Reason
type Route ¶
type Route struct {
AppName string `json:"app_name"`
Path string `json:"path"`
Image string `json:"image"`
Memory uint64 `json:"memory"`
Headers http.Header `json:"headers"`
Type string `json:"type"`
Format string `json:"format"`
MaxConcurrency int `json:"max_concurrency"`
Timeout int32 `json:"timeout"`
IdleTimeout int32 `json:"idle_timeout"`
Config `json:"config"`
}
func (*Route) SetDefaults ¶
func (r *Route) SetDefaults()
SetDefaults sets zeroed field to defaults.
type RouteFilter ¶
TODO are these sql LIKE queries? or strict matches?
type RouteWrapper ¶
type RouteWrapper struct {
Route *Route `json:"route"`
}
func (*RouteWrapper) Validate ¶
func (m *RouteWrapper) Validate(skipZero bool) error
type Start ¶
type Start struct {
/* Time when task started execution. Always in UTC.
*/
StartedAt strfmt.DateTime `json:"started_at,omitempty"`
}
Start start
swagger:model Start
type Task ¶
type Task struct {
NewTask
IDStatus
/* Time when task completed, whether it was successul or failed. Always in UTC.
*/
CompletedAt strfmt.DateTime `json:"completed_at,omitempty"`
/* Time when task was submitted. Always in UTC.
Read Only: true
*/
CreatedAt strfmt.DateTime `json:"created_at,omitempty"`
/* Env vars for the task. Comes from the ones set on the Route.
*/
EnvVars map[string]string `json:"env_vars,omitempty"`
/* The error message, if status is 'error'. This is errors due to things outside the task itself. Errors from user code will be found in the log.
*/
Error string `json:"error,omitempty"`
/* App this task belongs to.
Read Only: true
*/
AppName string `json:"app_name,omitempty"`
Path string `json:"path"`
/* Machine usable reason for task being in this state.
Valid values for error status are `timeout | killed | bad_exit`.
Valid values for cancelled status are `client_request`.
For everything else, this is undefined.
*/
Reason string `json:"reason,omitempty"`
/* If this field is set, then this task was retried by the task referenced in this field.
Read Only: true
*/
RetryAt string `json:"retry_at,omitempty"`
/* If this field is set, then this task is a retry of the ID in this field.
Read Only: true
*/
RetryOf string `json:"retry_of,omitempty"`
/* Time when task started execution. Always in UTC.
*/
StartedAt strfmt.DateTime `json:"started_at,omitempty"`
}
Task task
swagger:model Task