Типы записей

Полный справочник всех типов записей Wippy.

Записи ссылаются друг на друга в формате namespace:name. Реестр автоматически связывает зависимости, обеспечивая правильный порядок инициализации ресурсов.

См. также

Lua Runtime

Тип Описание
function.lua Точка входа Lua-функции
process.lua Долгоживущий Lua-процесс
workflow.lua Temporal workflow (детерминированный)
library.lua Разделяемая Lua-библиотека
module.lua Модульный интерфейс Lua
function.lua.bc Предкомпилированный байт-код функции
library.lua.bc Предкомпилированный байт-код библиотеки
process.lua.bc Предкомпилированный байт-код процесса
workflow.lua.bc Предкомпилированный байт-код workflow
- name: handler
  kind: function.lua
  source: file://handler.lua
  method: main
  modules:
    - http
    - json
  imports:
    utils: app.lib:helpers  # Импорт другой записи как модуля
Используйте imports для ссылок на другие Lua-записи. Они становятся доступны через require("alias_name") в коде.

HTTP-сервисы

Тип Описание
http.service HTTP-сервер (слушает порт)
http.router Префикс маршрутов и middleware
http.endpoint HTTP-эндпоинт (метод + путь)
http.static Раздача статических файлов
# HTTP-сервер
- name: gateway
  kind: http.service
  addr: ":8080"
  lifecycle:
    auto_start: true

# Роутер с middleware
- name: api
  kind: http.router
  meta:
    server: gateway
  prefix: /api
  middleware:
    - cors
    - ratelimit

# Эндпоинт
- name: users_list
  kind: http.endpoint
  meta:
    router: app:api
  method: GET
  path: /users
  func: list_handler

Lua API: См. Модуль HTTP

local http = require("http")
local req = http.request()
local resp = http.response()

resp:set_status(200)
resp:write_json({users = get_users()})

Базы данных

Тип Описание
db.sql.sqlite SQLite
db.sql.postgres PostgreSQL
db.sql.mysql MySQL
db.cdc.postgres Источник Change Data Capture для Postgres (см. CDC)
db.cdc.sqlite Источник Change Data Capture для SQLite (см. CDC)

SQLite

- name: database
  kind: db.sql.sqlite
  file: "./data/app.db"
  lifecycle:
    auto_start: true

# In-memory для тестов
- name: testdb
  kind: db.sql.sqlite
  file: ":memory:"

PostgreSQL

- name: database
  kind: db.sql.postgres
  host: localhost
  port: 5432
  database: dbname
  username: user
  password: pass
  options:
    sslmode: disable
  pool:
    max_open: 25
    max_idle: 5
    max_lifetime: "30m"
  lifecycle:
    auto_start: true

MySQL

- name: database
  kind: db.sql.mysql
  host: localhost
  port: 3306
  database: dbname
  username: user
  password: pass
  options:
    parseTime: "true"
  lifecycle:
    auto_start: true

См. Database для ссылок на секреты ${env:NAME}, параметров TLS и настройки пула соединений. Когда меняется значение из env, стоящее за записью базы данных, пул переключается на лету — активные заимствования довершаются со старыми настройками соединения.

Lua API: См. Модуль SQL

local sql = require("sql")
local db, err = sql.get("app:database")

local rows, err = db:query("SELECT * FROM users WHERE id = ?", user_id)
db:execute("INSERT INTO logs (msg) VALUES (?)", message)

Key-Value хранилища

Тип Описание
store.memory In-memory хранилище
store.sql Хранилище на базе SQL
store.kv.raft Реплицируемое в кластере, строго согласованное KV (общий Raft)
store.kv.crdt Реплицируемое в кластере, согласованное в конечном счёте KV (gossip/CRDT)
# Memory store
- name: cache
  kind: store.memory
  lifecycle:
    auto_start: true

# SQL-backed store
- name: persistent_store
  kind: store.sql
  database: app:database
  table_name: kv_store
  lifecycle:
    auto_start: true

# Cluster-replicated store (requires clustering)
- name: deployments
  kind: store.kv.raft
  namespace: deploy

Типы store.kv.* требуют включённой кластеризации. См. Store для компромиссов согласованности.

Lua API: См. Модуль Store

local store = require("store")
local s, err = store.get("app:cache")

s:set("user:123", user_data, 3600)  -- TTL в секундах
local data = s:get("user:123")

Очереди

Тип Описание
queue.driver.memory In-memory драйвер очередей
queue.driver.amqp Драйвер AMQP (RabbitMQ)
queue.driver.sqs Драйвер AWS SQS
queue.queue Объявление очереди
queue.consumer Потребитель очереди
# Драйвер
- name: queue_driver
  kind: queue.driver.memory
  lifecycle:
    auto_start: true

