엔트리 종류 참조
엔트리 종류 참조
섹션 제목: “엔트리 종류 참조”Wippy에서 사용 가능한 모든 엔트리 종류에 대한 참조 문서입니다.
엔트리는
namespace:name형식으로 서로 참조합니다. 레지스트리는 이 참조를 기반으로 의존성을 자동으로 연결하여 리소스가 올바른 순서로 초기화되도록 합니다.
Lua 런타임
섹션 제목: “Lua 런타임”| Kind | 설명 |
|---|---|
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 # 다른 엔트리를 모듈로 가져오기imports를 사용하여 다른 Lua 엔트리를 참조하세요. 코드에서 require("alias_name")으로 사용할 수 있습니다.
HTTP 서비스
섹션 제목: “HTTP 서비스”| Kind | 설명 |
|---|---|
http.service | HTTP 서버 (포트 바인딩) |
http.router | 라우트 프리픽스와 미들웨어 |
http.endpoint | HTTP 엔드포인트 (메서드 + 경로) |
http.static | 정적 파일 서빙 |
# HTTP 서버- name: gateway kind: http.service addr: ":8080" lifecycle: auto_start: true
# 미들웨어가 있는 라우터- name: api kind: http.router meta: server: gateway prefix: /api middleware: - cors - rate_limit
# 엔드포인트- name: users_list kind: http.endpoint meta: router: app:api method: GET path: /users func: list_handlerLua API: HTTP 모듈 참조
local http = require("http")local req = http.request()local resp = http.response()
resp:status(200):json({users = get_users()})데이터베이스
섹션 제목: “데이터베이스”| Kind | 설명 |
|---|---|
db.sql.sqlite | SQLite 데이터베이스 |
db.sql.postgres | PostgreSQL 데이터베이스 |
db.sql.mysql | MySQL 데이터베이스 |
SQLite
섹션 제목: “SQLite”- name: database kind: db.sql.sqlite file: "./data/app.db" lifecycle: auto_start: true
# 테스트용 인메모리- name: testdb kind: db.sql.sqlite file: ":memory:"PostgreSQL
섹션 제목: “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: trueMySQL
섹션 제목: “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 접미사 변형, TLS 옵션 및 연결 풀 튜닝은 Database를 참조하세요.
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)키-값 스토어
섹션 제목: “키-값 스토어”| Kind | 설명 |
|---|---|
store.memory | 인메모리 키-값 스토어 |
store.sql | SQL 기반 키-값 스토어 |
store.kv.raft | 클러스터 복제, 강한 일관성 KV (공유 Raft) |
store.kv.crdt | 클러스터 복제, 최종 일관성 KV (gossip/CRDT) |
# 메모리 스토어- name: cache kind: store.memory lifecycle: auto_start: true
# SQL 기반 스토어- name: persistent_store kind: store.sql database: app:database table: kv_store lifecycle: auto_start: true
# 클러스터 복제 스토어 (클러스터링 필요)- name: deployments kind: store.kv.raft namespace: deploystore.kv.* 종류는 클러스터링이 활성화되어 있어야 합니다. 일관성 트레이드오프는 스토어를 참조하세요.
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")| Kind | 설명 |
|---|---|
queue.driver.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: trueLua API: Queue 모듈 참조
local queue = require("queue")
-- 메시지 발행queue.publish("app:jobs", {task = "process", id = 123})
-- 컨슈머 핸들러에서 현재 메시지 접근local msg = queue.message()local data = msg:body_json()func는 각 메시지마다 호출됩니다. 핸들러 내에서 queue.message()로 현재 메시지에 접근합니다.
프로세스 관리
섹션 제목: “프로세스 관리”| Kind | 설명 |
|---|---|
process.host | 프로세스 실행 호스트 |
process.service | 슈퍼바이즈드 프로세스 (process.lua 래핑) |
terminal.host | 터미널/CLI 호스트 |
# 프로세스 호스트 (프로세스가 실행되는 곳)- 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: trueprocess.service를 사용하세요. process 필드는 process.lua 엔트리를 참조합니다.
Temporal (워크플로우)
섹션 제목: “Temporal (워크플로우)”| Kind | 설명 |
|---|---|
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클라우드 스토리지
섹션 제목: “클라우드 스토리지”| Kind | 설명 |
|---|---|
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: 클라우드 스토리지 모듈 참조
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", {expires = "1h"})endpoint를 사용하세요.
파일 시스템
섹션 제목: “파일 시스템”| Kind | 설명 |
|---|---|
fs.directory | 디렉토리 접근 |
fs.embed | 읽기 전용 내장 파일 시스템 |
- name: data_dir kind: fs.directory directory: "./data" auto_init: true # 없으면 생성 mode: "0755" # 권한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()| Kind | 설명 |
|---|---|
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:defaultsLua API: Env 모듈 참조
local env = require("env")
local api_key = env.get("API_KEY")env.set("CACHE_TTL", "3600")템플릿
섹션 제목: “템플릿”| Kind | 설명 |
|---|---|
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:templatesLua API: 템플릿 모듈 참조
local templates = require("templates")local set, err = templates.get("app:templates")
local html = set:render("email", { user = "Alice", message = "Welcome!"})| Kind | 설명 |
|---|---|
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"'Lua API: 보안 모듈 참조
local security = require("security")
-- 액션 전 권한 확인if security.can("delete", "users", {user_id = id}) then delete_user(id)end
-- 현재 액터 가져오기local actor = security.actor()계약 (의존성 주입)
섹션 제목: “계약 (의존성 주입)”| Kind | 설명 |
|---|---|
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_nameLua에서 사용:
local contract = require("contract")
-- 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: 계약 모듈 참조
default: true를 설정하세요(context_required 필드가 설정되지 않은 경우에만 작동).
| Kind | 설명 |
|---|---|
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 런타임
섹션 제목: “WASM 런타임”| Kind | 설명 |
|---|---|
function.wat | WebAssembly 함수 (WAT 텍스트 형식) |
function.wasm | WebAssembly 함수 (바이너리) |
process.wasm | WebAssembly 프로세스 |
- name: sum kind: function.wasm source: file://sum.wasm transport: payload # 또는 wasi-httpWASM 개요 참조.
네트워크
섹션 제목: “네트워크”| Kind | 설명 |
|---|---|
network | 기본 네트워크 오버레이 |
network.socks5 | SOCKS5 프록시 오버레이 |
network.i2p | I2P 네트워크 오버레이 |
network.tailscale | Tailscale 오버레이 |
http.service에서는 network:를 통해, funcs/process에서는 network 옵션을 통해, http_client에서는 overlay_network 옵션을 통해 참조됩니다. 네트워크 참조.
레지스트리 프리미티브
섹션 제목: “레지스트리 프리미티브”| Kind | 설명 |
|---|---|
registry.entry | 엔트리 디스크립터 (내부) |
ns.definition | 네임스페이스 정의 |
ns.requirement | 네임스페이스 요구사항 선언 |
ns.dependency | 네임스페이스 의존성 |
이들은 레지스트리 로더가 _index.yaml 프론트매터와 의존성 선언으로부터 생성합니다. 작성자가 직접 정의하는 경우는 거의 없으며, version:, namespace:, 의존성 블록이 해석된 결과로 나타납니다.
라이프사이클 설정
섹션 제목: “라이프사이클 설정”대부분의 엔트리는 라이프사이클 설정을 지원합니다:
- 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.usersentries: - name: handler kind: function.lua
# 다른 엔트리에서 참조func: app.users:handler엔트리 재정의 {id=“overriding-entries”}
섹션 제목: “엔트리 재정의 {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=:9090CLI(-o) 값은 형태에 따라 변환됩니다(true/false는 bool로, 숫자는 숫자로, 그 외에는 string). override: 섹션 값은 YAML 타입을 그대로 유지합니다. 엔트리 대신 전역 설정 섹션을 재정의하려면 --set을 사용하세요.