Функции

Функции — синхронные точки входа без состояния. Вызываете их, они выполняются, возвращают результат. При выполнении функция наследует контекст вызывающего — если вызывающий отменяется, функция тоже. Это делает функции идеальными для HTTP-обработчиков, API-эндпоинтов и любых операций, которые должны завершиться в рамках жизненного цикла запроса.

Вызов функций

Вызывайте функции синхронно через funcs.call():

local funcs = require("funcs")
local result, err = funcs.call("app.api:get_user", user_id)

Для неблокирующего выполнения используйте funcs.async():

local future = funcs.async("app.process:analyze", data)

local ch = future:response()
local result, ok = ch:receive()

См. модуль funcs для полного API.

Распространение контекста

Каждый вызов создаёт фрейм со своей областью контекста. Дочерние функции наследуют родительский контекст без явной передачи:

local ctx = require("ctx")

local trace_id = ctx.get("trace_id")
local user_id = ctx.get("user_id")

Добавляйте контекст при вызове:

local exec = funcs.new()
    :with_context({trace_id = "abc-123"})
    :call("app.api:process", data)

Контекст безопасности распространяется так же. Вызываемые функции видят актора вызывающего и могут проверять разрешения. См. модуль security для API контроля доступа.

Определение в реестре

На уровне реестра запись функции выглядит так:

- name: get_user
  kind: function.lua
  source: file://handlers/user.lua
  method: get
  pool:
    type: lazy
    max_size: 16

Функции могут вызываться другими компонентами среды исполнения — HTTP-обработчиками, потребителями очередей, запланированными задачами — и подчиняются проверкам разрешений на основе контекста безопасности вызывающего.

Пулы

Функции работают на пулах, управляющих выполнением. Тип пула определяет поведение масштабирования.

Inline выполняется в горутине вызывающего. Никакой конкурентности, нулевой оверхед аллокаций. Используется для встроенных контекстов.

Static поддерживает фиксированное число воркеров. Запросы ставятся в очередь, когда все воркеры заняты. Предсказуемое использование ресурсов.

pool:
  type: static
  workers: 8
  buffer: 512

Lazy стартует пустым и создаёт воркеров по запросу. Простаивающие воркеры уничтожаются по таймауту. Эффективен для переменной нагрузки.

pool:
  type: lazy
  max_size: 32

Adaptive масштабируется автоматически на основе пропускной способности. Контроллер измеряет производительность и подстраивает число воркеров под текущую нагрузку.

pool:
  type: adaptive
  max_size: 256
Если не указать тип пула, среда исполнения выберет его на основе конфигурации. Укажите workers для static, max_size для lazy, или явно задайте type для полного контроля.

Интерсепторы

Вызовы функций проходят через цепочку интерсепторов. Интерсепторы обрабатывают сквозную функциональность, не затрагивая бизнес-логику.

- name: my_function
  kind: function.lua
  source: file://handler.lua
  method: main
  meta:
    options:
      retry:
        max_attempts: 3
        initial_delay: 100
        backoff_factor: 2.0

Встроенные интерсепторы включают retry с экспоненциальным backoff. Можно добавить свои интерсепторы для логирования, метрик, трассировки, авторизации, circuit breaking или трансформации запросов.

Цепочка выполняется до и после каждого вызова. Каждый интерсептор может модифицировать запрос, прервать выполнение или обернуть ответ.

Контракты

Функции могут предоставлять схемы ввода/вывода как контракты. Контракты определяют сигнатуры методов, обеспечивая валидацию во время выполнения и генерацию документации.

local contract = require("contract")
local email = contract.get("app.email:sender")
email:send({to = "user@example.com", subject = "Hello"})

Эта абстракция позволяет подменять реализации без изменения вызывающего кода — полезно для тестирования, мультитенантных деплоев или постепенных миграций.

Функции vs Процессы

Функции наследуют контекст вызывающего и привязаны к его жизненному циклу. Когда вызывающий отменяется, функции отменяются. Это обеспечивает edge-выполнение — работу прямо в HTTP-обработчиках и потребителях очередей.

Процессы работают независимо с контекстом хоста. Они переживают своего создателя и общаются через сообщения. Используйте процессы для фоновой работы; используйте функции для операций в рамках запроса.