mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
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
653 lines
17 KiB
YAML
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'
|