# Очередь
- name: jobs
  kind: queue.queue
  driver: queue_driver

# Потребитель
- name: job_consumer
  kind: queue.consumer
  queue: app:jobs
  func: job_handler
  concurrency: 4
  prefetch: 10
  lifecycle:
    auto_start: true

Lua API: См. Модуль Queue

local queue = require("queue")

-- Публикация сообщения
queue.publish("app:jobs", {task = "process", id = 123})

-- В обработчике потребителя: тело сообщения — аргумент обработчика
local function main(data)
    -- доступ к метаданным доставки через текущее сообщение
    local msg = queue.message()
    local id = msg:id()
    local priority = msg:header("priority")
    msg:ack()
end
Функция func потребителя вызывается один раз на сообщение, получая тело сообщения аргументом. Используйте queue.message() внутри обработчика для id() доставки, header()/headers() и ack()/nack().

Управление процессами

Тип Описание
process.host Хост выполнения процессов
process.service Супервизируемый процесс (обёртка над process.lua)
terminal.host Хост терминала/CLI
pg.scope Область группы процессов (см. Группы процессов)
# Хост процессов (где выполняются процессы)
- name: processes
  kind: process.host
  host:
    workers: 32             # Горутины-воркеры (по умолчанию: NumCPU)
    queue_size: 1024        # Размер глобальной очереди
    local_queue_size: 256   # Очередь на воркер
  lifecycle:
    auto_start: true

# Определение процесса
- name: worker_process
  kind: process.lua
  source: file://worker.lua
  method: main

# Супервизируемый сервис
- name: worker
  kind: process.service
  process: app:worker_process
  host: app:processes
  input: ["arg1", "arg2"]
  lifecycle:
    auto_start: true
    restart:
      max_attempts: 10

- name: terminal
  kind: terminal.host
  lifecycle:
    auto_start: true
Используйте process.service, когда нужен процесс как супервизируемый сервис с автоматическим перезапуском. Поле process ссылается на запись process.lua.

Обновление живой записи process.host перемасштабирует host.workers на месте — работающие процессы, PID и очереди сохраняются. host.queue_size, host.local_queue_size и lifecycle фиксируются при создании: живое обновление, меняющее их, отклоняется, как и изменение числа воркеров у хоста, воркеры которого управляются аффинностью.

Безопасность процесса

Записи process.lua и process.lua.bc принимают блок security: верхнего уровня. Он входит в состав записи, поэтому применяется к каждому запуску этого процесса — как на process.host, так и на terminal.host:

- name: worker_process
  kind: process.lua
  source: file://worker.lua
  method: main
  security:
    actor:
      id: system.worker
      meta:
        tenant: acme
    policies:
      - app.security:worker_policy
    groups:
      - app.security:background_jobs
Поле Описание
actor.id Идентичность актора, под которой работает процесс; заменяет унаследованного актора
actor.meta Атрибуты актора, которые вычисляют политики
policies Registry ID (namespace:name) политик, объединяемых в область
groups Registry ID групп политик, чьи политики объединяются в область

Разрешение происходит при старте процесса и атомарно: если какую-либо из перечисленных политик или групп разрешить не удаётся, spawn завершается неудачей и частичный контекст не устанавливается. Опущенный actor наследует актора порождающей стороны; опущенные одновременно policies и groups наследуют её область. Блок принимают function.lua, function.lua.bc, process.lua и process.lua.bc.

Запись-команда может дополнительно объявить meta.command.security, который применяется только при запуске записи как CLI-команды — см. Безопасность команд. На обычные spawn он не влияет.

См. Безопасность.

Temporal (Workflows)

Тип Описание
temporal.client Подключение к Temporal
temporal.worker Воркер Temporal
- name: temporal_client
  kind: temporal.client
  address: "localhost:7233"
  namespace: "default"
  auth:
    type: none  # none, api_key, mtls
  lifecycle:
    auto_start: true

- name: temporal_worker
  kind: temporal.worker
  client: temporal_client
  task_queue: "main-queue"
  lifecycle:
    auto_start: true

Облачное хранилище

Тип Описание
config.aws Конфигурация AWS
cloudstorage.s3 Доступ к S3-бакету
- name: aws
  kind: config.aws
  region: "us-east-1"
  access_key_id: ${env:AWS_ACCESS_KEY_ID}
  secret_access_key: ${env:AWS_SECRET_ACCESS_KEY}

- name: uploads
  kind: cloudstorage.s3
  config: app:aws
  bucket: "my-uploads"
  endpoint: ""  # Опционально, для S3-совместимых сервисов

Lua API: См. Модуль Cloud Storage

