Funktionsaufruf
Das Modul funcs ruft registrierte Funktionen synchron oder asynchron auf. Ein Executor kann Anfragekontext, Sicherheitsidentität und implementierungsspezifische Aufrufoptionen weitergeben. Diese Seite ist eine API-Referenz; Ziel-IDs, Argumente und Anwendungsdaten stehen für umgebenden Code.
Laden
local funcs = require("funcs")
call
Ruft eine registrierte Funktion synchron auf und wartet auf ihr Ergebnis.
local result, err = funcs.call("app.api:get_user", user_id)
if err then
return nil, err
end
print(result.name)
| Parameter | Typ | Beschreibung |
|---|---|---|
target |
string | Funktions-ID im Format "namespace:name" |
...args |
any | Argumente, die an die Funktion übergeben werden |
Gibt zurück: result, error
Das Ziel verwendet das Format namespace:name.
async
Startet einen Funktionsaufruf und gibt sofort ein Future zurück. Futures ermöglichen andere Arbeit während des Aufrufs und unterstützen mehrere gleichzeitige Aufrufe.
-- 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
| Parameter | Typ | Beschreibung |
|---|---|---|
target |
string | Funktions-ID im Format "namespace:name" |
...args |
any | Argumente, die an die Funktion übergeben werden |
Gibt zurück: Future, error
new
Erstellt einen Executor für Aufrufe mit benutzerdefiniertem Kontext, Sicherheitsidentität oder Aufrufoptionen.
local exec = funcs.new()
Gibt zurück: Executor
Executor
Ein Executor speichert Aufrufkontext und Optionen. Seine Konfigurationsmethoden geben neue Executor-Instanzen zurück, sodass eine Basiskonfiguration wiederverwendet werden kann.
with_context
Fügt anfragebezogene Werte hinzu, die der aufgerufenen Funktion zur Verfügung stehen, etwa Trace-IDs, Sitzungsdaten oder Feature-Flags.
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
| Parameter | Typ | Beschreibung |
|---|---|---|
values |
table | Schlüssel-Wert-Paare zum Hinzufügen zum Kontext |
Gibt zurück: Executor, error
with_actor
Setzt den Sicherheits-Actor für Autorisierungsprüfungen in der aufgerufenen Funktion.
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
| Parameter | Typ | Beschreibung |
|---|---|---|
actor |
Actor | Sicherheits-Actor (vom Security-Modul) |
Gibt zurück: Executor, error
with_scope
Setzt den Sicherheits-Scope für aufgerufene Funktionen. Scopes definieren die verfügbaren Berechtigungen für den Aufruf.
local security = require("security")
local scope = security.new_scope()
local exec, err = funcs.new():with_scope(scope)
if err then return nil, err end
| Parameter | Typ | Beschreibung |
|---|---|---|
scope |
Scope | Sicherheits-Scope (vom Security-Modul) |
Gibt zurück: Executor, error
with_options
Setzt Aufrufoptionen wie die Retry-Richtlinie oder das Overlay-Netzwerk. Optionen werden über etwaige voreingestellte Optionen des Ziel-Funktions-Eintrags gemergt.
-- Vorübergehende Fehler bis zu 5 Mal mit exponentiellem Backoff wiederholen
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
-- Alle Versuche fehlgeschlagen, oder der Fehler war nicht wiederholbar
end
| Parameter | Typ | Beschreibung |
|---|---|---|
options |
table | Aufrufoptionen |
| Option | Typ | Beschreibung |
|---|---|---|
retry.max_attempts |
int | Maximale Versuche einschließlich des ersten (1 deaktiviert Retry) |
retry.initial_delay |
int/duration | Verzögerung vor erstem Retry (ms oder Duration-String), Standard 100 |
retry.max_delay |
int/duration | Obergrenze der Backoff-Verzögerung (ms oder Duration-String), Standard 10s |
retry.backoff_factor |
number | Multiplikator, der die Verzögerung nach jedem Versuch skaliert, Standard 2.0 |
retry.jitter |
number | Anteil zufälligen Jitters pro Verzögerung, Standard 0.1 |
retry.retry_kinds |
string[] | Nur Fehler dieser Arten wiederholen; standardmäßig wird jede Art außer Invalid, PermissionDenied und Internal wiederholt |
retry.skip_kinds |
string[] | Fehler dieser Arten niemals wiederholen |
network |
string | Registry-ID eines Overlay-Netzwerks, über das der ausgehende Verkehr des Aufrufs geleitet wird; erfordert die Berechtigung network.select |
Nur wiederholbare Fehler lösen Retries aus; nicht wiederholbare Fehler treten sofort zutage. Temporal-Activity-Optionen sind in Activities beschrieben.
Die von der Runtime definierte Option ist:
| Erkannte Option | Typ | Beschreibung |
|---|---|---|
network |
string | Registry-ID des ausgehenden network.*-Entrys |
Gibt zurück: Executor, error
Die Auswahl eines Netzwerks erfordert die Berechtigung network.select für diese Netzwerk-ID.
call und async
Executor-Versionen von call und async, die den konfigurierten Kontext verwenden.
-- Wiederverwendbaren Executor mit Kontext aufbauen
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
Zusammenfassung von Future-Aufrufen
async() gibt ein Future zurück, das einen laufenden Aufruf darstellt. Die folgenden Methoden decken die Schritte zum Empfangen, Prüfen oder Abbrechen dieses Aufrufs ab. Siehe Future für die Referenz des Future-Objekts.
response und channel
Gibt den zugrunde liegenden Channel zum Empfangen des Ergebnisses zurück.
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()
}
Gibt zurück: Channel
Der Response-Channel signalisiert den Abschluss. Sobald er bereit ist, liefert future:result() den zwischengespeicherten Wert oder den Fehler der aufgerufenen Funktion.
is_complete
Nicht-blockierende Prüfung, ob das Future abgeschlossen ist.
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()
Gibt zurück: boolean
is_canceled
Gibt true zurück, wenn der Provider das Future als abgebrochen markiert hat. Beachten Sie die nachfolgende Einschränkung zur Abbruchbehandlung.
if future:is_canceled() then
print("Operation was canceled")
end
Gibt zurück: boolean
result
Gibt das zwischengespeicherte Ergebnis zurück, wenn abgeschlossen, oder nil wenn noch ausstehend.
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
Gibt zurück: Payload|table|nil, error|nil
error
Gibt den Fehler zurück, wenn das Future fehlgeschlagen ist.
local err, has_error = future:error()
if has_error then
print("Error kind:", err:kind())
end
Gibt zurück: error|nil, boolean
Diese Methode gibt bei einem fehlgeschlagenen Vorgang einen nicht wiederholbaren INTERNAL-Wrapper zurück. Verwenden Sie result(), um die ursprünglichen Fehlermetadaten der aufgerufenen Funktion zu erhalten.
cancel
Fordert den Abbruch der asynchronen Operation an.
local canceled, err = future:cancel()
if err then return nil, err end
Gibt zurück: boolean, error
cancel() und is_canceled() keinen stabilen providerübergreifenden Vertrag. Verwenden Sie Cancellation nicht für die Korrektheit der Anwendung; lassen Sie stattdessen lokal ein Timeout ablaufen und ignorieren Sie ein verspätetes Ergebnis, bis die Runtime die Provider-Cancellation trennt.
Parallele Operationen
Kombinieren Sie async mit channel.select, um mehrere Aufrufe gleichzeitig auszuführen und ihre Ergebnisse einzusammeln.
-- 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
Berechtigungen
Funktionsoperationen unterliegen der Sicherheitsrichtlinienauswertung.
| Aktion | Ressource | Beschreibung |
|---|---|---|
funcs.call |
Funktions-ID | Eine bestimmte Funktion aufrufen |
funcs.context |
context |
with_context() verwenden, um benutzerdefinierten Kontext zu setzen |
funcs.security |
security |
with_actor() oder with_scope() verwenden |
network.select |
Netzwerk-ID | with_options({network = ...}) verwenden, um ein Overlay-Netzwerk auszuwählen |
Fehler
| Bedingung | Art | Wiederholbar |
|---|---|---|
| Target leer | errors.INVALID |
nein |
| Namespace fehlt | errors.INVALID |
nein |
| Name fehlt | errors.INVALID |
nein |
| Berechtigung verweigert | errors.PERMISSION_DENIED |
nein |
| Async außerhalb eines Prozesses | errors.INTERNAL |
nein |
| Abonnement fehlgeschlagen | errors.INTERNAL |
nein |
| Dispatch zum Start des asynchronen Aufrufs fehlgeschlagen | errors.INTERNAL |
nein |
| Funktionsfehler | variiert | variiert |
Siehe Fehlerbehandlung für den Umgang mit Fehlern.