Files
fn-serverless/docs/swagger.yml
Reed Allman 9edacae928 clean up hotf(x) concurrency, rm max c
this patch gets rid of max concurrency for functions altogether, as discussed,
since it will be challenging to support across functions nodes. as a result of
doing so, the previous version of functions would fall over when offered 1000
functions, so there was some work needed in order to push this through.
further work is necessary as docker basically falls over when trying to start
enough containers at the same time, and with this patch essentially every
function can scale infinitely. it seems like we could add some kind of
adaptive restrictions based on task run length and configured wait time so
that fast running functions will line up to run in a hot container instead of
them all creating new hot containers.

this patch takes a first cut at whacking out some of the insanity that was the
previous concurrency model, which was problematic in that it limited
concurrency significantly across all functions since every task went through
the same unbuffered channel, which could create blocking issues for all
functions if the channel is not picked off fast enough (it's not apparent that
this was impossible in the previous implementation). in any event, each
request has a goroutine already, there's no reason not to use it. not too hard
to wrap a map in a lock, not sure what the benefits were (added insanity?) in effect
this is marginally easier to understand and less insane (marginally). after
getting rid of max c this adds a blocking mechanism for the first invocation
of any function so that all other hot functions will wait on the first one to
finish to avoid a herd issue (was making docker die...) -- this could be
slightly improved, but works in a pinch. reduced some memory usage by having
redundant maps of htfnsvr's and task.Requests (by a factor of 2!). cleaned up
some of the protocol stuff, need to clean this up further. anyway, it's a
first cut. have another patch that rewrites all of it but was getting into
rabbit hole territory, would be happy to oblige if anybody else has problems
understanding this rat's nest of channels. there is a good bit of work left to
make this prod ready (regardless of removing max c).

a warning that this will break the db schemas, didn't put the effort in to add
migration stuff since this isn't deployed anywhere in prod...

TODO need to clean out the htfnmgr bucket with LRU
TODO need to clean up runner interface
TODO need to unify the task running paths across protocols
TODO need to move the ram checking stuff into worker for noted reasons
TODO need better elasticity of hot f(x) containers
2017-06-05 20:04:13 -07:00

653 lines
17 KiB
YAML

