関数呼び出し

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を返す。ブロックしたくない長時間実行操作、または複数の操作を並行で実行したい場合に使用。

-- ブロックせずに重い計算を開始
local future, err = funcs.async("app.process:analyze_data", large_dataset)
if err then
    return nil, err
end

-- 計算実行中に他の処理を実行...

-- 準備ができたら結果を待機
local ch = future:response()
local payload, ok = ch:receive()
if ok then
    local result = payload:data()
end
パラメータ 説明
target string "namespace:name"形式の関数ID
...args any 関数に渡される引数

戻り値: Future, error

new

カスタムコンテキストで関数呼び出しを構築するための新しいExecutorを作成。リクエストコンテキストを伝播、セキュリティ資格情報を設定、またはタイムアウトを設定する必要がある場合に使用。

local exec = funcs.new()

戻り値: Executor, error

Executor

カスタムコンテキストオプション付きの関数呼び出しビルダー。メソッドは新しいExecutorインスタンスを返す(イミュータブルチェーン)ので、ベース設定を再利用可能。

with_context

呼び出される関数で利用可能になるコンテキスト値を追加。トレースID、ユーザーセッション、機能フラグなどのリクエストスコープデータを伝播するために使用。

-- 下流サービスにリクエストコンテキストを伝播
local exec = funcs.new():with_context({
    request_id = ctx.get("request_id"),
    feature_flags = {dark_mode = true}
})

local user, err = exec:call("app.api:get_user", user_id)
パラメータ 説明
values table コンテキストに追加するキー/値ペア

戻り値: Executor, error

with_actor

呼び出される関数での認可チェック用のセキュリティアクターを設定。特定のユーザーの代わりに関数を呼び出す場合に使用。

local security = require("security")
local actor = security.actor()  -- 現在のユーザーのアクターを取得

-- ユーザーの資格情報でadmin関数を呼び出し
local exec = funcs.new():with_actor(actor)
local result, err = exec:call("app.admin:delete_record", record_id)
if err and err:kind() == "PERMISSION_DENIED" then
    return nil, errors.new("PERMISSION_DENIED", "User cannot delete records")
end
パラメータ 説明
actor Actor セキュリティアクター(securityモジュールから)

戻り値: Executor, error

with_scope

呼び出される関数のセキュリティスコープを設定。スコープは呼び出しで利用可能な権限を定義。

local security = require("security")
local scope = security.new_scope()

local exec = funcs.new():with_scope(scope)
パラメータ 説明
scope Scope セキュリティスコープ(securityモジュールから)

戻り値: Executor, error

with_options

タイムアウトや優先度などの呼び出しオプションを設定。時間制限が必要な操作に使用。

-- 外部API呼び出しに5秒のタイムアウトを設定
local exec = funcs.new():with_options({timeout = 5000})
local result, err = exec:call("app.external:fetch_data", query)
if err then
    -- タイムアウトまたは他のエラーを処理
end
パラメータ 説明
options table 実装固有のオプション

戻り値: Executor, error

call / async

設定されたコンテキストを使用するExecutor版のcallとasync。

-- コンテキスト付きの再利用可能なexecutorを構築
local exec = funcs.new()
    :with_context({trace_id = "abc-123"})
    :with_options({timeout = 10000})

-- 同じコンテキストで複数の呼び出しを実行
local users, _ = exec:call("app.api:list_users")
local posts, _ = exec:call("app.api:list_posts")

Future

async()呼び出しによって返される。進行中の非同期操作を表す。

response / channel

結果を受信するための基礎となるチャネルを返す。

local future, _ = funcs.async("app.api:slow_operation", data)
local ch = future:response()  -- またはfuture:channel()

local result = channel.select {
    ch:case_receive(),
    timeout:case_receive()
}

戻り値: Channel

is_complete

Futureが完了したかどうかのノンブロッキングチェック。

while not future:is_complete() do
    -- 他の処理を実行
    time.sleep("100ms")
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
    print("Got:", value: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

非同期操作をキャンセル。

future:cancel()

並行操作

asyncとchannel.selectを使用して複数の操作を並行に実行。

-- 複数の操作を並行で開始
local f1, _ = funcs.async("app.api:get_user", user_id)
local f2, _ = funcs.async("app.api:get_orders", user_id)
local f3, _ = funcs.async("app.api:get_preferences", user_id)

-- チャネルを使用してすべての完了を待機
local user_ch = f1:channel()
local orders_ch = f2:channel()
local prefs_ch = f3:channel()

local results = {}
for i = 1, 3 do
    local r = channel.select {
        user_ch:case_receive(),
        orders_ch:case_receive(),
        prefs_ch:case_receive()
    }
    if r.channel == user_ch then
        results.user = r.value:data()
    elseif r.channel == orders_ch then
        results.orders = r.value:data()
    else
        results.prefs = r.value:data()
    end
end

権限

関数操作はセキュリティポリシー評価の対象。

アクション リソース 説明
funcs.call Function ID 特定の関数を呼び出し
funcs.context context with_context()を使用してカスタムコンテキストを設定
funcs.security security with_actor()またはwith_scope()を使用

エラー

条件 種別 再試行可能
Targetが空 errors.INVALID no
Namespaceがない errors.INVALID no
Nameがない errors.INVALID no
権限拒否 errors.PERMISSION_DENIED no
サブスクライブ失敗 errors.INTERNAL no
関数エラー 様々 様々

エラーの処理についてはエラー処理を参照。