Dayanıklı İşlevler'de senaryo izleme - GitHub Sorun izleme örneği

İzleyici deseni, bir iş akışındaki esnek yinelenen işlemi ifade eder; örneğin, belirli koşullar karşılanana kadar yoklama. Bu makalede, izlemeyi uygulamak için Dayanıklı İşlevler kullanan bir örnek açıklanmaktadır.

Önkoşullar

Senaryoya genel bakış

Bu örnek GitHub deposundaki sorunların sayısını izler ve 3'ten fazla açık sorun olduğunda kullanıcıyı uyarır. Düzenli aralıklarla açılan sorun sayılarını istemek için düzenli süreölçerle tetiklenen bir işlev kullanabilirsiniz. Ancak, bu yaklaşımla ilgili bir sorun yaşam süresi yönetimidir. Yalnızca bir uyarı gönderilmesi gerekiyorsa, 3 veya daha fazla sorun algılandıktan sonra izleyicinin kendisini devre dışı bırakması gerekir. İzleme düzeni, diğer avantajların dışında kendi yürütmesini sonlandırabilir:

  • İzleyiciler zamanlamaya göre değil aralıklarla çalışır: zamanlayıcı tetikleyicisi saatte bir çalışır ; bir izleyici eylemler arasında bir saat bekler. Bir izleyicinin eylemleri belirtilmedikçe çakışmaz ve bu durum uzun süre çalışan görevler için önemli olabilir.
  • İzleyicilerin dinamik aralıkları olabilir: Bekleme süresi bazı koşullar temelinde değişebilir.
  • Bazı koşullar karşılandığında veya başka bir işlem tarafından sonlandırıldığında izleyiciler sonlandırılabilir.
  • İzleyiciler parametre alabilir. Örnek, aynı depo izleme işleminin istenen herhangi bir genel GitHub deposuna ve telefon numarasına nasıl uygulanabileceğini gösterir.
  • İzleyiciler ölçeklenebilir. Her izleyici bir düzenleme örneği olduğundan, yeni işlevler oluşturmak veya daha fazla kod tanımlamak zorunda kalmadan birden çok monitör oluşturulabilir.
  • İzleyiciler daha büyük iş akışlarıyla kolayca tümleştirilir. İzleyici, daha karmaşık bir düzenleme işlevinin bir bölümü veya alt düzenleme olabilir.

Yapılandırma

Twilio tümleştirmesini yapılandırma

Bu örnek, cep telefonuna SMS mesajları göndermek için Twilio hizmetini kullanmayı içerir. Azure İşlevleri zaten Twilio bağlaması aracılığıyla Twilio desteğine sahiptir ve örnek bu özelliği kullanır.

İhtiyacınız olan ilk şey bir Twilio hesabıdır. adresinde https://www.twilio.com/try-twilioücretsiz bir tane oluşturabilirsiniz. Bir hesabınız olduğunda aşağıdaki üç uygulama ayarlarını işlev uygulamanıza ekleyin.

Uygulama ayarı adı Değer açıklaması
TwilioAccountSid Twilio hesabınızın SID değeri
TwilioAuthToken Twilio hesabınız için kimlik doğrulama belirteci
TwilioPhoneNumber Twilio hesabınızla ilişkili telefon numarası. Bu, SMS mesajları göndermek için kullanılır.

İşlevler

Bu makalede, örnek uygulamada aşağıdaki işlevler açıklanmaktadır:

  • E3_Monitor: Düzenli aralıklarla çağıran E3_TooManyOpenIssuesbir düzenleyici işlevi. dönüş değeri E3_TooManyOpenIssues ise Trueöğesini çağırırE3_SendAlert.
  • E3_TooManyOpenIssues: Bir depoda çok fazla açık sorun olup olmadığını denetleen bir etkinlik işlevi . Tanıtım amacıyla, 3'ten fazla açık sorunun çok fazla olmasını göz önünde bulundurabiliriz.
  • E3_SendAlert: Twilio aracılığıyla SMS mesajı gönderen bir etkinlik işlevi.

E3_Monitor orchestrator işlevi

E3_Monitor işlevi orchestrator işlevleri için standard function.json işlevini kullanır.

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "context",
      "type": "orchestrationTrigger",
      "direction": "in"
    }
  ]
}

İşlevi uygulayan kod aşağıdadır:

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)