# This is the Oracle Functions API spec
# If you make changes here, remember to run `go generate` in api/models/ and
# api/server to make sure you use the changes.
swagger: '2.0'
info:
title: Oracle Functions
description: The open source serverless platform.
version: "0.1.30"
# the domain of the service
host: "127.0.0.1:8080"
# array of all schemes that your API supports
schemes:
- https
- http
# will be prefixed to all paths
basePath: /v1
consumes:
- application/json
produces:
- application/json
paths:
/version:
get:
summary: "Get daemon version."
tags:
- Version
responses:
200:
description: Daemon version.
schema:
$ref: '#/definitions/Version'
/apps:
get:
summary: "Get all app names."
description: "Get a list of all the apps in the system."
tags:
- Apps
responses:
200:
description: List of apps.
schema:
$ref: '#/definitions/AppsWrapper'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
post:
summary: "Post new app"
description: "Insert a new app"
tags:
- Apps
parameters:
- name: body
in: body
description: App to post.
required: true
schema:
$ref: '#/definitions/AppWrapper'
responses:
200:
description: App details and stats.
schema:
$ref: '#/definitions/AppWrapper'
400:
description: Parameters are missing or invalid.
schema:
$ref: '#/definitions/Error'
409:
description: App already exists.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/apps/{app}:
delete:
summary: "Delete an app."
description: "Delete an app."
tags:
- Apps
parameters:
- name: app
in: path
description: Name of the app.
required: true
type: string
responses:
200:
description: Apps successfully deleted.
404:
description: App does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
summary: "Get information for a app."
description: "This gives more details about a app, such as statistics."
tags:
- Apps
parameters:
- name: app
in: path
description: name of the app.
required: true
type: string
responses:
200:
description: App details and stats.
schema:
$ref: '#/definitions/AppWrapper'
404:
description: App does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
patch:
summary: "Updates an app."
description: "You can set app level settings here. "
tags:
- Apps
parameters:
- name: app
in: path
description: name of the app.
required: true
type: string
- name: body
in: body
description: App to post.
required: true
schema:
$ref: '#/definitions/AppWrapper'
responses:
200:
description: App details and stats.
schema:
$ref: '#/definitions/AppWrapper'
400:
description: Parameters are missing or invalid.
schema:
$ref: '#/definitions/Error'
404:
description: App does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/apps/{app}/routes:
post:
summary: Create new Route
description: Create a new route in an app, if app doesn't exists, it creates the app
tags:
- Routes
parameters:
- name: app
in: path
description: name of the app.
required: true
type: string
- name: body
in: body
description: One route to post.
required: true
schema:
$ref: '#/definitions/RouteWrapper'
responses:
200:
description: Route created
schema:
$ref: '#/definitions/RouteWrapper'
400:
description: Invalid route due to parameters being missing or invalid.
schema:
$ref: '#/definitions/Error'
409:
description: Route already exists.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
summary: Get route list by app name.
description: This will list routes for a particular app.
tags:
- Routes
parameters:
- name: app
in: path
description: Name of app for this set of routes.
required: true
type: string
responses:
200:
description: Route information
schema:
$ref: '#/definitions/RoutesWrapper'
404:
description: App does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/apps/{app}/routes/{route}:
patch:
summary: Update a Route
description: Update a route
tags:
- Routes
parameters:
- name: app
in: path
description: name of the app.
required: true
type: string
- name: route
in: path
description: route path.
required: true
type: string
- name: body
in: body
description: One route to post.
required: true
schema:
$ref: '#/definitions/RouteWrapper'
responses:
200:
description: Route updated
schema:
$ref: '#/definitions/RouteWrapper'
400:
description: Invalid route due to parameters being missing or invalid.
schema:
$ref: '#/definitions/Error'
404:
description: App does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
get:
summary: Gets route by name
description: Gets a route by name.
tags:
- Routes
parameters:
- name: app
in: path
description: Name of app for this set of routes.
required: true
type: string
- name: route
in: path
description: Route name
required: true
type: string
responses:
200:
description: Route information
schema:
$ref: '#/definitions/RouteWrapper'
404:
description: Route does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
delete:
summary: Deletes the route
tags:
- Routes
description: Deletes the route.
parameters:
- name: app
in: path
description: Name of app for this set of routes.
required: true
type: string
- name: route
in: path
description: Route name
required: true
type: string
responses:
200:
description: Route successfully deleted.
404:
description: Route does not exist.
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/calls/{call}:
get:
summary: Get call information
description: Get call information
tags:
- Call
parameters:
- name: call
description: Call ID.
required: true
type: string
in: path
responses:
200:
description: Call found
schema:
$ref: '#/definitions/CallWrapper'
404:
description: Call not found.
schema:
$ref: '#/definitions/Error'
/apps/{app}/calls/{route}:
get:
summary: Get route-bound calls.
description: Get route-bound calls.
tags:
- Call
parameters:
- name: app
description: App name.
required: true
type: string
in: path
- name: route
description: App route.
required: true
type: string
in: path
responses:
200:
description: Calls found
schema:
$ref: '#/definitions/CallsWrapper'
404:
description: Calls not found.
schema:
$ref: '#/definitions/Error'
/tasks:
get:
summary: Get next task.
description: Gets the next task in the queue, ready for processing. Consumers should start processing tasks in order. No other consumer can retrieve this task.
tags:
- Tasks
responses:
200:
description: Task information
schema:
$ref: '#/definitions/TaskWrapper'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
definitions:
Route:
type: object
properties:
path:
type: string
description: URL path that will be matched to this route
readOnly: true
image:
description: Name of Docker image to use in this route. You should include the image tag, which should be a version number, to be more accurate. Can be overridden on a per route basis with route.image.
type: string
headers:
type: object
description: Map of http headers that will be sent with the response
additionalProperties:
type: array
items:
type: string
memory:
type: integer
format: int64
description: Max usable memory for this route (MiB).
type:
enum:
- sync
- async
description: Route type
format:
enum:
- default
- http
- json
description: Payload format sent into function.
config:
type: object
description: Route configuration - overrides application configuration
additionalProperties:
type: string
timeout:
type: integer
default: 30
description: Timeout for executions of this route. Value in Seconds
idle_timeout:
type: integer
default: 30
description: Hot functions idle timeout before termination. Value in Seconds
App:
type: object
properties:
name:
type: string
description: "Name of this app. Must be different than the image name. Can ony contain alphanumeric, -, and _."
readOnly: true
config:
type: object
description: Application configuration
additionalProperties:
type: string
Version:
type: object
properties:
version:
type: string
readOnly: true
RoutesWrapper:
type: object
required:
- routes
properties:
routes:
type: array
items:
$ref: '#/definitions/Route'
error:
$ref: '#/definitions/ErrorBody'
RouteWrapper:
type: object
required:
- route
properties:
message:
type: string
error:
$ref: '#/definitions/ErrorBody'
route:
$ref: '#/definitions/Route'
AppsWrapper:
type: object
required:
- apps
properties:
apps:
type: array
items:
$ref: '#/definitions/App'
error:
$ref: '#/definitions/ErrorBody'
AppWrapper:
type: object
required:
- app
properties:
app:
$ref: '#/definitions/App'
error:
$ref: '#/definitions/ErrorBody'
CallsWrapper:
type: object
required:
- app
- route
properties:
app:
type: string
description: "Name of this app."
readOnly: true
route:
type: string
description: "Name of this app."
readOnly: true
CallWrapper:
type: object
required:
- call
properties:
call:
type: string
description: "Call ID."
readOnly: true
Call:
allOf:
- type: object
properties:
id:
type: string
description: Call UUID ID.
readOnly: true
status:
type: string
description: Call execution status.
readOnly: true
app_name:
type: string
description: App name that is assigned to a route that is being executed.
readOnly: true
path:
type: string
description: App route that is being executed.
readOnly: true
created_at:
type: string
format: date-time
description: Time when call was submitted. Always in UTC.
readOnly: true
started_at:
type: string
format: date-time
description: Time when call started execution. Always in UTC.
readOnly: true
completed_at:
type: string
format: date-time
description: Time when call completed, whether it was successul or failed. Always in UTC.
readOnly: true
Task:
allOf:
- $ref: "#/definitions/NewTask"
- type: object
properties:
group_name:
type: string
description: "Group this task belongs to."
readOnly: true
error:
type: string
description: "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."
reason:
type: string
description: |
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.
enum:
- timeout
- killed
- bad_exit
- client_request
created_at:
type: string
format: date-time
description: Time when task was submitted. Always in UTC.
readOnly: true
started_at:
type: string
format: date-time
description: Time when task started execution. Always in UTC.
completed_at:
type: string
format: date-time
description: Time when task completed, whether it was successul or failed. Always in UTC.
# We maintain a doubly linked list of the retried task to the
# original task.
retry_of:
type: string
description: If this field is set, then this task is a retry of the ID in this field.
readOnly: true
retry_at:
type: string
description: If this field is set, then this task was retried by the task referenced in this field.
readOnly: true
env_vars:
# this is a map: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#model-with-mapdictionary-properties
type: object
description: Env vars for the task. Comes from the ones set on the Group.
additionalProperties:
type: string
ErrorBody:
type: object
properties:
message:
type: string
readOnly: true
fields:
type: string
readOnly: true
Error:
type: object
properties:
error:
$ref: '#/definitions/ErrorBody'
NewTask:
type: object
required:
- image
properties:
image:
type: string
description: Name of Docker image to use. This is optional and can be used to override the image defined at the group level.
payload:
type: string
# 256k
# maxLength breaks ruby generator too: https://github.com/treeder/worker_ruby/blob/0aa9236ce5060af3f15758937712973f80dd54fe/lib/iron_titan/models/task.rb#L272
# maxLength: 268435456
description: Payload for the task. This is what you pass into each task to make it do something.
TaskWrapper:
type: object
required:
- task
properties:
task:
$ref: '#/definitions/Task'