local cloudstorage = require("cloudstorage")
local storage, err = cloudstorage.get("app:uploads")

storage:upload_object("files/doc.pdf", file_content)
local url = storage:presigned_get_url("files/doc.pdf", {expiration = 3600})  -- в секундах, по умолчанию 3600
Используйте endpoint для подключения к S3-совместимым сервисам типа MinIO или DigitalOcean Spaces.

Файловые системы

Тип Описание
fs.directory Доступ к каталогу
fs.embed Встраиваемая файловая система только для чтения
- name: data_dir
  kind: fs.directory
  directory: "./data"
  auto_init: true   # Создать, если не существует
  mode: "0755"      # Права доступа

Lua API: См. Модуль Filesystem

local fs = require("fs")
local filesystem, err = fs.get("app:data_dir")

local file = filesystem:open("output.txt", "w")
file:write("Hello, World!")
file:close()

Окружение

Тип Описание
env.storage.memory In-memory хранилище переменных
env.storage.file Файловое хранилище переменных
env.storage.os Переменные окружения ОС
env.storage.static Статическое хранилище (только чтение)
env.storage.router Роутер окружения (несколько хранилищ)
env.variable Переменная окружения
- name: os_env
  kind: env.storage.os

- name: file_env
  kind: env.storage.file
  file_path: ".env"
  auto_create: true

- name: defaults
  kind: env.storage.static
  values:
    PUBLIC_API_HOST: "https://api.example.com"
    APP_ENV: "production"

- name: app_env
  kind: env.storage.router
  storages:
    - app:os_env
    - app:file_env
    - app:defaults

Lua API: См. Модуль Env

local env = require("env")

local api_key = env.get("API_KEY")
env.set("CACHE_TTL", "3600")
Роутер перебирает хранилища по порядку. При чтении возвращается первое найденное значение; запись идёт в первое хранилище из списка.

Шаблоны

Тип Описание
template.jet Отдельный Jet-шаблон
template.set Набор шаблонов
# Набор шаблонов с настройками движка
- name: templates
  kind: template.set
  engine:
    development_mode: false
    extensions:
      - ".jet"
      - ".html.jet"

# Отдельный шаблон
- name: email_template
  kind: template.jet
  source: file://templates/email.jet
  set: app:templates

Lua API: См. Модуль Template

local templates = require("templates")
local set, err = templates.get("app:templates")

local html = set:render("email", {
    user = "Alice",
    message = "Welcome!"
})

Безопасность

Тип Описание
security.policy Политика безопасности с условиями
security.policy.expr Политика на основе выражений
security.token_store Хранилище токенов
# Политика с условиями
- name: admin_policy
  kind: security.policy
  policy:
    actions: "*"
    resources: "*"
    effect: allow
    conditions:
      - field: "actor.meta.role"
        operator: eq
        value: "admin"

# Политика на основе выражений
- name: owner_policy
  kind: security.policy.expr
  policy:
    actions: "*"
    resources: "*"
    effect: allow
    expression: 'actor.id == meta.owner_id || actor.meta.role == "admin"'
  groups:
    - operators

Группы политик образуются самими политиками: политика перечисляет под groups: ID групп, к которым принадлежит, а группа — это множество политик, назвавших её. Отдельного типа записи для группы нет. ID групп — это Registry ID: голое имя разрешается в пространстве имён объявляющей политики, поэтому operators выше становится app.security:operators при объявлении в пространстве имён app.security. Записи ссылаются на группы по полному namespace:name.

Lua API: См. Модуль Security

local security = require("security")

-- Проверка разрешения перед действием
if security.can("delete", "users", {user_id = id}) then
    delete_user(id)
end

-- Получить текущего актора
local actor = security.actor()
Вычисляется каждая политика в области видимости. deny из любой подходящей политики выигрывает у любого allow; если запрета нет, подходящий allow даёт доступ. Порядок значения не имеет.

Контракты (Dependency Injection)

Тип Описание
contract.definition Интерфейс со спецификациями методов
contract.binding Связывает методы контракта с реализациями
# Определение интерфейса
- name: greeter
  kind: contract.definition
  methods:
    - name: greet
      description: Возвращает приветствие
    - name: greet_with_name
      description: Возвращает персональное приветствие
      input_schemas:
        - format: "application/schema+json"
          definition: {"type": "string"}
      output_schemas:
        - format: "application/schema+json"
          definition: {"type": "string"}

# Функции-реализации
- name: greeter_greet
  kind: function.lua
  source: file://greeter_greet.lua
  method: main

- name: greeter_greet_name
  kind: function.lua
  source: file://greeter_greet_name.lua
  method: main

