엔트리 종류 참조
이 페이지는 사용 가능한 엔트리 종류를 요약하고 자세한 모듈 및 시스템 레퍼런스로 연결합니다.
YAML과 Lua 블록은 하나의 애플리케이션이 아니라 레퍼런스 조각입니다. 레지스트리 ID, 자격 증명, 데이터 객체, get_users나 delete_user 같은 헬퍼는 예시입니다. 완전한 반환값과 오류 계약은 연결된 모듈 페이지를 확인하세요.
엔트리는
namespace:name형식으로 서로 참조합니다. 레지스트리는 이 참조를 사용해 의존성과 초기화 순서를 결정합니다.
참고
Lua 런타임
| 종류 | 설명 |
|---|---|
function.lua |
Lua 함수 진입점 |
process.lua |
장기 실행 Lua 프로세스 |
workflow.lua |
Temporal 워크플로우 (결정론적) |
library.lua |
공유 Lua 라이브러리 |
module.lua |
Lua 모듈 인터페이스 |
function.lua.bc |
사전 컴파일된 함수 바이트코드 |
library.lua.bc |
사전 컴파일된 라이브러리 바이트코드 |
process.lua.bc |
사전 컴파일된 프로세스 바이트코드 |
workflow.lua.bc |
사전 컴파일된 워크플로우 바이트코드 |
- name: handler
kind: function.lua
source: file://handler.lua
method: main
modules:
- http
- json
imports:
utils: app.lib:helpers # Import another entry as module
imports를 사용하여 다른 Lua 엔트리를 참조하세요. 코드에서 require("alias_name")으로 사용할 수 있습니다.
HTTP 서비스
| 종류 | 설명 |
|---|---|
http.service |
HTTP 서버 (포트 바인딩) |
http.router |
라우트 프리픽스와 미들웨어 |
http.endpoint |
HTTP 엔드포인트 (메서드 + 경로) |
http.static |
정적 파일 서빙 |
# HTTP server
- name: gateway
kind: http.service
addr: ":8080"
lifecycle:
auto_start: true
# Router with middleware
- name: api
kind: http.router
meta:
server: gateway
prefix: /api
middleware:
- cors
- ratelimit
# Endpoint
- 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 |
Postgres 변경 데이터 캡처 소스 (CDC 참조) |
db.cdc.sqlite |
SQLite 변경 데이터 캡처 소스 (CDC 참조) |
SQLite
- name: database
kind: db.sql.sqlite
file: "./data/app.db"
lifecycle:
auto_start: true
# In-memory for testing
- 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
${env:NAME} 시크릿 참조, TLS 옵션 및 연결 풀 튜닝은 Database를 참조하세요. 데이터베이스 엔트리 뒤의 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})
키-값 스토어
| 종류 | 설명 |
|---|---|
store.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.* 종류는 클러스터링이 활성화되어 있어야 합니다. 일관성 트레이드오프는 스토어를 참고하세요.
Lua API: Store 모듈 참조
local store = require("store")
local s, err = store.get("app:cache")
s:set("user:123", user_data, 3600) -- TTL in seconds
local data = s:get("user:123")
큐
| 종류 | 설명 |
|---|---|
queue.driver.memory |
인메모리 큐 드라이버 |
queue.driver.amqp |
AMQP (RabbitMQ) 드라이버 |
queue.driver.sqs |
AWS SQS 드라이버 |
queue.queue |
큐 선언 |
queue.consumer |
큐 컨슈머 |
# Driver
- name: queue_driver
kind: queue.driver.memory
lifecycle:
auto_start: true
# Queue
- name: jobs
kind: queue.queue
driver: queue_driver
# Consumer
- 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")
-- Publish a message
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 |
프로세스 그룹 스코프 (프로세스 그룹 참조) |
# Process host (where processes run)
- name: processes
kind: process.host
host:
workers: 32 # Worker goroutines (default: NumCPU)
queue_size: 1024 # Global queue capacity
local_queue_size: 256 # Per-worker queue
lifecycle:
auto_start: true
# Process definition
- name: worker_process
kind: process.lua
source: file://worker.lua
method: main
# Supervised process service
- 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 |
스코프에 병합되는 정책의 레지스트리 ID (namespace:name) |
groups |
정책이 스코프에 병합되는 정책 그룹의 레지스트리 ID |
해석은 프로세스가 시작될 때 일어나며 원자적입니다: 나열된 정책이나 그룹 중 하나라도 해석할 수 없으면 스폰이 실패하고 부분적인 컨텍스트는 설치되지 않습니다. actor를 생략하면 스폰한 쪽의 액터를 상속하고, policies와 groups를 모두 생략하면 스폰한 쪽의 스코프를 상속합니다. function.lua, function.lua.bc, process.lua, process.lua.bc 모두 이 블록을 받습니다.
커맨드 엔트리는 추가로 meta.command.security를 선언할 수 있으며, 이는 엔트리가 CLI 커맨드로 실행될 때만 적용됩니다 — 커맨드 보안을 참조하세요. 일반 스폰에는 영향을 주지 않습니다.
보안을 참조하세요.
Temporal (워크플로우)
| 종류 | 설명 |
|---|---|
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: "" # Optional, for S3-compatible services
Lua API: 클라우드 스토리지 모듈 참조
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를 사용하세요.
파일 시스템
| 종류 | 설명 |
|---|---|
fs.directory |
디렉토리 접근 |
fs.embed |
읽기 전용 내장 파일 시스템 |
- name: data_dir
kind: fs.directory
directory: "./data"
auto_init: true # Create if not exists
mode: "0755" # Permissions
Lua API: 파일시스템 모듈 참조
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 |
인메모리 환경 스토리지 |
env.storage.file |
파일 기반 환경 스토리지 |
env.storage.os |
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 |
템플릿 세트 설정 |
# Template set with engine configuration
- name: templates
kind: template.set
engine:
development_mode: false
extensions:
- ".jet"
- ".html.jet"
# Individual template
- name: email_template
kind: template.jet
source: file://templates/email.jet
set: app:templates
Lua API: 템플릿 모듈 참조
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 |
토큰 스토리지 |
# Condition-based policy
- name: admin_policy
kind: security.policy
policy:
actions: "*"
resources: "*"
effect: allow
conditions:
- field: "actor.meta.role"
operator: eq
value: "admin"
# Expression-based policy
- 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를 나열하고, 그룹은 그 그룹을 지명한 정책들의 집합입니다. 별도의 그룹 엔트리 kind는 없습니다. 그룹 ID는 레지스트리 ID입니다 — 이름만 쓰면 선언한 정책의 네임스페이스에서 해석되므로, 위의 operators는 네임스페이스 app.security에서 선언되면 app.security:operators가 됩니다. 엔트리는 전체 namespace:name으로 그룹을 참조합니다.
Lua API: 보안 모듈 참조
local security = require("security")
-- Check permission before action
if security.can("delete", "users", {user_id = id}) then
delete_user(id)
end
-- Get current actor
local actor = security.actor()
deny를 내면 모든 allow보다 우선합니다. deny가 없으면 일치하는 allow가 접근을 허용합니다. 순서는 중요하지 않습니다.
계약 (의존성 주입)
| 종류 | 설명 |
|---|---|
contract.definition |
메서드 명세가 있는 인터페이스 |
contract.binding |
계약 메서드를 함수 구현에 매핑 |
# Define the contract interface
- name: greeter
kind: contract.definition
methods:
- name: greet
description: Returns a greeting message
- name: greet_with_name
description: Returns a personalized greeting
input_schemas:
- format: "application/schema+json"
definition: {"type": "string"}
output_schemas:
- format: "application/schema+json"
definition: {"type": "string"}
# Implementation functions
- 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
# Bind contract methods to implementations
- 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")
-- Open binding by ID
local greeter, err = contract.open("app:greeter_impl")
-- Call methods
local result = greeter:greet()
local personalized = greeter:greet_with_name("Alice")
-- Check if instance implements contract
local is_greeter = contract.is(greeter, "app:greeter")
Lua API: 계약 모듈 참조
default: true를 설정하세요. 계약은 기본 바인딩을 하나만 가질 수 있습니다.
실행
| 종류 | 설명 |
|---|---|
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 런타임
| 종류 | 설명 |
|---|---|
function.wat |
WebAssembly 함수 (WAT 텍스트 형식) |
function.wasm |
WebAssembly 함수 (바이너리) |
process.wasm |
WebAssembly 프로세스 |
# WAT 텍스트는 인라인 소스입니다
- 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를 선언합니다. 컴포넌트 구축을 참조하세요.
라이프사이클 설정
슈퍼바이저가 관리하는 서비스 엔트리는 라이프사이클 설정을 제공합니다. 아래 블록은 이를 지원하는 서비스 엔트리 안에 둡니다:
lifecycle:
auto_start: true # Start automatically
start_timeout: 10s # Max startup time
stop_timeout: 10s # Max shutdown time
stable_threshold: 5s # Uninterrupted run time before retry accounting resets
requires:
- app:database
restart: # Retry policy
initial_delay: 1s
max_delay: 90s
backoff_factor: 2.0
max_attempts: 0 # 0 = infinite
depends_on을 사용하면 엔트리가 올바른 순서로 시작됩니다. 슈퍼바이저는 각 의존성이 자신의 시작을 완료한 뒤에야 그에 의존하는 엔트리를 시작합니다.
엔트리 참조 형식
엔트리는 namespace:name 형식을 사용하여 참조됩니다:
# Definition
namespace: app.users
entries:
- name: handler
kind: function.lua
# Reference from another entry
func: app.users:handler
엔트리 재정의 {id="overriding-entries"}
override: 설정 섹션이나 -o CLI 플래그를 사용하면, 소스 YAML을 편집하지 않고도 실행 시 엔트리의 모든 필드(kind 포함)를 재정의할 수 있습니다. 키는 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로, 숫자는 숫자로, 그 외에는 string). override: 섹션 값은 YAML 타입을 그대로 유지합니다. 엔트리 대신 전역 설정 섹션을 재정의하려면 --set을 사용하세요.