Bu düzenleyici işlevi aşağıdaki eylemleri gerçekleştirir:

  1. İzlenecek depoyu ve SMS bildirimi göndereceği telefon numarasını alır.
  2. İzleyicinin süre sonunu belirler. Örnek, kısaltma için sabit kodlanmış bir değer kullanır.
  3. İstenen depoda çok fazla açık sorun olup olmadığını belirlemek için E3_TooManyOpenIssues çağırır.
  4. Çok fazla sorun varsa, aramalar istenen telefon numarasına SMS bildirimi göndermek için E3_SendAlert .
  5. Sonraki yoklama aralığında düzenlemeyi sürdürmek için dayanıklı bir zamanlayıcı oluşturur. Örnek, kısaltma için sabit kodlanmış bir değer kullanır.
  6. Geçerli UTC saati izleyicinin son kullanma saatini geçene veya sms uyarısı gönderilene kadar çalışmaya devam eder.

Birden çok düzenleyici örneği, orchestrator işlevini birden çok kez çağırarak aynı anda çalıştırılabilir. İzlenecek depo ve SMS uyarısı gönderilecek telefon numarası belirtilebilir. Son olarak, zamanlayıcıyı beklerken orchestrator işlevinin çalışmadığını , dolayısıyla bunun için ücretlendirilmeyeceğini unutmayın.

E3_TooManyOpenIssues etkinlik işlevi

Diğer örneklerde olduğu gibi yardımcı etkinlik işlevleri de tetikleyici bağlamasını activityTrigger kullanan normal işlevlerdir. E3_TooManyOpenIssues işlevi, depoda şu anda açık olan sorunların listesini alır ve bunların "çok fazla" olup olmadığını belirler: örneğimize göre 3'ten fazla.

function.json aşağıdaki gibi tanımlanır:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "repoID",
      "type": "activityTrigger",
      "direction": "in"
    }
  ]
}

Ve uygulama burada.

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

E3_SendAlert etkinlik işlevi

E3_SendAlert işlevi, son kullanıcıya çözümü bekleyen en az 3 açık sorun olduğunu bildiren bir SMS iletisi göndermek için Twilio bağlamasını kullanır.

function.json basit:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "repoID",
      "type": "activityTrigger",
      "direction": "in"
    }
  ]
}

SMS iletisini gönderen kod da şu şekildedir:

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!"

Örneği çalıştırma

Bir GitHub hesabına ihtiyacınız olacaktır. Bu kaynakla, sorunları açabileceğiniz geçici bir genel depo oluşturun.

Örnekteki HTTP ile tetiklenen işlevleri kullanarak, aşağıdaki HTTP POST isteğini göndererek düzenlemeyi başlatabilirsiniz:

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" }

Örneğin GitHub kullanıcı adınız foo ve deponuz ise bar değeriniz "repo" olmalıdır "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}"}

E3_Monitor örneği başlatılır ve açık sorunlar için sağlanan depoyu sorgular. En az 3 açık sorun bulunursa, uyarı göndermek için bir etkinlik işlevini çağırır; aksi takdirde, bir süreölçer ayarlar. Süreölçerin süresi dolduğunda düzenleme devam eder.

Azure İşlevleri portalındaki işlev günlüklerine bakarak düzenlemenin etkinliğini görebilirsiniz.

[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...)

Düzenleme, zaman aşımına ulaşıldığında veya 3'ten fazla açık sorun algılandığında tamamlanır. API'yi terminate başka bir işlev içinde de kullanabilir veya yukarıdaki 202 yanıtında başvurulan terminatePostUri HTTP POST web kancasını çağırabilirsiniz. Web kancasını kullanmak için değerini erken sonlandırma nedeni ile değiştirin {text} . HTTP POST URL'si kabaca aşağıdaki gibi görünür:

POST https://{host}/runtime/webhooks/durabletask/instances/f6893f25acf64df2ab53a35c09d52635/terminate?reason=Because&taskHub=SampleHubVS&connection=Storage&code={systemKey}

Sonraki adımlar

Bu örnek, dayanıklı zamanlayıcılar ve koşullu mantık kullanarak dış kaynağın durumunu izlemek için Dayanıklı İşlevler nasıl kullanılacağını göstermiştir. Sonraki örnekte, insan etkileşimini işlemek için dış olayların ve dayanıklı zamanlayıcıların nasıl kullanılacağı gösterilmektedir.