feat: expose result subscription HTTP and WebSocket APIs
This commit is contained in:
569
protocol/eventsv1/events.schema.json
Normal file
569
protocol/eventsv1/events.schema.json
Normal file
@@ -0,0 +1,569 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.yuntuo.hk/k2safe/orbit/schema/events.v1.json",
|
||||
"title": "Orbit result events v1",
|
||||
"description": "消息最大512KiB。JSON重复键、非规范uint64和非规范base64url额外由实际解码器拒绝。",
|
||||
"$defs": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{32}$"
|
||||
},
|
||||
"counter": {
|
||||
"type": "string",
|
||||
"pattern": "^(?:[1-9][0-9]{0,18}|1[0-7][0-9]{18}|18[0-3][0-9]{17}|184[0-3][0-9]{16}|1844[0-5][0-9]{15}|18446[0-6][0-9]{14}|184467[0-3][0-9]{13}|1844674[0-3][0-9]{12}|184467440[0-6][0-9]{10}|1844674407[0-2][0-9]{9}|18446744073[0-6][0-9]{8}|1844674407370[0-8][0-9]{6}|18446744073709[0-4][0-9]{5}|184467440737095[0-4][0-9]{4}|18446744073709550[0-9]{3}|18446744073709551[0-5][0-9]{2}|1844674407370955160[0-9]{1}|1844674407370955161[0-4]|18446744073709551615)$",
|
||||
"description": "1 至 18446744073709551615 的规范十进制字符串,不允许前导零。"
|
||||
},
|
||||
"time": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"secret": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$"
|
||||
},
|
||||
"hello": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subscription_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"capacity": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 32
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subscription_id",
|
||||
"capacity"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"welcome": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"subscription_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"capacity": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 32
|
||||
},
|
||||
"lease_duration_ms": {
|
||||
"const": 30000
|
||||
},
|
||||
"heartbeat_interval_ms": {
|
||||
"const": 15000
|
||||
},
|
||||
"server_time": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"session_id",
|
||||
"subscription_id",
|
||||
"capacity",
|
||||
"lease_duration_ms",
|
||||
"heartbeat_interval_ms",
|
||||
"server_time",
|
||||
"enabled"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ackInput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"delivery_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"epoch": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"lease_secret": {
|
||||
"$ref": "#/$defs/secret"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"delivery_id",
|
||||
"epoch",
|
||||
"lease_secret"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ackResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"delivery_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"event_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"epoch": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"acknowledged_at": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"deduplicated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"delivery_id",
|
||||
"event_id",
|
||||
"epoch",
|
||||
"acknowledged_at",
|
||||
"deduplicated"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"pong": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_time": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"server_time",
|
||||
"enabled"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"snapshot": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": 1
|
||||
},
|
||||
"task_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"queue_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"state": {
|
||||
"enum": [
|
||||
"SUCCEEDED",
|
||||
"FAILED",
|
||||
"CANCELLED",
|
||||
"NEEDS_REVIEW"
|
||||
]
|
||||
},
|
||||
"revision": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"result": {},
|
||||
"effect_uncertain": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"current_attempt_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"schema_version",
|
||||
"task_id",
|
||||
"queue_id",
|
||||
"state",
|
||||
"revision",
|
||||
"effect_uncertain"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"event": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"sequence": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"task.succeeded",
|
||||
"task.failed",
|
||||
"task.cancelled",
|
||||
"task.needs_review"
|
||||
]
|
||||
},
|
||||
"aggregate_kind": {
|
||||
"const": "task"
|
||||
},
|
||||
"aggregate_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"aggregate_revision": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"occurred_at": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"details": {
|
||||
"type": "object"
|
||||
},
|
||||
"snapshot": {
|
||||
"$ref": "#/$defs/snapshot"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"sequence",
|
||||
"type",
|
||||
"aggregate_kind",
|
||||
"aggregate_id",
|
||||
"aggregate_revision",
|
||||
"occurred_at",
|
||||
"details",
|
||||
"snapshot"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"leasedDelivery": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"subscription_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"event_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"sequence": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"revision": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"state": {
|
||||
"const": "LEASED"
|
||||
},
|
||||
"available_at": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"lease_epoch": {
|
||||
"$ref": "#/$defs/counter"
|
||||
},
|
||||
"lease_until": {
|
||||
"$ref": "#/$defs/time"
|
||||
},
|
||||
"attempts": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 1000000
|
||||
},
|
||||
"attempt_budget": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 1000000
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"created_at",
|
||||
"id",
|
||||
"subscription_id",
|
||||
"event_id",
|
||||
"sequence",
|
||||
"revision",
|
||||
"state",
|
||||
"available_at",
|
||||
"lease_epoch",
|
||||
"lease_until",
|
||||
"attempts",
|
||||
"attempt_budget"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"grant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"delivery": {
|
||||
"$ref": "#/$defs/leasedDelivery"
|
||||
},
|
||||
"event": {
|
||||
"$ref": "#/$defs/event"
|
||||
},
|
||||
"lease_secret": {
|
||||
"$ref": "#/$defs/secret"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"delivery",
|
||||
"event",
|
||||
"lease_secret"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"error": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"enum": [
|
||||
"INVALID_ARGUMENT",
|
||||
"UNAUTHENTICATED",
|
||||
"PERMISSION_DENIED",
|
||||
"NOT_FOUND",
|
||||
"STATE_CONFLICT",
|
||||
"DELIVERY_LEASE_LOST",
|
||||
"EVENT_HISTORY_EXPIRED",
|
||||
"UNAVAILABLE"
|
||||
]
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"clientFrame": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "events.hello"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "#/$defs/hello"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "event.ack"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "#/$defs/ackInput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"session_id",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "events.ping"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"session_id",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"serverFrame": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "events.welcome"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"reply_to": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "#/$defs/welcome"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"session_id",
|
||||
"reply_to",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "event.deliver"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "#/$defs/grant"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"session_id",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "ack"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"reply_to": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"body": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ackResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/pong"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"session_id",
|
||||
"reply_to",
|
||||
"body"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol_version": {
|
||||
"const": "1"
|
||||
},
|
||||
"type": {
|
||||
"const": "error"
|
||||
},
|
||||
"message_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"session_id": {
|
||||
"$ref": "#/$defs/id"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/$defs/error"
|
||||
},
|
||||
"reply_to": {
|
||||
"$ref": "#/$defs/id"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"protocol_version",
|
||||
"type",
|
||||
"message_id",
|
||||
"error"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/clientFrame"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/serverFrame"
|
||||
}
|
||||
]
|
||||
}
|
||||
9
protocol/eventsv1/schema.go
Normal file
9
protocol/eventsv1/schema.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Package eventsv1 提供可靠结果订阅v1的机器可读契约;授权和状态由数据库事务决定。
|
||||
package eventsv1
|
||||
|
||||
import _ "embed"
|
||||
|
||||
// Schema 分别定义客户端和服务端消息,禁止将响应字段伪装成请求。
|
||||
//
|
||||
//go:embed events.schema.json
|
||||
var Schema string
|
||||
Reference in New Issue
Block a user