التنسيقات هي سير عمل طويل الأمد بحالة يمكنك تشغيلها، الاستعلام، تعليقها، استئنافها، وإنهاؤها باستخدام واجهات برمجة تطبيقات إدارة مدمجة. في Durable Functions، يكشف ربط عميل orchestration هذه واجهات برمجة التطبيقات. في مجموعات تطوير المهام الدائمة، تتوفر هذه العمليات من خلال الفئة DurableTaskClient . تغطي هذه المقالة جميع عمليات إدارة المثيلات المدعومة لكلا المنصتين.
نصيحة
جدولة المهام المتطورة Azure هي الواجهة الخلفية الموصى بها لكل من Durable Functions وحزمة تطوير المهام الدائمة، وتوفر تجربة مدارة بالكامل بدون خوادم لتشغيل سير العمل المتطور على نطاق واسع.
بدء مثيلات
طريقة start-new (أو schedule-new) على عميل التوزيع تبدأ نسخة تنسيق جديدة. داخليا، تكتب هذه الطريقة رسالة إلى الخلفية المعدة (مثل Durable Task Scheduler أو Azure Storage) ثم تعيد. تقوم هذه الرسالة بتفعيل بدء التوزيع الموسيقي بالاسم المحدد.
إليك المعايير لبدء نسخة جديدة من التوزيع الأوركسترالي:
-
الاسم: اسم دالة المنسق التي يجب جدولتها.
-
الإدخال: أي بيانات JSON قابلة للتسلسل يجب تمريرها كمدخل إلى دالة المنسق.
-
InstanceId: (اختياري) المعرف الفريد للمثيل. إذا لم تحدد هذه المعلمة، فإن الأسلوب يستخدم معرفا عشوائيا.
نصيحة
استخدم معرفا عشوائيا لمعرف المثيل كلما أمكن ذلك. تساعد معرفات العينات العشوائية في ضمان توزيع متساو للحمل عند توسيع وظائف الأوركستراتور عبر عدة أجهزة افتراضية. الوقت المناسب لاستخدام معرفات العينات غير العشوائية هو عندما يأتي المعرف من مصدر خارجي أو عندما تقوم بتنفيذ نمط التنسيق الأحادي .
- الاسم: اسم الفرقة الموسيقية التي يجب جدولتها.
-
الإدخال: أي بيانات قابلة للتسلسل-JSON يجب تمريرها كمدخل إلى التوزيع الموسيقي.
-
InstanceId: (اختياري) المعرف الفريد للمثيل. إذا لم تحدد هذه المعلمة، فإن الأسلوب يستخدم معرفا عشوائيا.
نصيحة
استخدم معرفا عشوائيا لمعرف المثيل كلما أمكن ذلك. تساعد معرفات العينات العشوائية في ضمان توزيع متساو للحمل عند توسيع التوزيع عبر عدة أجهزة افتراضية. الوقت المناسب لاستخدام معرفات العينات غير العشوائية هو عندما يأتي المعرف من مصدر خارجي أو عندما تقوم بتنفيذ نمط التنسيق الأحادي .
تبدأ دالة المثال التالية نسخة توزيع جديدة:
[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
[QueueTrigger("start-queue")] string input,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
string instanceId = await starter.StartNewAsync("HelloWorld", input);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
ما لم يتم تحديد خلاف ذلك، تستخدم الأمثلة الموجودة في هذه الصفحة مشغل HTTP مع function.jsonالتالية .
function.json
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": ["post"]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
],
"disabled": false
}
ملحوظة
يستهدف هذا المثال Durable Functions الإصدار 2.x. في الإصدار 1.x، استخدم orchestrationClient بدلا من durableClient.
index.js
const df = require("durable-functions");
module.exports = async function(context, input) {
const client = df.getClient(context);
const instanceId = await client.startNew("HelloWorld", undefined, input);
context.log(`Started orchestration with ID = ${instanceId}.`);
};
ما لم يتم تحديد خلاف ذلك، تستخدم الأمثلة الموجودة في هذه الصفحة مشغل HTTP مع function.jsonالتالية .
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": ["post"]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
],
"disabled": false
}
ملحوظة
يستهدف هذا المثال Durable Functions الإصدار 2.x. في الإصدار 1.x، استخدم orchestrationClient بدلا من durableClient.
__init__.py
import logging
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new('HelloWorld', None, None)
logging.log(f"Started orchestration with ID = ${instance_id}.")
ما لم يتم تحديد خلاف ذلك، تستخدم الأمثلة الموجودة في هذه الصفحة مشغل HTTP مع function.jsonالتالية .
function.json
{
"bindings": [
{
"name": "Request",
"type": "httpTrigger",
"direction": "in",
"methods": ["post"]
},
{
"name": "Response",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
],
"disabled": false
}
ملحوظة
يستهدف هذا المثال Durable Functions الإصدار 2.x. في الإصدار 1.x، استخدم orchestrationClient بدلا من durableClient.
run.ps1
param($Request, $TriggerMetadata)
$InstanceId = Start-DurableOrchestration -FunctionName 'HelloWorld'
Write-Host "Started orchestration with ID = '$InstanceId'"
@FunctionName("HelloWorldQueueTrigger")
public void helloWorldQueueTrigger(
@QueueTrigger(name = "input", queueName = "start-queue", connection = "Storage") String input,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
final ExecutionContext context) {
DurableTaskClient client = durableContext.getClient();
String instanceID = client.scheduleNewOrchestrationInstance("HelloWorld");
context.getLogger().info("Scheduled orchestration with ID = " + instanceID);
}
للانتظار حتى يبدأ الموزع قبل العودة من الفعالية، استخدم الطريقة waitForInstanceStart() .
// wait up to 30 seconds for the scheduled orchestration to enter the "Running" state
client.waitForInstanceStart(instanceID, Duration.ofSeconds(30));
مهم
حاليا، حزمة تطوير المهام الدائمة PowerShell غير متوفرة.
يوضح الكود التالي كيفية بدء نسخة تنسيقية جديدة باستخدام مجموعات SDK للمهام الدائمة:
using Microsoft.DurableTask.Client;
// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloWorld", input);
Console.WriteLine($"Started orchestration with ID = '{instanceId}'.");
// Optionally, wait for the orchestration to start
OrchestrationMetadata metadata = await client.WaitForInstanceStartAsync(instanceId, timeout: TimeSpan.FromSeconds(30));
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Schedule a new orchestration instance
instance_id = client.schedule_new_orchestration(hello_world, input=input_data)
print(f"Started orchestration with ID = '{instance_id}'.")
# Optionally, wait for the orchestration to start
state = client.wait_for_orchestration_start(instance_id, timeout=30)
import com.microsoft.durabletask.DurableTaskClient;
// Schedule a new orchestration instance
String instanceId = client.scheduleNewOrchestrationInstance("HelloWorld", input);
System.out.println("Started orchestration with ID = '" + instanceId + "'.");
// Optionally, wait for the orchestration to start
OrchestrationMetadata metadata = client.waitForInstanceStart(instanceId, Duration.ofSeconds(30), false);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// Schedule a new orchestration instance
const instanceId = await client.scheduleNewOrchestration("HelloWorld", input);
console.log(`Started orchestration with ID = '${instanceId}'.`);
// Optionally, wait for the orchestration to start
const state = await client.waitForOrchestrationStart(instanceId, false, 30);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
مثيلات الاستعلام
بعد بدء نسخ تنسيق جديدة، من المرجح أنك بحاجة للاستعلام عن حالة وقت التشغيل الخاصة بها لمعرفة ما إذا كانت تعمل أو مكتملة أو فاشلة.
طريقة الحصول على الحالة على عميل التنسيق تعيد حالة مثيل التنسيق.
يأخذ instanceId (مطلوب) و showHistory (اختياري) showHistoryOutput و(اختياري) و showInput (اختياري) كمعلمات.
-
showHistory: إذا تم تعيينها إلى true، تحتوي الاستجابة على محفوظات التنفيذ.
-
showHistoryOutput: إذا تم تعيينه إلى true، يحتوي سجل التنفيذ على مخرجات النشاط.
-
showInput: إذا تم تعيينه على false، فإن الاستجابة لا تحتوي على مدخل الدالة. القيمة الافتراضية هي true.
يقوم الأسلوب بإرجاع كائن بالخصائص التالية:
-
الاسم: اسم دالة المنسق.
-
InstanceId: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس
instanceId الإدخال).
-
CreatedTime: الوقت الذي تبدأ فيه وظيفة الموزع في العمل.
-
LastUpdatedTime: الوقت الذي يتوقف فيه التوزيع الأوركسترالي إلى نقاط التفتيش.
-
الإدخال: إدخال الدالة كقيمة JSON. هذا الحقل غير مأهول إذا
showInput كان .false
-
CustomStatus: حالة التزامن المخصص بتنسيق JSON.
-
المخرج: مخرج الدالة كقيمة JSON (إذا اكتملت الدالة). إذا فشلت وظيفة المنسق، تشمل هذه الخاصية تفاصيل الفشل. إذا تم تعليق أو إنهاء وظيفة المنسق، فإن هذه الخاصية تشمل سبب التعليق أو الإنهاء (إن وجد).
-
RuntimeStatus: إحدى القيم التالية:
-
قيد الانتظار: تم جدولة النسخة لكنها لم تبدأ بعد في التشغيل.
-
التشغيل: النسخة تعمل.
-
اكتمل: تم الانتهاء من النسخة بشكل طبيعي.
-
تابع كجديد: أعادت النسخة تشغيل نفسها بتاريخ جديد. هذه الحالة هي حالة عابرة.
-
فشل: فشل المثيل مع وجود خطأ.
-
تم إنهاءه: توقفت الحالة فجأة.
-
معلق: يتم تعليق النسخة ويمكن استئنافها في وقت لاحق.
-
المحفوظات: محفوظات تنفيذ التنسيق. يتم ملء هذا الحقل فقط إذا
showHistory تم تعيينه إلى true.
-
showHistory: إذا تم تعيينها إلى true، تحتوي الاستجابة على محفوظات التنفيذ.
-
showHistoryOutput: إذا تم تعيينه إلى true، يحتوي سجل التنفيذ على مخرجات النشاط.
-
showInput: إذا تم ضبطه على false، فإن الاستجابة لا تحتوي على مدخلات التوزيع الموسيقي. القيمة الافتراضية هي true.
يقوم الأسلوب بإرجاع كائن بالخصائص التالية:
-
الاسم: اسم الفرقة الموسيقية.
-
InstanceId: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس
instanceId الإدخال).
-
CreatedTime: الوقت الذي يبدأ فيه التوزيع الأوركسترالي بالتشغيل.
-
LastUpdatedTime: الوقت الذي يتوقف فيه التوزيع الأوركسترالي إلى نقاط التفتيش.
-
الإدخال: إدخال التوزيع كقيمة JSON. هذا الحقل غير مأهول إذا
showInput كان .false
-
CustomStatus: حالة التزامن المخصص بتنسيق JSON.
-
المخرج: مخرج التوزيع كقيمة JSON (إذا اكتمل التوزيع الموسيقي). إذا فشل التنسيق، تشمل هذه الخاصية تفاصيل الفشل. إذا تم تعليق أو إنهاء التنظيم، فإن هذه الخاصية تشمل سبب الإيقاف أو الإنهاء (إن وجد).
-
RuntimeStatus: إحدى القيم التالية:
-
قيد الانتظار: تم جدولة النسخة لكنها لم تبدأ بعد في التشغيل.
-
التشغيل: النسخة تعمل.
-
اكتمل: تم الانتهاء من النسخة بشكل طبيعي.
-
تابع كجديد: أعادت النسخة تشغيل نفسها بتاريخ جديد. هذه الحالة هي حالة عابرة.
-
فشل: فشل المثيل مع وجود خطأ.
-
تم إنهاءه: توقفت الحالة فجأة.
-
معلق: يتم تعليق النسخة ويمكن استئنافها في وقت لاحق.
-
المحفوظات: محفوظات تنفيذ التنسيق. يتم ملء هذا الحقل فقط إذا
showHistory تم تعيينه إلى true.
ملحوظة
لا يتم وضع علامة على الموزع حتى Completed تنتهي جميع مهامه المجدولة ويعود الموزع. بعبارة أخرى، ليس كافيا أن يصل الموزع إلى بيانه return ليتم تمييزه ك Completed. وهذا مهم بشكل خاص في الحالات التي WhenAny يستخدم؛ غالبا return ما يكون هؤلاء المنظمون قبل تنفيذ جميع المهام المجدولة.
تعود هذه الطريقة ب null (.NET و Java)، undefined (جافا سكريبت)، أو None (Python) إذا لم يكن المثيل موجودا.
[FunctionName("GetStatus")]
public static async Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("check-status-queue")] string instanceId)
{
DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
// do something based on the current status.
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
const status = await client.getStatus(instanceId);
// do something based on the current status.
// example: if status.runtimeStatus === df.OrchestrationRuntimeStatus.Running: ...
}
لتكوين function.json ، انظر مثيلات التشغيل.
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
status = await client.get_status(instance_id)
# do something based on the current status
# example: if (existing_instance.runtime_status is df.OrchestrationRuntimeStatus.Running) { ...
param($Request, $TriggerMetadata)
# Get instanceid from body
$InstanceId = $Request.Body.InstanceId
$Status = Get-DurableStatus -InstanceId $InstanceId -ShowHistory -ShowHistoryOutput -ShowInput
Write-Host "Status: $($Status | ConvertTo-Json)"
# Do something based on status
# example: if ($Status.runtimeStatus -eq 'Running') { ... }
@FunctionName("GetStatus")
public void getStatus(
@QueueTrigger(name = "instanceID", queueName = "check-status-queue", connection = "Storage") String instanceID,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
final ExecutionContext context) {
DurableTaskClient client = durableContext.getClient();
OrchestrationMetadata metadata = client.getInstanceMetadata(instanceID, false);
if (metadata != null) {
OrchestrationRuntimeStatus status = metadata.getRuntimeStatus();
switch (status) {
// do something based on the current status
}
}
}
using Microsoft.DurableTask.Client;
// Get the status of an orchestration instance
OrchestrationMetadata? metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true);
if (metadata != null)
{
OrchestrationRuntimeStatus status = metadata.RuntimeStatus;
// do something based on the current status
}
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Get the status of an orchestration instance
state = client.get_orchestration_state(instance_id, fetch_payloads=True)
if state is not None:
status = state.runtime_status
# do something based on the current status
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.OrchestrationMetadata;
// Get the status of an orchestration instance
OrchestrationMetadata metadata = client.getInstanceMetadata(instanceId, true);
if (metadata != null) {
OrchestrationRuntimeStatus status = metadata.getRuntimeStatus();
// do something based on the current status
}
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// Get the status of an orchestration instance
const state = await client.getOrchestrationState(instanceId, true);
if (state) {
const status = state.runtimeStatus;
// do something based on the current status
}
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
الاستعلام عن جميع المثيلات
يمكنك استخدام واجهات برمجة التطبيقات بلغتك SDK للاستعلام عن حالات جميع مثيلات التنسيق في مركز المهام. تقوم واجهة برمجة التطبيقات هذه "list-instances" أو "get-status" بإرجاع قائمة الكائنات التي تمثل مثيلات التنسيق المطابقة لمعلمات الاستعلام.
[FunctionName("GetAllStatus")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient client,
ILogger log)
{
var noFilter = new OrchestrationStatusQueryCondition();
OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
noFilter,
CancellationToken.None);
foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
{
log.LogInformation(JsonConvert.SerializeObject(instance));
}
// Note: ListInstancesAsync only returns the first page of results.
// To request additional pages provide the result.ContinuationToken
// to the OrchestrationStatusQueryCondition's ContinuationToken property.
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, req) {
const client = df.getClient(context);
const instances = await client.getStatusAll();
instances.forEach((instance) => {
context.log(JSON.stringify(instance));
});
};
لتكوين function.json، انظر نسخ التشغيل.
import logging
import json
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instances = await client.get_status_all()
for instance in instances:
logging.log(json.dumps(instance))
لتكوين function.json، انظر نسخ التشغيل.
ملحوظة
لا يدعم PowerShell هذه الميزة حاليا، لكن يمكنك تحقيقها باستخدام واجهة برمجة تطبيقات Durable Functions HTTP.
@FunctionName("GetAllStatus")
public String getAllStatus(
@HttpTrigger(name = "req", methods = {HttpMethod.GET}) HttpRequestMessage<?> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
DurableTaskClient client = durableContext.getClient();
OrchestrationStatusQuery noFilter = new OrchestrationStatusQuery();
OrchestrationStatusQueryResult result = client.queryInstances(noFilter);
return "Found " + result.getOrchestrationState().size() + " orchestrations.";
}
using Microsoft.DurableTask.Client;
// Query all orchestration instances
AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(new OrchestrationQuery());
await foreach (OrchestrationMetadata instance in instances)
{
Console.WriteLine(instance.InstanceId);
}
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Query all orchestration instances
instances = client.list_orchestrations()
for instance in instances:
print(instance.instance_id)
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.OrchestrationStatusQuery;
import com.microsoft.durabletask.OrchestrationStatusQueryResult;
// Query all orchestration instances
OrchestrationStatusQuery query = new OrchestrationStatusQuery();
OrchestrationStatusQueryResult result = client.queryInstances(query);
for (OrchestrationMetadata instance : result.getOrchestrationState()) {
System.out.println(instance.getInstanceId());
}
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// Query all orchestration instances
const instances = client.getAllInstances();
for await (const instance of instances) {
console.log(instance.instanceId);
}
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
مثيلات الاستعلام مع عوامل التصفية
ماذا لو لم تكن بحاجة لكل المعلومات التي توفرها استعلام الحالة القياسية؟ على سبيل المثال، ماذا لو كنت تبحث فقط عن وقت إنشاء الأوركسترا أو حالة مدة تشغيل الأوركسترا؟ ضيق نطاق استعلامك بتطبيق فلاتر.
[FunctionName("QueryStatus")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient client,
ILogger log)
{
// Get the first 100 running or pending instances that were created between 7 and 1 days ago
var queryFilter = new OrchestrationStatusQueryCondition
{
RuntimeStatus = new[]
{
OrchestrationRuntimeStatus.Pending,
OrchestrationRuntimeStatus.Running,
},
CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
PageSize = 100,
};
OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
queryFilter,
CancellationToken.None);
foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
{
log.LogInformation(JsonConvert.SerializeObject(instance));
}
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, req) {
const client = df.getClient(context);
const runtimeStatus = [
df.OrchestrationRuntimeStatus.Completed,
df.OrchestrationRuntimeStatus.Running,
];
const instances = await client.getStatusBy(
new Date(2021, 3, 10, 10, 1, 0),
new Date(2021, 3, 10, 10, 23, 59),
runtimeStatus
);
instances.forEach((instance) => {
context.log(JSON.stringify(instance));
});
};
راجع بدء مثيلات لتكوين function.json.
import logging
from datetime import datetime
import json
import azure.functions as func
import azure.durable_functions as df
from azure.durable_functions.models.OrchestrationRuntimeStatus import OrchestrationRuntimeStatus
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
runtime_status = [OrchestrationRuntimeStatus.Completed, OrchestrationRuntimeStatus.Running]
instances = await client.get_status_by(
datetime(2021, 3, 10, 10, 1, 0),
datetime(2021, 3, 10, 10, 23, 59),
runtime_status
)
for instance in instances:
logging.log(json.dumps(instance))
ملحوظة
هذه الميزة غير مدعومة حاليا في PowerShell، لكن يمكنك تحقيقها باستخدام واجهة برمجة تطبيقات Durable Functions HTTP.
@FunctionName("GetRunningInstances")
public String getRunningInstances(
@HttpTrigger(name = "req", methods = {HttpMethod.GET}) HttpRequestMessage<?> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
DurableTaskClient client = durableContext.getClient();
OrchestrationStatusQuery filter = new OrchestrationStatusQuery()
.setRuntimeStatusList(List.of(OrchestrationRuntimeStatus.PENDING, OrchestrationRuntimeStatus.RUNNING))
.setCreatedTimeFrom(Instant.now().minus(Duration.ofDays(7)))
.setCreatedTimeTo(Instant.now().minus(Duration.ofDays(1)));
OrchestrationStatusQueryResult result = client.queryInstances(filter);
return "Found " + result.getOrchestrationState().size() + " orchestrations.";
}
using Microsoft.DurableTask.Client;
// Get running or pending instances created in the last 7 days
var query = new OrchestrationQuery
{
Statuses = new[] { OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.Pending },
CreatedFrom = DateTime.UtcNow.AddDays(-7),
CreatedTo = DateTime.UtcNow.AddDays(-1),
PageSize = 100
};
AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(query);
await foreach (OrchestrationMetadata instance in instances)
{
Console.WriteLine($"{instance.InstanceId}: {instance.RuntimeStatus}");
}
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
from datetime import datetime, timedelta
# Get running or pending instances created in the last 7 days
instances = client.list_orchestrations(
created_time_from=datetime.utcnow() - timedelta(days=7),
created_time_to=datetime.utcnow() - timedelta(days=1),
runtime_status=['RUNNING', 'PENDING']
)
for instance in instances:
print(f"{instance.instance_id}: {instance.runtime_status}")
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.OrchestrationStatusQuery;
import com.microsoft.durabletask.OrchestrationRuntimeStatus;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
// Get running or pending instances created in the last 7 days
OrchestrationStatusQuery filter = new OrchestrationStatusQuery()
.setRuntimeStatusList(List.of(OrchestrationRuntimeStatus.PENDING, OrchestrationRuntimeStatus.RUNNING))
.setCreatedTimeFrom(Instant.now().minus(Duration.ofDays(7)))
.setCreatedTimeTo(Instant.now().minus(Duration.ofDays(1)));
OrchestrationStatusQueryResult result = client.queryInstances(filter);
for (OrchestrationMetadata instance : result.getOrchestrationState()) {
System.out.println(instance.getInstanceId() + ": " + instance.getRuntimeStatus());
}
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
import { OrchestrationStatus } from "@microsoft/durabletask-js";
const client = createAzureManagedClient(connectionString);
// Get running or pending instances created in the last 7 days
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
const instances = client.getAllInstances({
statuses: [OrchestrationStatus.RUNNING, OrchestrationStatus.PENDING],
createdFrom: sevenDaysAgo,
createdTo: oneDayAgo,
});
for await (const instance of instances) {
console.log(`${instance.instanceId}: ${instance.runtimeStatus}`);
}
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
إنهاء المثيلات
إذا كان لديك حالة توزيع موسيقي تستغرق وقتا طويلا للتشغيل، أو تحتاج لإيقافها قبل اكتمالها لأي سبب، يمكنك إنهاؤها.
المعاملتان لواجهة برمجة التطبيقات النهائية هما معرف المثيل وسلسلة السبب ، اللذان يكتبان إلى السجلات وإلى حالة المثيل.
[FunctionName("TerminateInstance")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("terminate-queue")] string instanceId)
{
string reason = "Found a bug";
return client.TerminateAsync(instanceId, reason);
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
const reason = "Found a bug";
return client.terminate(instanceId, reason);
};
راجع بدء مثيلات لتكوين function.json.
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
reason = "Found a bug"
return await client.terminate(instance_id, reason)
param($Request, $TriggerMetadata)
# Get instance id from body
$InstanceId = $Request.Body.InstanceId
$Reason = 'Found a bug'
Stop-DurableOrchestration -InstanceId $InstanceId -Reason $Reason
@FunctionName("TerminateInstance")
public void terminateInstance(
@HttpTrigger(name = "req", methods = {HttpMethod.POST}) HttpRequestMessage<String> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
String instanceID = req.getBody();
String reason = "Found a bug";
durableContext.getClient().terminate(instanceID, reason);
}
using Microsoft.DurableTask.Client;
string reason = "Found a bug";
await client.TerminateInstanceAsync(instanceId, reason);
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
reason = "Found a bug"
client.terminate_orchestration(instance_id, reason=reason)
import com.microsoft.durabletask.DurableTaskClient;
String reason = "Found a bug";
client.terminate(instanceId, reason);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
const reason = "Found a bug";
await client.terminateOrchestration(instanceId, reason);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
النسخة المنتهية تنتقل في النهاية إلى Terminated الحالة. لكن هذا الانتقال لا يحدث فورا. بدلا من ذلك، يتم وضع عملية الإنهاء في قائمة الانتظار في مركز المهام مع عمليات أخرى لهذا النموذج. يمكنك استخدام واجهات برمجة تطبيقات استعلام المثيل لمعرفة متى وصل مثيل منتهى Terminated بالفعل إلى الحالة.
ملحوظة
لا يتم نشر إنهاء المثيل حاليا. وظائف النشاط والتنسيقات الفرعية تعمل حتى الاكتمال، بغض النظر عما إذا كنت تنهي نسخة التوزيع التي استدعتها.
تعليق واستئناف الحالات
تعليق التوزيع يسمح لك بإيقاف توزيع موسيقي مستمر. على عكس إنهاء التوزيع الأوركسترالي، يمكنك استئناف التوزيع الموسيقي المعلق لاحقا.
المعلمتان لواجهة برمجة تطبيقات الإيقاف المؤقت هي معرف مثيل وسلسلة سبب، والتي تتم كتابتها إلى السجلات وإلى حالة المثيل.
[FunctionName("SuspendResumeInstance")]
public static async Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("suspend-resume-queue")] string instanceId)
{
// To suspend an orchestration
string suspendReason = "Need to pause workflow";
await client.SuspendAsync(instanceId, suspendReason);
// To resume an orchestration
string resumeReason = "Continue workflow";
await client.ResumeAsync(instanceId, resumeReason);
}
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
// To suspend an orchestration
const suspendReason = "Need to pause workflow";
await client.suspend(instanceId, suspendReason);
// To resume an orchestration
const resumeReason = "Continue workflow";
await client.resume(instanceId, resumeReason);
};
import azure.functions as func
import azure.durable_functions as df
from datetime import timedelta
async def main(req: func.HttpRequest, starter: str, instance_id: str):
client = df.DurableOrchestrationClient(starter)
# To suspend an orchestration
suspend_reason = "Need to pause workflow"
await client.suspend(instance_id, suspend_reason)
# To resume an orchestration
resume_reason = "Continue workflow"
await client.resume(instance_id, resume_reason)
param($Request, $TriggerMetadata)
$InstanceId = $Request.Body.InstanceId
# To suspend an orchestration
$SuspendReason = 'Need to pause workflow'
Suspend-DurableOrchestration -InstanceId $InstanceId -Reason $SuspendReason
# To resume an orchestration
$ResumeReason = 'Continue workflow'
Resume-DurableOrchestration -InstanceId $InstanceId -Reason $ResumeReason
@FunctionName("SuspendResumeInstance")
public void suspendResumeInstance(
@HttpTrigger(name = "req", methods = {HttpMethod.POST}) HttpRequestMessage<String> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
String instanceID = req.getBody();
DurableTaskClient client = durableContext.getClient();
// To suspend an orchestration
String suspendReason = "Need to pause workflow";
client.suspendInstance(instanceID, suspendReason);
// To resume an orchestration
String resumeReason = "Continue workflow";
client.resumeInstance(instanceID, resumeReason);
}
using Microsoft.DurableTask.Client;
// To suspend an orchestration
string suspendReason = "Need to pause workflow";
await client.SuspendInstanceAsync(instanceId, suspendReason);
// To resume an orchestration
string resumeReason = "Continue workflow";
await client.ResumeInstanceAsync(instanceId, resumeReason);
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# To suspend an orchestration
suspend_reason = "Need to pause workflow"
client.suspend_orchestration(instance_id, reason=suspend_reason)
# To resume an orchestration
resume_reason = "Continue workflow"
client.resume_orchestration(instance_id, reason=resume_reason)
import com.microsoft.durabletask.DurableTaskClient;
// To suspend an orchestration
String suspendReason = "Need to pause workflow";
client.suspendInstance(instanceId, suspendReason);
// To resume an orchestration
String resumeReason = "Continue workflow";
client.resumeInstance(instanceId, resumeReason);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// To suspend an orchestration
await client.suspendOrchestration(instanceId);
// To resume an orchestration
await client.resumeOrchestration(instanceId);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
تنتقل الحالة المعلقة في النهاية إلى Suspended الولاية. ومع ذلك، هذا الانتقال لا يحدث فورا. بدلا من ذلك، يتم وضع عملية التعليق في قائمة الانتظار في مركز المهام مع العمليات الأخرى في تلك الحالة. استخدم واجهات برمجة تطبيقات استعلام المثيل لمعرفة متى وصل المثيل الجاري فعليا إلى Suspended الحالة.
عند استئناف الموزع المعلق، يتغير حالته مرة أخرى إلى Running.
إرسال الأحداث إلى المثيلات
في بعض السيناريوهات، تحتاج وظائف المنسق إلى الانتظار والاستماع للأحداث الخارجية. من الأمثلة التي يكون فيها هذا النهج مفيدا سيناريوهات المراقبةوالتفاعل البشري .
في بعض السيناريوهات، تحتاج التوزيعات إلى الانتظار والاستماع للأحداث الخارجية. من الأمثلة التي يكون فيها هذا النهج مفيدا سيناريوهات المراقبةوالتفاعل البشري .
يمكنك إرسال إشعارات الأحداث إلى الإصدارات الجارية باستخدام واجهة برمجة تطبيقات Raise Event الخاصة بعميل التنسيق. يمكن للتنسيقات الاستماع إلى هذه الأحداث والاستجابة لها باستخدام انتظار واجهة برمجة تطبيقات منسق الأحداث الخارجية .
المعايير لحدث الرفع هي:
-
معرف المثيل: المعرف الفريد للمثيل.
-
اسم الحدث: اسم الحدث المراد إرساله.
-
بيانات الحدث: حمولة JSON قابلة للتسلسل لإرسالها إلى المثيل.
[FunctionName("RaiseEvent")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("event-queue")] string instanceId)
{
int[] eventData = new int[] { 1, 2, 3 };
return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
const eventData = [ 1, 2, 3 ];
return client.raiseEvent(instanceId, "MyEvent", eventData);
};
راجع بدء مثيلات لتكوين function.json.
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
event_data = [1, 2 ,3]
return await client.raise_event(instance_id, 'MyEvent', event_data)
param($Request, $TriggerMetadata)
# Get instance id from body
$InstanceId = $Request.Body.InstanceId
$EventName = 'MyEvent'
$EventData = @(1,2,3)
Send-DurableExternalEvent -InstanceId $InstanceId -EventName $EventName -EventData $EventData
@FunctionName("RaiseEvent")
public void raiseEvent(
@HttpTrigger(name = "req", methods = {HttpMethod.POST}) HttpRequestMessage<String> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
String instanceID = req.getBody();
String eventName = "MyEvent";
int[] eventData = { 1, 2, 3 };
durableContext.getClient().raiseEvent(instanceID, eventName, eventData);
}
using Microsoft.DurableTask.Client;
int[] eventData = new int[] { 1, 2, 3 };
await client.RaiseEventAsync(instanceId, "MyEvent", eventData);
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
event_data = [1, 2, 3]
client.raise_orchestration_event(instance_id, "MyEvent", event_data)
import com.microsoft.durabletask.DurableTaskClient;
int[] eventData = { 1, 2, 3 };
client.raiseEvent(instanceId, "MyEvent", eventData);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
const eventData = [1, 2, 3];
await client.raiseOrchestrationEvent(instanceId, "MyEvent", eventData);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
ملحوظة
إذا لم يكن هناك نسخة تنسيق بمعرف النسخة المحدد، يتم تجاهل رسالة الحدث. إذا كان هناك مثيل لكنه لم ينتظر الحدث بعد، يتم تخزين الحدث في حالة النسخة حتى يكون جاهزا للاستلام والمعالجة.
انتظر حتى اكتمال التنسيق
في التوزيعات الموسيقية طويلة الأمد، قد ترغب في الانتظار والحصول على نتائج التوزيع الأوركسترالي. في هذه الحالات، من المفيد أيضا تحديد فترة مهلة على التوزيع الأوركسترالي. إذا تم تجاوز المهلة، يتم إعادة حالة التوزيع بدلا من النتائج.
استخدم واجهة برمجة التطبيقات "انتظر الاكتمال أو إنشاء استجابة حالة المراجعة" للحصول على المخرج الفعلي من مثيل التنسيق بشكل متزامن. افتراضيا، هذه الطريقة لها مهلة زمنية تبلغ عشر ثوان وفترة استطلاع مدتها ثانية واحدة.
إليك مثال على دالة HTTP-trigger التي توضح كيفية استخدام هذه الواجهة:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace VSSample
{
public static class HttpSyncStart
{
private const string Timeout = "timeout";
private const string RetryInterval = "retryInterval";
[FunctionName("HttpSyncStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
string functionName,
ILogger log)
{
// Function input comes from the request content.
object eventData = await req.Content.ReadAsAsync<object>();
string instanceId = await starter.StartNewAsync(functionName, eventData);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
req,
instanceId,
timeout,
retryInterval);
}
private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
{
string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
if (string.IsNullOrEmpty(queryParameterStringValue))
{
return null;
}
return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
}
}
}
const df = require("durable-functions");
const timeout = "timeout";
const retryInterval = "retryInterval";
module.exports = async function (context, req) {
const client = df.getClient(context);
const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
context.log(`Started orchestration with ID = '${instanceId}'.`);
const timeoutInMilliseconds = getTimeInSeconds(req, timeout) || 30000;
const retryIntervalInMilliseconds = getTimeInSeconds(req, retryInterval) || 1000;
const response = client.waitForCompletionOrCreateCheckStatusResponse(
context.bindingData.req,
instanceId,
timeoutInMilliseconds,
retryIntervalInMilliseconds
);
return response;
};
function getTimeInSeconds(req, queryParameterName) {
const queryValue = req.query[queryParameterName];
return queryValue
? queryValue * 1000 // expected to be in seconds
: undefined;
}
راجع بدء مثيلات لتكوين function.json.
import logging
import azure.functions as func
import azure.durable_functions as df
timeout = "timeout"
retry_interval = "retryInterval"
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new(req.route_params['functionName'], None, req.get_body())
logging.log(f"Started orchestration with ID = '${instance_id}'.")
timeout_in_milliseconds = get_time_in_seconds(req, timeout)
timeout_in_milliseconds = timeout_in_milliseconds if timeout_in_milliseconds != None else 30000
retry_interval_in_milliseconds = get_time_in_seconds(req, retry_interval)
retry_interval_in_milliseconds = retry_interval_in_milliseconds if retry_interval_in_milliseconds != None else 1000
return await client.wait_for_completion_or_create_check_status_response(
req,
instance_id,
timeout_in_milliseconds,
retry_interval_in_milliseconds
)
def get_time_in_seconds(req: func.HttpRequest, query_parameter_name: str):
query_value = req.params.get(query_parameter_name)
return query_value if query_value != None else 1000
ملحوظة
لا يحتوي PowerShell حاليا على أمر مضمن لهذا السيناريو.
Java لا يوجد حاليا طريقة واحدة لهذا السيناريو، لكن يمكنك تنفيذها ببضع أسطر إضافية من الكود.
@FunctionName("HttpStartAndWait")
public HttpResponseMessage httpStartAndWait(
@HttpTrigger(name = "req", route = "orchestrators/{functionName}/wait", methods = {HttpMethod.POST}) HttpRequestMessage<?> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
@BindingName("functionName") String functionName,
final ExecutionContext context) {
DurableTaskClient client = durableContext.getClient();
String instanceId = client.scheduleNewOrchestrationInstance(functionName);
context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
try {
String timeoutString = req.getQueryParameters().get("timeout");
Integer timeoutInSeconds = Integer.parseInt(timeoutString);
OrchestrationMetadata orchestration = client.waitForInstanceCompletion(
instanceId,
Duration.ofSeconds(timeoutInSeconds),
true /* getInputsAndOutputs */);
return req.createResponseBuilder(HttpStatus.OK)
.body(orchestration.getSerializedOutput())
.header("Content-Type", "application/json")
.build();
} catch (TimeoutException timeoutEx) {
// timeout expired - return a 202 response
return durableContext.createCheckStatusResponse(req, instanceId);
}
}
توفر مجموعات تطوير المهام المتطورة طريقة للانتظار حتى تنتهي التنسيق بشكل متزامن.
using Microsoft.DurableTask.Client;
// Wait for orchestration to complete with a timeout
OrchestrationMetadata metadata = await client.WaitForInstanceCompletionAsync(
instanceId,
timeout: TimeSpan.FromSeconds(30),
getInputsAndOutputs: true);
if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Completed)
{
Console.WriteLine($"Output: {metadata.SerializedOutput}");
}
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Wait for orchestration to complete with a timeout
state = client.wait_for_orchestration_completion(
instance_id,
timeout=30,
fetch_payloads=True)
if state.runtime_status == 'COMPLETED':
print(f"Output: {state.serialized_output}")
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.OrchestrationMetadata;
import java.time.Duration;
import java.util.concurrent.TimeoutException;
// Wait for orchestration to complete with a timeout
try {
OrchestrationMetadata metadata = client.waitForInstanceCompletion(
instanceId,
Duration.ofSeconds(30),
true /* getInputsAndOutputs */);
System.out.println("Output: " + metadata.getSerializedOutput());
} catch (TimeoutException e) {
System.out.println("Orchestration did not complete within timeout");
}
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
import { OrchestrationStatus } from "@microsoft/durabletask-js";
const client = createAzureManagedClient(connectionString);
// Wait for orchestration to complete with a timeout
const state = await client.waitForOrchestrationCompletion(instanceId, true, 30);
if (state?.runtimeStatus === OrchestrationStatus.COMPLETED) {
console.log(`Output: ${state.serializedOutput}`);
}
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
استدعاء الدالة مع السطر التالي. استخدم ثانيتين للاستراحة و0.5 ثانية لفترة إعادة المحاولة:
curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"
ملحوظة
يفترض الأمر cURL أعلاه أن لديك دالة منسق تسمى E1_HelloSequence في مشروعك. بسبب كيفية كتابة دالة مشغل HTTP، يمكنك استبدالها باسم أي دالة منسق في مشروعك.
اعتمادا على الوقت اللازم للحصول على الاستجابة من حالة التوزيع الأوركسترالي، هناك حالتان:
- تنتهي حالات التوزيع ضمن المهلة المحددة (في هذه الحالة ثانيتين)، ويكون الرد هو مخرج مثيل التوزيع الفعلي، الذي يتم تقديمه بشكل متزامن:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked
[
"Hello Tokyo!",
"Hello Seattle!",
"Hello London!"
]
- لا يمكن لحالات التنسيق أن تنتهي ضمن المهلة المحددة المحددة، والاستجابة هي الافتراضية الموصوفة في اكتشاف رابط رابط API:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked
{
"id": "d3b72dddefce4e758d92f4d411567177",
"sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
"statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
"terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
"suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
"resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}
ملحوظة
قد يختلف تنسيق عناوين webhook حسب النسخة التي تستخدمها من مضيف Azure Functions. المثال السابق هو لمضيف Azure Functions 3.0.
استرداد عناوين URL لخطاف الويب لإدارة HTTP
استخدم نظاما خارجيا لمراقبة أو رفع الأحداث إلى مستوى التنسيق. تتواصل الأنظمة الخارجية مع Durable Functions عبر عناوين webhook التي تشكل جزءا من الاستجابة الافتراضية الموصوفة في <اكتشاف رابط رابط واجهة برمجة التطبيقات <(API) c0>>. يمكن الوصول إلى روابط webhook بشكل برمجي باستخدام ربط عميل التنسيق. تحديدا، تحصل واجهة برمجة تطبيقات إنشاء إدارة HTTP على كائن قابل للتسلسل يحتوي على هذه الروابط الخاصة ب webhook.
تحتوي واجهة برمجة تطبيقات حمولة إدارة HTTP على معلمة واحدة:
-
معرف المثيل: المعرف الفريد للمثيل.
ترجع الأساليب كائنا بخصائص السلسلة التالية:
-
المعرف: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس
InstanceId الإدخال).
-
StatusQueryGetUri: عنوان URL لحالة مثيل التنسيق.
-
SendEventPostUri: عنوان URL "رفع الحدث" لمثيل التنسيق.
-
TerminatePostUri: عنوان URL "إنهاء" لمثيل التنسيق.
-
PurgeHistoryDeleteUri: عنوان URL "محفوظات التطهير" لمثيل التنسيق.
-
SuspendPostUri: رابط "تعليق" لحالة التوزيع الموسيقي.
-
ResumePostUri: رابط "resume" الخاص بنسخة التوزيع الموسيقي.
ترسل الدوال نسخا من هذه الكائنات إلى أنظمة خارجية لمراقبة أو رفع الأحداث على التنسيقات المقابلة، كما هو موضح في الأمثلة التالية.
[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
[ActivityTrigger] IDurableActivityContext ctx,
[DurableClient] IDurableOrchestrationClient client,
[CosmosDB(
databaseName: "MonitorDB",
containerName: "HttpManagementPayloads",
Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);
// send the payload to Azure Cosmos DB
document = new { Payload = payload, id = ctx.InstanceId };
}
ملحوظة
الكود السابق في C# يستخدم النموذج قيد العملية مع IDurableOrchestrationClient و IDurableActivityContext، واللذين يتم تصنيفهما كمنقرضين في الإصدارات الأحدث من امتداد Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
modules.exports = async function(context, ctx) {
const client = df.getClient(context);
const payload = client.createHttpManagementPayload(ctx.instanceId);
// send the payload to Azure Cosmos DB
context.bindings.document = JSON.stringify({
id: ctx.instanceId,
payload,
});
};
راجع بدء مثيلات لتكوين function.json.
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.cosmosdb.cdb.Document:
client = df.DurableOrchestrationClient(starter)
payload = client.create_check_status_response(req, instance_id).get_body().decode()
return func.cosmosdb.CosmosDBConverter.encode({
id: instance_id,
payload: payload
})
using namespace System.Net
param($Request, $TriggerMetadata)
$InstanceId = $Request.Body.InstanceId
$Response = New-DurableOrchestrationCheckStatusResponse -Request $Request -InstanceId $InstanceId
Push-OutputBinding -Name Response -Value $Response
ملحوظة
Java لا تدعم هذه الميزة حاليا.
إعادة التكرار
إذا حدث فشل في التنسيق لسبب غير متوقع، أعد النسخة إلى حالة سليمة سابقا باستخدام واجهة برمجة تطبيقات مبنية لهذا الغرض.
ملحوظة
هذه الواجهة ليست بديلا عن سياسات معالجة الأخطاء وإعادة المحاولة بشكل صحيح. بل هو مخصص للاستخدام فقط في الحالات التي تفشل فيها حالات التوزيع لأسباب غير متوقعة. لا يمكن "إعادة التوزيع الموسيقية في حالات غير Failed (على سبيل المثال، Running، Pending، Terminated، أو Completed) إلى الوراء. لمزيد من المعلومات حول سياسات معالجة الأخطاء وإعادة المحاولة، راجع مقالة معالجة الأخطاء .
استخدم طريقة (.NET) أو (JavaScript) من طريقة ><ربط عميل التنسيق لإعادة التوزيع إلى حالة Running. تعيد هذه الطريقة أيضا تشغيل فشل تنفيذ النشاط أو التنسيق الفرعي الذي تسبب في فشل التنسيق.
على سبيل المثال، لنفترض أن لديك سير عمل يتضمن سلسلة من الموافقات البشرية. افترض أن سلسلة من وظائف النشاط أبلغت شخصا بأن موافقته مطلوبة وانتظرت حتى الرد في الوقت الحقيقي. بعد أن تتلقى جميع أنشطة الموافقة ردودا أو تتوقف عن الوقت، افترض أن نشاطا آخر فشل بسبب خطأ في تكوين التطبيق، مثل سلسلة connection string غير صالحة. والنتيجة هي فشل التنسيق في عمق سير العمل. مع واجهة برمجة التطبيقات RewindAsync (.NET) أو rewind (JavaScript)، يمكن لمسؤول التطبيق إصلاح خطأ التكوين وإعادة التنسيق الفاشل إلى الحالة التي سبقت الفشل مباشرة. لا يلزم إعادة الموافقة على أي من خطوات التفاعل البشري، ويمكن الآن إكمال التنسيق بنجاح.
ملحوظة
لا تدعم ميزة الإرجاع إرجاع مثيلات التنسيق التي تستخدم مؤقتات دائمة.
[FunctionName("RewindInstance")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("rewind-queue")] string instanceId)
{
string reason = "Orchestrator failed and needs to be revived.";
return client.RewindAsync(instanceId, reason);
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
const reason = "Orchestrator failed and needs to be revived.";
return client.rewind(instanceId, reason);
};
راجع بدء مثيلات لتكوين function.json.
ملحوظة
Python لا يدعم هذه الميزة حاليا.
ملحوظة
لا يدعم PowerShell هذه الميزة حاليا.
ملحوظة
Java لا تدعم هذه الميزة حاليا.
using Microsoft.DurableTask.Client;
string reason = "Orchestrator failed and needs to be revived.";
await client.RewindInstanceAsync(instanceId, reason);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
const reason = "Orchestrator failed and needs to be revived.";
await client.rewindInstance(instanceId, reason);
هذه العينة معروضة فقط لملفات .NET وJavaScript.
هذه العينة معروضة فقط لملفات .NET وJavaScript.
هذه العينة معروضة فقط لملفات .NET وJavaScript.
مثيلات إعادة التشغيل
إعادة تشغيل التوزيع الموسيقي تخلق نسخة جديدة باستخدام تاريخ نسخة تم تشغيلها سابقا. هذه الميزة مفيدة عندما ترغب في إعادة تشغيل توزيع أوركسترالي بنفس نمط الإدخال ومعرف المثال، مما يخلق تجربة جديدة مبنية على الأصل.
[FunctionName("RestartInstance")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("restart-queue")] string instanceId)
{
return client.RestartAsync(instanceId, restartWithNewInstanceId: true);
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
ملحوظة
JavaScript لا يدعم هذه الميزة حاليا.
ملحوظة
Python لا يدعم هذه الميزة حاليا.
ملحوظة
لا يدعم PowerShell هذه الميزة حاليا.
ملحوظة
هذه الميزة غير مدعومة حاليا في Java.
using Microsoft.DurableTask.Client;
// Restart an orchestration with a new instance ID
string newInstanceId = await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: true);
Console.WriteLine($"Restarted as new instance: {newInstanceId}");
// Restart an orchestration keeping the same instance ID
await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: false);
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// Restart an orchestration with a new instance ID
const newInstanceId = await client.restartOrchestration(instanceId, true);
console.log(`Restarted as new instance: ${newInstanceId}`);
// Restart an orchestration keeping the same instance ID
await client.restartOrchestration(instanceId, false);
هذه العينة معروضة فقط لملفات .NET وJavaScript.
هذه العينة معروضة فقط لملفات .NET وJavaScript.
هذه العينة معروضة فقط لملفات .NET وJavaScript.
إزالة محفوظات المثيل
لإزالة جميع البيانات المرتبطة بتنظيم التشغيل، قم بمسح سجل المشاهد. على سبيل المثال، احذف أي موارد تخزين مرتبطة بمثيل مكتمل. استخدم واجهة برمجة تطبيقات مثيل التطهير التي يحددها عميل التنسيق.
المثال التالي يوضح كيفية تطهير نسخة أوركسترا واحدة.
[FunctionName("PurgeInstanceHistory")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[QueueTrigger("purge-queue")] string instanceId)
{
return client.PurgeInstanceHistoryAsync(instanceId);
}
const df = require("durable-functions");
module.exports = async function(context, instanceId) {
const client = df.getClient(context);
return client.purgeInstanceHistory(instanceId);
};
راجع بدء مثيلات لتكوين function.json.
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
return await client.purge_instance_history(instance_id)
ملحوظة
هذه الميزة غير مدعومة حاليا في PowerShell، ولكن يمكن تحقيقها باستخدام واجهة برمجة تطبيقات Durable Functions HTTP.
@FunctionName("PurgeInstance")
public HttpResponseMessage purgeInstance(
@HttpTrigger(name = "req", methods = {HttpMethod.POST}, route = "purge/{instanceID}") HttpRequestMessage<?> req,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
@BindingName("instanceID") String instanceID) {
PurgeResult result = durableContext.getClient().purgeInstance(instanceID);
if (result.getDeletedInstanceCount() == 0) {
return req.createResponseBuilder(HttpStatus.NOT_FOUND)
.body("No completed instance with ID '" + instanceID + "' was found!")
.build();
} else {
return req.createResponseBuilder(HttpStatus.OK)
.body("Successfully purged data for " + instanceID)
.build();
}
}
using Microsoft.DurableTask.Client;
// Purge a single orchestration instance
PurgeResult result = await client.PurgeInstanceAsync(instanceId);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Purge a single orchestration instance
result = client.purge_orchestration(instance_id)
print(f"Purged {result.deleted_instance_count} instance(s).")
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.PurgeResult;
// Purge a single orchestration instance
PurgeResult result = client.purgeInstance(instanceId);
System.out.println("Purged " + result.getDeletedInstanceCount() + " instance(s).");
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
const client = createAzureManagedClient(connectionString);
// Purge a single orchestration instance
const result = await client.purgeOrchestration(instanceId);
console.log(`Purged ${result?.deletedInstanceCount ?? 0} instance(s).`);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
المثال التالي يظهر دالة يتم تفعيلها بالمؤقت تقوم بحذف السجل لجميع حالات التوزيع الموسيقي التي اكتملت بعد الفترة الزمنية المحددة. في هذه الحالة، فإنه يزيل البيانات لجميع المثيلات المكتملة منذ 30 يوما أو أكثر. تتم جدولة هذه الدالة على سبيل المثال للتشغيل مرة واحدة يوميا، في الساعة 12:00 مساء بالتوقيت العالمي المتفق عليه:
[FunctionName("PurgeInstanceHistory")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
return client.PurgeInstanceHistoryAsync(
DateTime.MinValue,
DateTime.UtcNow.AddDays(-30),
new List<OrchestrationStatus>
{
OrchestrationStatus.Completed
});
}
ملحوظة
يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .
purgeInstanceHistoryBy يمكن استخدام الأسلوب لمسح محفوظات المثيلات بشكل مشروط لمثيلات متعددة.
function.json
{
"bindings": [
{
"schedule": "0 0 12 * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
],
"disabled": false
}
ملحوظة
يستهدف هذا المثال Durable Functions الإصدار 2.x. في الإصدار 1.x، استخدم orchestrationClient بدلا من durableClient.
index.js
const df = require("durable-functions");
module.exports = async function (context, myTimer) {
const client = df.getClient(context);
const createdTimeFrom = new Date(0);
const createdTimeTo = new Date().setDate(today.getDate() - 30);
const runtimeStatuses = [ df.OrchestrationRuntimeStatus.Completed ];
return client.purgeInstanceHistoryBy(createdTimeFrom, createdTimeTo, runtimeStatuses);
};
ملحوظة
هذه الميزة غير مدعومة حاليا في PowerShell، ولكن يمكن تحقيقها باستخدام واجهة برمجة تطبيقات Durable Functions HTTP.
import azure.functions as func
import azure.durable_functions as df
from azure.durable_functions.models.DurableOrchestrationStatus import OrchestrationRuntimeStatus
from datetime import datetime, timedelta
async def main(req: func.HttpRequest, starter: str, instance_id: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
created_time_from = datetime.min
created_time_to = datetime.today() + timedelta(days = -30)
runtime_statuses = [OrchestrationRuntimeStatus.Completed]
return await client.purge_instance_history_by(created_time_from, created_time_to, runtime_statuses)
@FunctionName("PurgeInstances")
public void purgeInstances(
@TimerTrigger(name = "purgeTimer", schedule = "0 0 12 * * *") String timerInfo,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
ExecutionContext context) throws TimeoutException {
PurgeInstanceCriteria criteria = new PurgeInstanceCriteria()
.setCreatedTimeFrom(Instant.now().minus(Duration.ofDays(60)))
.setCreatedTimeTo(Instant.now().minus(Duration.ofDays(30)))
.setRuntimeStatusList(List.of(OrchestrationRuntimeStatus.COMPLETED));
PurgeResult result = durableContext.getClient().purgeInstances(criteria);
context.getLogger().info(String.format("Purged %d instance(s)", result.getDeletedInstanceCount()));
}
using Microsoft.DurableTask.Client;
// Purge completed instances older than 30 days
var filter = new PurgeInstancesFilter(
CreatedFrom: DateTime.MinValue,
CreatedTo: DateTime.UtcNow.AddDays(-30),
Statuses: new[] { OrchestrationRuntimeStatus.Completed });
PurgeResult result = await client.PurgeAllInstancesAsync(filter);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
from datetime import datetime, timedelta
# Purge completed instances older than 30 days
result = client.purge_orchestrations(
created_time_from=datetime.min,
created_time_to=datetime.utcnow() - timedelta(days=30),
runtime_status=['COMPLETED']
)
print(f"Purged {result.deleted_instance_count} instance(s).")
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.PurgeInstanceCriteria;
import com.microsoft.durabletask.PurgeResult;
import com.microsoft.durabletask.OrchestrationRuntimeStatus;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
// Purge completed instances older than 30 days
PurgeInstanceCriteria criteria = new PurgeInstanceCriteria()
.setCreatedTimeTo(Instant.now().minus(Duration.ofDays(30)))
.setRuntimeStatusList(List.of(OrchestrationRuntimeStatus.COMPLETED));
PurgeResult result = client.purgeInstances(criteria);
System.out.println("Purged " + result.getDeletedInstanceCount() + " instance(s).");
import { createAzureManagedClient } from "@microsoft/durabletask-js-azuremanaged";
import { OrchestrationStatus, PurgeInstanceCriteria } from "@microsoft/durabletask-js";
const client = createAzureManagedClient(connectionString);
// Purge completed instances older than 30 days
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
const criteria = new PurgeInstanceCriteria();
criteria.setCreatedTimeTo(thirtyDaysAgo);
criteria.setRuntimeStatusList([OrchestrationStatus.COMPLETED]);
const result = await client.purgeOrchestration(criteria);
console.log(`Purged ${result?.deletedInstanceCount ?? 0} instance(s).`);
حزمة تطوير المهام المتغيرة غير متوفرة لجهاز PowerShell. استخدم Durable Functions بدلا من ذلك.
ملحوظة
لكي تنجح عملية محفوظات الإزالة، يجب أن تكون حالة وقت التشغيل للمثيل الهدف مكتملة أو منتهية أو فاشلة.
الخطوات التالية