Scénář monitorování v Durable Functions – ukázka monitorování problému na GitHubu
Model monitorování odkazuje na flexibilní opakující se proces v pracovním postupu – například dotazování, dokud nebudou splněny určité podmínky. Tento článek vysvětluje ukázku, která používá Durable Functions k implementaci monitorování.
Požadavky
Přehled scénáře
Tato ukázka monitoruje počet problémů v úložišti GitHub a upozorní uživatele, pokud existují více než 3 otevřené problémy. K vyžádání počtu otevřených problémů v pravidelných intervalech můžete použít běžnou funkci aktivovanou časovačem. Jedním z problémů s tímto přístupem je ale správa životnosti. Pokud se má odeslat jenom jedna výstraha, po zjištění 3 nebo více problémů se monitorování musí samo zakázat. Model monitorování může kromě dalších výhod ukončit vlastní provádění:
- Monitoruje spouštění v intervalech, ne v plánech: trigger časovače se spouští každou hodinu; Monitor čeká mezi akcemi jednu hodinu. Akce monitorování se nepřekrývají, pokud nejsou zadané, což může být důležité pro dlouhotrvající úlohy.
- Monitory můžou mít dynamické intervaly: čekací doba se může měnit v závislosti na určité podmínce.
- Monitorování se může ukončit, když je splněna některá podmínka, nebo může být ukončena jiným procesem.
- Monitory můžou přijímat parametry. Ukázka ukazuje, jak se stejný proces monitorování úložiště dá použít u libovolného požadovaného veřejného úložiště GitHub a telefonního čísla.
- Monitory jsou škálovatelné. Vzhledem k tomu, že každé monitorování je instance orchestrace, je možné vytvořit více monitorů bez nutnosti vytvářet nové funkce nebo definovat více kódu.
- Monitory se snadno integrují do větších pracovních postupů. Monitorování může být jedna část složitější funkce orchestrace nebo dílčí orchestrace.
Konfigurace
Konfigurace integrace Twilio
Tato ukázka zahrnuje použití služby Twilio k odesílání zpráv SMS na mobilní telefon. Azure Functions již podporuje Platformu Twilio prostřednictvím vazby Twilio a ukázka tuto funkci používá.
První věc, kterou potřebujete, je účet Twilio. Můžete si ho zdarma vytvořit na adrese https://www.twilio.com/try-twilio. Jakmile budete mít účet, přidejte do aplikace funkcí následující tři nastavení .
Název nastavení aplikace | Popis hodnoty |
---|---|
TwilioAccountSid | Identifikátor SID vašeho účtu Twilio |
TwilioAuthToken | Ověřovací token pro váš účet Twilio |
TwilioPhoneNumber | Telefonní číslo přidružené k vašemu účtu Twilio. Používá se k odesílání zpráv SMS. |
Funkce
Tento článek vysvětluje následující funkce v ukázkové aplikaci:
E3_Monitor
: Funkce orchestrátoru , která pravidelně voláE3_TooManyOpenIssues
. Volá,E3_SendAlert
pokud jeTrue
vrácená hodnota parametruE3_TooManyOpenIssues
.E3_TooManyOpenIssues
: Funkce aktivity , která kontroluje, jestli úložiště nemá příliš mnoho otevřených problémů. Pro účely ukázky považujeme za příliš mnoho otevřených problémů více než 3.E3_SendAlert
: Funkce aktivity, která odešle zprávu SMS prostřednictvím platformy Twilio.
funkce orchestrátoru E3_Monitor
Funkce E3_Monitor používá pro funkce orchestrátoru standardní function.json .
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
Tady je kód, který implementuje funkci:
import azure.durable_functions as df
from datetime import timedelta
from typing import Dict
def orchestrator_function(context: df.DurableOrchestrationContext):
monitoring_request: Dict[str, str] = context.get_input()
repo_url: str = monitoring_request["repo"]
phone: str = monitoring_request["phone"]
# Expiration of the repo monitoring
expiry_time = context.current_utc_datetime + timedelta(minutes=5)
while context.current_utc_datetime < expiry_time:
# Count the number of issues in the repo (the GitHub API caps at 30 issues per page)
too_many_issues = yield context.call_activity("E3_TooManyOpenIssues", repo_url)
# If we detect too many issues, we text the provided phone number
if too_many_issues:
# Extract URLs of GitHub issues, and return them
yield context.call_activity("E3_SendAlert", phone)
break
else:
# Reporting the number of statuses found
status = f"The repository does not have too many issues, for now ..."
context.set_custom_status(status)
# Schedule a new "wake up" signal
next_check = context.current_utc_datetime + timedelta(minutes=1)
yield context.create_timer(next_check)
return "Monitor completed!"
main = df.Orchestrator.create(orchestrator_function)
Tato funkce orchestrátoru provádí následující akce:
- Získá úložiště pro monitorování a telefonní číslo , na které odešle oznámení SMS.
- Určuje dobu vypršení platnosti monitorování. V ukázce se pro zkrácení používá pevně zakódovaná hodnota.
- Volání E3_TooManyOpenIssues k určení, jestli v požadovaném úložišti není příliš mnoho otevřených problémů.
- Pokud je problémů příliš mnoho, volání E3_SendAlert odeslat oznámení SMS na požadované telefonní číslo.
- Vytvoří trvalý časovač pro obnovení orchestrace v dalším intervalu dotazování. V ukázce se pro zkrácení používá pevně zakódovaná hodnota.
- Poběží až do doby, než aktuální čas UTC uplyne od doby vypršení platnosti monitorování nebo se odešle upozornění SMS.
Více instancí orchestrátoru lze spustit současně voláním funkce orchestrátoru vícekrát. Je možné zadat úložiště, které se má monitorovat, a telefonní číslo, do které se má odeslat upozornění SMS. Nakonec si všimněte, že funkce orchestrátoru při čekání na časovač neběží, takže se vám za ni nebudou účtovat poplatky.
funkce aktivity E3_TooManyOpenIssues
Stejně jako u jiných ukázek jsou pomocné funkce aktivit běžné funkce, které používají vazbu triggeru activityTrigger
. Funkce E3_TooManyOpenIssues získá seznam aktuálně otevřených problémů v úložišti a určí, jestli jich není příliš mnoho: více než 3 podle naší ukázky.
Soubor function.json je definovaný takto:
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "repoID",
"type": "activityTrigger",
"direction": "in"
}
]
}
A tady je implementace.
import requests
import json
def main(repoID: str) -> str:
# We use the GitHub API to count the number of open issues in the repo provided
# Note that the GitHub API only displays at most 30 issues per response, so
# the maximum number this activity will return is 30. That's enough for demo'ing purposes.
[user, repo] = repoID.split("/")
url = f"https://api.github.com/repos/{user}/{repo}/issues?state=open"
res = requests.get(url)
if res.status_code != 200:
error_message = f"Could not find repo {user} under {repo}! API endpoint hit was: {url}"
raise Exception(error_message)
issues = json.loads(res.text)
too_many_issues: bool = len(issues) >= 3
return too_many_issues
funkce aktivity E3_SendAlert
Funkce E3_SendAlert používá vazbu Platformy Twilio k odeslání zprávy SMS s oznámením koncovému uživateli, že existují alespoň 3 otevřené problémy, které čekají na vyřešení.
Jeho soubor function.json je jednoduchý:
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "repoID",
"type": "activityTrigger",
"direction": "in"
}
]
}
A tady je kód, který odešle ZPRÁVU SMS:
import json
import random
random.seed(10)
def main(phoneNumber: str, message):
payload = {
"body": f"Hey! You may want to check on your repo, there are too many open issues",
"to": phoneNumber
}
message.set(json.dumps(payload))
return "Message sent!"
Spuštění ukázky
Budete potřebovat účet GitHub . Pomocí něj vytvořte dočasné veřejné úložiště, do kterého můžete otevírat problémy.
Pomocí funkcí aktivovaných protokolem HTTP, které jsou součástí ukázky, můžete zahájit orchestraci odesláním následujícího požadavku HTTP POST:
POST https://{host}/orchestrators/E3_Monitor
Content-Length: 77
Content-Type: application/json
{ "repo": "<your GitHub handle>/<a new GitHub repo under your user>", "phone": "+1425XXXXXXX" }
Pokud je foo
například uživatelské jméno GitHubu a vaše úložiště, bar
pak by hodnota pro "repo"
hodnotu měla být "foo/bar"
.
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Location: https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635?taskHub=SampleHubVS&connection=Storage&code={SystemKey}
RetryAfter: 10
{"id": "f6893f25acf64df2ab53a35c09d52635", "statusQueryGetUri": "https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635?taskHub=SampleHubVS&connection=Storage&code={systemKey}", "sendEventPostUri": "https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635/raiseEvent/{eventName}?taskHub=SampleHubVS&connection=Storage&code={systemKey}", "terminatePostUri": "https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635/terminate?reason={text}&taskHub=SampleHubVS&connection=Storage&code={systemKey}"}
Spustí se instance E3_Monitor a dotáže se poskytnutého úložiště na otevřené problémy. Pokud jsou nalezeny alespoň 3 otevřené problémy, zavolá funkci aktivity k odeslání upozornění. jinak nastaví časovač. Po vypršení platnosti časovače se orchestrace obnoví.
Aktivitu orchestrace můžete zobrazit v protokolech funkcí na portálu Azure Functions.
[2020-12-04T18:24:30.007Z] Executing 'Functions.HttpStart' (Reason='This function was programmatically
called via the host APIs.', Id=93772f6b-f4f0-405a-9d7b-be9eb7a38aa6)
[2020-12-04T18:24:30.769Z] Executing 'Functions.E3_Monitor' (Reason='(null)', Id=058e656e-bcb1-418c-95b3-49afcd07bd08)
[2020-12-04T18:24:30.847Z] Started orchestration with ID = '788420bb31754c50acbbc46e12ef4f9c'.
[2020-12-04T18:24:30.932Z] Executed 'Functions.E3_Monitor' (Succeeded, Id=058e656e-bcb1-418c-95b3-49afcd07bd08, Duration=174ms)
[2020-12-04T18:24:30.955Z] Executed 'Functions.HttpStart' (Succeeded, Id=93772f6b-f4f0-405a-9d7b-be9eb7a38aa6, Duration=1028ms)
[2020-12-04T18:24:31.229Z] Executing 'Functions.E3_TooManyOpenIssues' (Reason='(null)', Id=6fd5be5e-7f26-4b0b-98df-c3ac39125da3)
[2020-12-04T18:24:31.772Z] Executed 'Functions.E3_TooManyOpenIssues' (Succeeded, Id=6fd5be5e-7f26-4b0b-98df-c3ac39125da3, Duration=555ms)
[2020-12-04T18:24:40.754Z] Executing 'Functions.E3_Monitor' (Reason='(null)', Id=23915e4c-ddbf-46f9-b3f0-53289ed66082)
[2020-12-04T18:24:40.789Z] Executed 'Functions.E3_Monitor' (Succeeded, Id=23915e4c-ddbf-46f9-b3f0-53289ed66082, Duration=38ms)
(...trimmed...)
Orchestrace se dokončí po dosažení časového limitu nebo zjištění více než 3 otevřených problémů. Můžete také použít terminate
rozhraní API v jiné funkci nebo vyvolat webhook terminatePostUri HTTP POST, na který se odkazuje v odpovědi 202 výše. Pokud chcete webhook použít, nahraďte {text}
textem důvod předčasného ukončení. Adresa URL protokolu HTTP POST bude vypadat zhruba takto:
POST https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635/terminate?reason=Because&taskHub=SampleHubVS&connection=Storage&code={systemKey}
Další kroky
Tato ukázka ukázala, jak pomocí Durable Functions monitorovat stav externího zdroje pomocí trvalých časovačů a podmíněné logiky. Další ukázka ukazuje, jak používat externí události a odolné časovače ke zpracování lidské interakce.