関数呼び出し
Wippyで他の関数を呼び出すプライマリな方法。コンテキスト伝播、セキュリティ資格情報、タイムアウトをフルサポートして、登録された関数をプロセス間で同期または非同期に実行。このモジュールは、コンポーネントが通信する必要のある分散アプリケーションを構築する上で中心的な役割を果たします。
ロード
local funcs = require("funcs")
call
登録された関数を同期的に呼び出し。即座に結果が必要で待機できる場合に使用。
local result, err = funcs.call("app.api:get_user", user_id)
if err then
return nil, err
end
print(result.name)
| パラメータ | 型 | 説明 |
|---|---|---|
target |
string | "namespace:name"形式の関数ID |
...args |
any | 関数に渡される引数 |
戻り値: result, error
target文字列はnamespace:nameパターンに従い、namespaceはモジュールを識別し、nameは特定の関数を識別します。
async
非同期関数呼び出しを開始し、即座にFutureを返す。ブロックしたくない長時間実行操作、または複数の操作を並行で実行したい場合に使用。
-- Start heavy computation without blocking
local future, err = funcs.async("app.process:analyze_data", large_dataset)
if err then
return nil, err
end
-- Do other work while computation runs...
-- Wait for result when ready
local ch = future:response()
local _, open = ch:receive()
if not open then
return nil, errors.new("future response channel closed")
end
local payload, result_err = future:result()
if result_err then
return nil, result_err
end
local result, data_err = payload:data()
if data_err then return nil, data_err end
| パラメータ | 型 | 説明 |
|---|---|---|
target |
string | "namespace:name"形式の関数ID |
...args |
any | 関数に渡される引数 |
戻り値: Future, error
new
カスタムコンテキストで関数呼び出しを構築するための新しいExecutorを作成。リクエストコンテキストを伝播、セキュリティ資格情報を設定、またはタイムアウトを設定する必要がある場合に使用。
local exec = funcs.new()
戻り値: Executor
Executor
カスタムコンテキストオプション付きの関数呼び出しビルダー。メソッドは新しいExecutorインスタンスを返す(イミュータブルチェーン)ので、ベース設定を再利用可能。
with_context
呼び出される関数で利用可能になるコンテキスト値を追加。トレースID、ユーザーセッション、機能フラグなどのリクエストスコープデータを伝播するために使用。
local ctx = require("ctx")
-- Propagate request context to downstream services
local request_id, ctx_err = ctx.get("request_id")
if ctx_err then return nil, ctx_err end
local exec, err = funcs.new():with_context({
request_id = request_id,
feature_flags = {dark_mode = true}
})
if err then return nil, err end
local user, err = exec:call("app.api:get_user", user_id)
if err then return nil, err end
| パラメータ | 型 | 説明 |
|---|---|---|
values |
table | コンテキストに追加するキー/値ペア |
戻り値: Executor, error
with_actor
呼び出される関数での認可チェック用のセキュリティアクターを設定。特定のユーザーの代わりに関数を呼び出す場合に使用。
local security = require("security")
local actor = security.actor() -- Get current user's actor
-- Call admin function with user's credentials
local exec, err = funcs.new():with_actor(actor)
if err then return nil, err end
local result, err = exec:call("app.admin:delete_record", record_id)
if err and err:kind() == errors.PERMISSION_DENIED then
return nil, errors.new({kind = errors.PERMISSION_DENIED, message = "User cannot delete records"})
end
| パラメータ | 型 | 説明 |
|---|---|---|
actor |
Actor | セキュリティアクター(securityモジュールから) |
戻り値: Executor, error
with_scope
呼び出される関数のセキュリティスコープを設定。スコープは呼び出しで利用可能な権限を定義。
local security = require("security")
local scope = security.new_scope()
local exec, err = funcs.new():with_scope(scope)
if err then return nil, err end
| パラメータ | 型 | 説明 |
|---|---|---|
scope |
Scope | セキュリティスコープ(securityモジュールから) |
戻り値: Executor, error
with_options
リトライポリシーやオーバーレイネットワークなどの呼び出しオプションを設定。オプションは対象の関数エントリのプリセットオプションに上書きマージされる。
-- 一時的な失敗を指数バックオフで最大5回リトライ
local exec = funcs.new():with_options({
retry = { max_attempts = 5, initial_delay = 100 }
})
local result, err = exec:call("app.external:fetch_data", query)
if err then
-- すべての試行が失敗したか、エラーがリトライ不可だった
end
| パラメータ | 型 | 説明 |
|---|---|---|
options |
table | 呼び出しオプション |
| オプション | 型 | 説明 |
|---|---|---|
retry.max_attempts |
int | 最初の試行を含む最大試行回数(1でリトライ無効) |
retry.initial_delay |
int/duration | 最初のリトライ前の遅延(ミリ秒または duration 文字列)、デフォルト 100 |
retry.max_delay |
int/duration | バックオフ遅延の上限(ミリ秒または duration 文字列)、デフォルト 10s |
retry.backoff_factor |
number | 各試行後に遅延へ適用される乗数、デフォルト 2.0 |
retry.jitter |
number | 各遅延に適用されるランダムジッターの割合、デフォルト 0.1 |
retry.retry_kinds |
string[] | これらの kind のエラーのみリトライする。デフォルトでは Invalid、PermissionDenied、Internal を除くすべての kind がリトライされる |
retry.skip_kinds |
string[] | これらの kind のエラーは決してリトライしない |
network |
string | 呼び出しの送信トラフィックを経由させるオーバーレイネットワークのレジストリID。network.select 権限が必要 |
リトライが発生するのはリトライ可能なエラーのみで、リトライ不可のエラーは即座に返される。Temporalのアクティビティオプションはアクティビティで説明する。
ランタイム定義のオプションは次のとおりです。
| 認識されるオプション | 型 | 説明 |
|---|---|---|
network |
string | 送信に使用する network.* エントリのレジストリ ID |
戻り値: Executor, error
ネットワークを選択するには、そのネットワーク ID に対する network.select 権限が必要です。
call / async
設定されたコンテキストを使用するExecutor版のcallとasync。
-- コンテキスト付きの再利用可能なexecutorを構築
local exec = funcs.new()
:with_context({trace_id = "abc-123"})
:with_options({retry = {max_attempts = 3}})
-- Make multiple calls with same context
local users, users_err = exec:call("app.api:list_users")
if users_err then return nil, users_err end
local posts, posts_err = exec:call("app.api:list_posts")
if posts_err then return nil, posts_err end
Future
async()呼び出しによって返される。進行中の非同期操作を表す。
response / channel
結果を受信するための基礎となるチャネルを返す。
local time = require("time")
local future, err = funcs.async("app.api:slow_operation", data)
if err then
return nil, err
end
local ch = future:response() -- or future:channel()
local timeout, err = time.after("5s")
if err then
return nil, err
end
local result = channel.select {
ch:case_receive(),
timeout:case_receive()
}
戻り値: Channel
is_complete
Futureが完了したかどうかのノンブロッキングチェック。
while not future:is_complete() do
-- do other work
local _, sleep_err = time.sleep("100ms")
if sleep_err then return nil, sleep_err end
end
local result, err = future:result()
戻り値: boolean
is_canceled
このFutureでcancel()が呼び出されたかどうかを返す。
if future:is_canceled() then
print("Operation was canceled")
end
戻り値: boolean
result
完了した場合はキャッシュされた結果を、まだ保留中の場合はnilを返す。
local value, err = future:result()
if err then
print("Failed:", err:message())
elseif value then
local data, data_err = value:data()
if data_err then return nil, data_err end
print("Got:", data)
end
戻り値: Payload|nil, error|nil
error
Futureが失敗した場合のエラーを返す。
local err, has_error = future:error()
if has_error then
print("Error kind:", err:kind())
end
戻り値: error|nil, boolean
cancel
非同期操作をキャンセル。
local canceled, err = future:cancel()
if err then return nil, err end
戻り値: boolean, error
cancel()とis_canceled()はproviderをまたぐ安定した契約ではありません。アプリケーションの正しさをキャンセルに依存させず、ローカルでタイムアウトし、ランタイムがproviderごとのキャンセルを分離するまでは遅れて届いた結果を無視してください。
並行操作
asyncとchannel.selectを使用して複数の操作を並行に実行。
-- Start multiple operations in parallel
local f1, err = funcs.async("app.api:get_user", user_id)
if err then return nil, err end
local f2, err = funcs.async("app.api:get_orders", user_id)
if err then return nil, err end
local f3, err = funcs.async("app.api:get_preferences", user_id)
if err then return nil, err end
-- Wait for all to complete using channels
local user_ch = f1:channel()
local orders_ch = f2:channel()
local prefs_ch = f3:channel()
local pending = {
[user_ch] = {name = "user", future = f1},
[orders_ch] = {name = "orders", future = f2},
[prefs_ch] = {name = "preferences", future = f3}
}
local results = {}
while next(pending) do
local cases = {}
for ch in pairs(pending) do
cases[#cases + 1] = ch:case_receive()
end
local r = channel.select(cases)
local completed = pending[r.channel]
pending[r.channel] = nil
local payload, result_err = completed.future:result()
if result_err then
return nil, result_err
end
local data, data_err = payload:data()
if data_err then
return nil, data_err
end
results[completed.name] = data
end
権限
関数操作はセキュリティポリシー評価の対象。
| アクション | リソース | 説明 |
|---|---|---|
funcs.call |
Function ID | 特定の関数を呼び出し |
funcs.context |
context |
with_context()を使用してカスタムコンテキストを設定 |
funcs.security |
security |
with_actor()またはwith_scope()を使用 |
network.select |
ネットワークID | with_options({network = ...})でオーバーレイネットワークを選択 |
エラー
| 条件 | 種別 | 再試行可能 |
|---|---|---|
| Targetが空 | errors.INVALID |
no |
| Namespaceがない | errors.INVALID |
no |
| Nameがない | errors.INVALID |
no |
| 権限拒否 | errors.PERMISSION_DENIED |
no |
| プロセス外での非同期呼び出し | errors.INTERNAL |
no |
| サブスクライブ失敗 | errors.INTERNAL |
no |
| 関数エラー | 様々 | 様々 |
エラーの処理についてはエラー処理を参照してください。