# Связывание методов контракта с реализациями
- name: greeter_impl
  kind: contract.binding
  contracts:
    - contract: app:greeter
      default: true
      methods:
        greet: app:greeter_greet
        greet_with_name: app:greeter_greet_name

Использование в Lua:

local contract = require("contract")

-- Открыть binding по ID
local greeter, err = contract.open("app:greeter_impl")

-- Вызов методов
local result = greeter:greet()
local personalized = greeter:greet_with_name("Alice")

-- Проверка, реализует ли экземпляр контракт
local is_greeter = contract.is(greeter, "app:greeter")

Lua API: См. Модуль Contract

Пометьте один binding как default: true, чтобы использовать его при открытии контракта без указания binding ID. У контракта может быть только один binding по умолчанию.

Выполнение команд

Тип Описание
exec.native Выполнение нативных команд
exec.docker Выполнение в Docker-контейнере
- name: native_exec
  kind: exec.native
  default_work_dir: "/app"
  command_whitelist:
    - "ls"
    - "cat"

- name: docker_exec
  kind: exec.docker
  image: "python:3.11-slim"
  default_work_dir: "/workspace"
  auto_remove: true
  memory_limit: 536870912  # 512MB
  command_whitelist:
    - "python"

WASM Runtime

Тип Описание
function.wat WebAssembly-функция (текстовый формат WAT)
function.wasm WebAssembly-функция (бинарный формат)
process.wasm WebAssembly-процесс
# Текст WAT — это inline-исходник
- name: sum_wat
  kind: function.wat
  source: file://sum.wat
  method: sum
  transport: payload   # или wasi-http

# Бинарный WASM загружается из записи файловой системы и проверяется по хэшу
- name: sum
  kind: function.wasm
  fs: app:modules
  path: sum.wasm
  hash: sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
  method: sum
  transport: payload

function.wasm и process.wasm принимают fs, path и hash — поля source у бинарной записи нет; source относится только к function.wat. hash обязателен и должен иметь вид sha256:<hex>; модуль отклоняется, если байты не совпадают.

См. Обзор WASM.

Сети

Тип Описание
network Базовый сетевой оверлей
network.socks5 Оверлей SOCKS5-прокси
network.i2p Оверлей сети I2P
network.tailscale Оверлей Tailscale

Используется в http.service через network:, в funcs/process через опцию network и в http_client через опцию overlay_network. См. Сеть.

Примитивы реестра

Тип Описание
registry.entry Запись с обычными данными без стоящего за ней сервиса (конфигурация, специфичная для приложения)
ns.definition Определение пространства имён
ns.requirement Декларация требования пространства имён
ns.dependency Зависимость пространства имён

Типы ns.* пишутся так же, как любые другие записи: компонент объявляет ns.definition и ns.requirement, а хост объявляет ns.dependency. См. Создание компонентов.

Настройка жизненного цикла

Большинство записей поддерживают настройку жизненного цикла:

- name: service
  kind: some.kind
  lifecycle:
    auto_start: true          # Запускать автоматически
    start_timeout: 10s        # Максимальное время запуска
    stop_timeout: 10s         # Максимальное время остановки
    stable_threshold: 5s      # Время до признания стабильным
    depends_on:
      - app:database
    restart:                  # Политика перезапуска
      initial_delay: 1s
      max_delay: 90s
      backoff_factor: 2.0
      max_attempts: 0         # 0 = бесконечно
Используйте depends_on для правильного порядка запуска. Супервизор запускает зависимую запись только после того, как каждая из её зависимостей завершила собственный запуск.

Формат ссылок на записи

Записи указываются в формате namespace:name:

# Определение
namespace: app.users
entries:
  - name: handler
    kind: function.lua

# Ссылка из другой записи
func: app.users:handler

Переопределение записей {id="overriding-entries"}

Любые поля записи — включая её kind — можно переопределить при запуске без редактирования исходного YAML, используя секцию конфигурации override: или CLI-флаг -o. Ключи используют формат namespace:entry:path:

override:
  app:gateway:addr: ":9090"        # data field (a bare path targets data.*)
  app:worker:meta.priority: high    # meta field
  app:db:kind: db.sql.postgres      # the entry's typed kind
  app:db:data.kind: custom          # a payload field literally named "kind"
Путь Цель
kind Типизированный kind записи (должен быть непустой строкой)
data.<field> или просто <field> Поле в data-нагрузке записи
meta.<field> Поле в метаданных записи

Те же переопределения работают из CLI:

wippy run -o app:db:kind=db.sql.postgres -o app:gateway:addr=:9090

Значения CLI (-o) приводятся по форме (true/false в bool, числа в числа, иначе строка); значения секции override: сохраняют свой YAML-тип. Чтобы переопределить глобальные секции конфигурации, а не записи, используйте --set.