تسلسل الدوال هو نمط تقوم فيه بتشغيل تسلسل من الدوال بالترتيب. من الشائع تمرير مخرج دالة إلى مدخل دالة أخرى. تصف هذه المقالة تسلسل التسلسل الذي تبنيه عند إكمال Durable Functions البدء السريع (C#, JavaScript, TypeScript, Python, PowerShell، أو Java). تعرف على المزيد في نظرة عامة Durable Functions.
المتطلبات المسبقه
نموذج البرمجة V3
نموذج البرمجة V4
تسلسل الدوال هو نمط تقوم فيه بتشغيل تسلسل من الأنشطة بالترتيب. من الشائع تمرير مخرج نشاط إلى مدخل النشاط التالي. تصف هذه المقالة تسلسل التسلسل لمجموعات تطوير المهام المتطورة لأنظمة .NET وJavaScript وPython وJava.
الدوال في عينة التسلسل
تصف هذه المقالة هذه الوظائف في التطبيق النموذجي:
-
E1_HelloSequence: وظيفة أوركستراتور تستدعي E1_SayHello عدة مرات بالتتابع. يخزن كل مخرج ويسجل النتائج.
-
E1_SayHello: دالة نشاط تضيف "مرحبا" إلى بداية السلسلة.
-
HttpStart: دالة عميل دائمة تعمل بتقنية HTTP وتبدأ نسخة من المنسق.
تصف هذه المقالة هذه المكونات في التطبيق النموذجي:
-
GreetingOrchestration, greetingOrchestrator, function_chaining_orchestrator, أو: ActivityChainingمنسق موسيقي يستدعي عدة أنشطة بالتتابع. يخزن كل مخرج ويسجل النتائج.
- وظائف النشاط: أنشطة تعالج المدخلات وترجع النتائج. كل نشاط يقوم بتحويل بسيط على المدخل.
- العميل: تطبيق عميل يبدأ نسخة من المنظم وينتظر النتيجة.
كود وظيفة المنسق
[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var outputs = new List<string>();
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}
يجب أن تحتوي جميع دوال التنسيق على C# على معلمة من النوع DurableOrchestrationContext، والتي توجد في تجميع Microsoft.Azure.WebJobs.Extensions.DurableTask. يتيح لك هذا السياق استدعاء وظائف نشاط أخرى وتمرير معلمات الإدخال باستخدام CallActivityAsync أسلوبها.
استدعاء التعليمات البرمجية E1_SayHello ثلاث مرات في تسلسل مع قيم معلمة مختلفة. تتم إضافة قيمة الإرجاع لكل استدعاء إلى outputs القائمة التي يتم إرجاعها في نهاية الدالة.
نموذج البرمجة V3
function.json
إذا طورت في Visual Studio Code أو في بوابة Azure، فإليك ملف المنسق function.json.
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
],
"disabled": false
}
إعداد المفتاح هو orchestrationTrigger نوع الربط. يجب أن تستخدم كافة دالات التزامن مشغلاً من هذا النوع.
التحذير
لاتباع قاعدة "عدم الإدخال/الإخراج" لوظائف الأوركستراتور، لا تستخدم روابط الإدخال أو الإخراج مع orchestrationTrigger ربط الزناد. إذا كنت بحاجة إلى روابط إدخال أو إخراج أخرى، استخدمها في activityTrigger الدوال التي يستدعيها المنسق. لمزيد من المعلومات، راجع قيود كود وظائف التنسيق.
index.js
ها هو منسق الدالة
const df = require("durable-functions");
module.exports = df.orchestrator(function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity("E1_SayHello", "Tokyo"));
output.push(yield context.df.callActivity("E1_SayHello", "Seattle"));
output.push(yield context.df.callActivity("E1_SayHello", "London"));
return output;
});
يجب أن تتضمن كافة وظائف التزامن JavaScript durable-functions الوحدة النمطية. هي مكتبة تتيح لك كتابة Durable Functions بلغة JavaScript. ثلاثة اختلافات رئيسية بين وظيفة التنسيق ووظائف جافاسكريبت الأخرى:
- دالة المنسق هي دالة مولد.
- يتم تضمين الدالة في استدعاء
durable-functions إلى أسلوب الوحدة النمطية orchestratordf (هنا).
- الوظيفة متزامنة. لأن
orchestrator الطريقة تستدعي context.done، تعود الدالة.
يحتوي الكائن context على كائن سياق تزامن دائم df يتيح لك استدعاء وظائف نشاط أخرى وتمرير معلمات الإدخال باستخدام أسلوب callActivity بها. تستدعي التعليمات البرمجية E1_SayHello ثلاث مرات في تسلسل مع قيم معلمة مختلفة، باستخدام yield للإشارة إلى التنفيذ ينبغي الانتظار على لاستدعاءات دالة النشاط المتزامنة ليتم إرجاعها. تتم إضافة قيمة الإرجاع لكل استدعاء إلى صفيف outputs، الذي يتم إرجاعه في نهاية الدالة.
نموذج البرمجة V4
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.orchestration("helloSequence", function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity(helloActivityName, "Tokyo"));
output.push(yield context.df.callActivity(helloActivityName, "Seattle"));
output.push(yield context.df.callActivity(helloActivityName, "Cairo"));
return output;
});
يجب أن تتضمن كافة وظائف التزامن JavaScript durable-functions الوحدة النمطية. تتيح لك هذه الوحدة كتابة Durable Functions بلغة JavaScript. لاستخدام نموذج برمجة عقدة V4، تحتاج إلى تثبيت v3.x نسخة .durable-functions
هناك اختلافان رئيسيان بين وظيفة التنسيق ووظائف جافاسكريبت الأخرى:
- دالة المنسق هي دالة مولد.
- الوظيفة متزامنة. تعود الدالة.
يحتوي الكائن context على كائن سياق تزامن دائم df يتيح لك استدعاء وظائف نشاط أخرى وتمرير معلمات الإدخال باستخدام أسلوب callActivity بها. تستدعي التعليمات البرمجية sayHello ثلاث مرات في تسلسل مع قيم معلمة مختلفة، باستخدام yield للإشارة إلى التنفيذ ينبغي الانتظار على لاستدعاءات دالة النشاط المتزامنة ليتم إرجاعها. تتم إضافة قيمة الإرجاع لكل استدعاء إلى صفيف outputs، الذي يتم إرجاعه في نهاية الدالة.
ملحوظة
تتوفر Python Durable Functions فقط لوقت تشغيل وظائف 3.0.
function.json
إذا كنت تستخدم Visual Studio Code أو بوابة Azure للتطوير، فإليك محتوى ملف function.json الخاص بوظيفة التنسيق. معظم ملفات المنسق function.json تبدو بالضبط تقريبًا مثل هذا.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
الشيء المهم هو نوع الربط orchestrationTrigger. يجب أن تستخدم كافة دالات التزامن مشغلاً من هذا النوع.
التحذير
للالتزام بقاعدة "عدم الإدخال/الإخراج" من دالات التزامن، لا تستخدم أي روابط إدخال أو إخراج بيانات عند استخدام orchestrationTrigger ربط المشغل. إذا كانت هناك حاجة إلى روابط إدخال أو إخراج أخرى، يجب استخدامها بدلاً من ذلك في سياق activityTrigger الدالات، والتي يتم استدعاؤها من قِبل المنسق. لمزيد من المعلومات، راجع المقالة قيود رمز دالة المنسق.
__init__.py
ها هو منسق الدالة
import azure.functions as func
import azure.durable_functions as df
def orchestrator_function(context: df.DurableOrchestrationContext):
result1 = yield context.call_activity('E1_SayHello', "Tokyo")
result2 = yield context.call_activity('E1_SayHello', "Seattle")
result3 = yield context.call_activity('E1_SayHello', "London")
return [result1, result2, result3]
main = df.Orchestrator.create(orchestrator_function)
يجب أن تتضمن جميع وظائف التوزيع Python حزمة durable-functions. هي مكتبة تتيح لك كتابة Durable Functions بلغة Python. هناك اختلافان رئيسيان بين وظيفة المنسق ودوال Python الأخرى:
- دالة المنسق هي دالة مولد.
- يقوم الملف بتسجيل وظيفة الموزع من خلال الإشارة
main = df.Orchestrator.create(<orchestrator function name>) إلى نهاية الملف. هذا يساعد في تمييزه عن وظائف المساعدة الأخرى المعلنة في الملف.
يتيح لك كائن context استدعاء دوال نشاط أخرى وتمرير معلمات الإدخال باستخدام أسلوب call_activity بها. تستدعي التعليمات البرمجية E1_SayHello ثلاث مرات في تسلسل مع قيم معلمة مختلفة، باستخدام yield للإشارة إلى التنفيذ ينبغي الانتظار على لاستدعاءات دالة النشاط المتزامنة ليتم إرجاعها. يتم إرجاع قيمة الإرجاع لكل استدعاء في نهاية الدالة.
عينة PowerShell غير متوفرة بعد.
عينة Java غير متوفرة بعد.
يظهر هذا الكود منسقا يقوم باستدعاء ثلاث أنشطة متتالية ويمرر كل مخرج إلى النشاط التالي:
using System.Threading.Tasks;
using Microsoft.DurableTask;
[DurableTask]
public class GreetingOrchestration : TaskOrchestrator<string, string>
{
public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
{
// Step 1: Say hello to the person
string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);
// Step 2: Process the greeting
string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);
// Step 3: Finalize the response
string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);
return finalResponse;
}
}
جميع .NET الموزعين ورثوا من TaskOrchestrator<TInput, TOutput>.
TaskOrchestrationContext تتيح لك استدعاء الأنشطة باستخدام CallActivityAsync. يستدعي الكود ثلاث أنشطة متتالية، حيث يستقبل كل نشاط مخرجات النشاط السابق.
يظهر الرمز التالي منسقا يستدعي ثلاث أنشطة متتالية:
import {
OrchestrationContext,
TOrchestrator,
} from "@microsoft/durabletask-js";
const greetingOrchestrator: TOrchestrator = async function* (
ctx: OrchestrationContext,
name: string
): any {
// Step 1: Say hello to the person
const greeting: string = yield ctx.callActivity(sayHello, name);
// Step 2: Process the greeting
const processedGreeting: string = yield ctx.callActivity(processGreeting, greeting);
// Step 3: Finalize the response
const finalResponse: string = yield ctx.callActivity(finalizeResponse, processedGreeting);
return finalResponse;
};
جميع منسقي JavaScript هي وظائف مولد (async function*) تستخدم yield لاستدعاء الأنشطة. طريقة سياق التوزيع تحدد callActivity جدولة تنفيذ النشاط. يستدعي الكود ثلاث أنشطة بالتسلسل، وينقل مخرجات كل نشاط إلى التالي.
يظهر الرمز التالي منسقا يستدعي ثلاث أنشطة متتالية:
from durabletask import task
# Orchestrator function
def function_chaining_orchestrator(ctx: task.OrchestrationContext, name: str) -> str:
"""Orchestrator that demonstrates function chaining pattern."""
# Call first activity
greeting = yield ctx.call_activity(say_hello, input=name)
# Call second activity with the result from first activity
processed_greeting = yield ctx.call_activity(process_greeting, input=greeting)
# Call third activity with the result from second activity
final_response = yield ctx.call_activity(finalize_response, input=processed_greeting)
return final_response
جميع Python المنظمين هي وظائف مولد تستخدم yield لاستدعاء الأنشطة. طريقة سياق التوزيع تحدد call_activity جدولة تنفيذ النشاط. يستدعي الكود ثلاث أنشطة بالتسلسل، وينقل مخرجات كل نشاط إلى التالي.
تم عرض هذه العينة لأنظمة .NET وJavaScript وJava وPython.
يظهر الرمز التالي منسقا يستدعي ثلاث أنشطة متتالية:
import com.microsoft.durabletask.DurableTaskGrpcWorker;
import com.microsoft.durabletask.DurableTaskSchedulerWorkerExtensions;
import com.microsoft.durabletask.TaskOrchestration;
import com.microsoft.durabletask.TaskOrchestrationFactory;
DurableTaskGrpcWorker worker = DurableTaskSchedulerWorkerExtensions.createWorkerBuilder(connectionString)
.addOrchestration(new TaskOrchestrationFactory() {
@Override
public String getName() { return "ActivityChaining"; }
@Override
public TaskOrchestration create() {
return ctx -> {
String input = ctx.getInput(String.class);
// Call activities in sequence, passing output from one to the next
String x = ctx.callActivity("Reverse", input, String.class).await();
String y = ctx.callActivity("Capitalize", x, String.class).await();
String z = ctx.callActivity("ReplaceWhitespace", y, String.class).await();
ctx.complete(z);
};
}
})
.build();
في Java، يعرف الموزعون باستخدام TaskOrchestrationFactory. تقوم طريقة السياق callActivity بجدولة تنفيذ النشاط، وتنتظر await() النتيجة. يستدعي الكود ثلاث أنشطة بالتسلسل، وينقل مخرجات كل نشاط إلى التالي.
رمز دالة النشاط
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
تستخدم الأنشطة ActivityTrigger السمة. استخدامه IDurableActivityContext لإجراءات النشاط، مثل قراءة المدخلات باستخدام GetInput<T>.
E1_SayHello يشكل سلسلة تحية.
بدلا من الربط ب IDurableActivityContext، اربط مباشرة بالنوع الذي يمرر إلى دالة النشاط. على سبيل المثال:
[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
return $"Hello {name}!";
}
نموذج البرمجة V3
E1_SayHello/function.js على
دالة.js في الملف لدالة النشاط E1_SayHello مشابهة لتلك التي باستثناء أنه يستخدم E1_HelloSequence نوع ربط بدلاً من نوع activityTriggerorchestrationTrigger آخر.
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"disabled": false
}
ملحوظة
استخدم الربط activityTrigger لجميع وظائف النشاط التي تستدعيها دالة التنسيق.
تنفيذ E1_SayHello عملية تنسيق سلسلة بسيطة نسبيًا.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
على عكس وظيفة التنسيق، لا تحتاج وظيفة النشاط إلى إعداد خاص. يقوم المنسق بتمرير الإدخال على الكائن context.bindings تحت اسم الربط activityTrigger —وفي هذه الحالة، context.bindings.name. قم بتعيين اسم الربط كمعامل للدالة المصدرة للوصول إليها مباشرة، كما تفعل العينة.
نموذج البرمجة V4
sayHello يشكل سلسلة تحية.
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.activity(helloActivityName, {
handler: function (input) {
return `Hello ${input}`;
},
});
على عكس وظيفة التنسيق، لا تحتاج وظيفة النشاط إلى إعداد خاص. يقوم المنسق بتمرير الإدخال كأول وسيط للدالة. الحجة الثانية هي سياق الاستدعاء، الذي لا يستخدمه هذا المثال.
E1_SayHello/function.js على
دالة.js في الملف لدالة النشاط E1_SayHello مشابهة لتلك التي باستثناء أنه يستخدم E1_HelloSequence نوع ربط بدلاً من نوع activityTriggerorchestrationTrigger آخر.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}
ملحوظة
يجب أن تُستخدم كافة دوال النشاط التي تسمى المقصودة من خلال التنسيق activityTrigger الربط.
تنفيذ E1_SayHello عملية تنسيق سلسلة بسيطة نسبيًا.
E1_SayHello/__init__.py
def main(name: str) -> str:
return f"Hello {name}!"
بعكس دالة المنسق لا تحتاج دالة النشاط إلى أي إعداد خاص. الإدخال الذي تم تمريره إليه عبر دالة المنسق يمكن الوصول إليه مباشرة كمعلمة الدالة.
عينة PowerShell قادمة قريبا.
الأنشطة في مجموعة تطوير المهام الدائمة ترث من TaskActivity<TInput, TOutput>:
using System.Threading.Tasks;
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;
[DurableTask]
public class SayHelloActivity : TaskActivity<string, string>
{
private readonly ILogger<SayHelloActivity> _logger;
public SayHelloActivity(ILogger<SayHelloActivity> logger)
{
_logger = logger;
}
public override Task<string> RunAsync(TaskActivityContext context, string name)
{
_logger.LogInformation("Activity SayHello called with name: {Name}", name);
return Task.FromResult($"Hello {name}!");
}
}
[DurableTask]
public class ProcessGreetingActivity : TaskActivity<string, string>
{
public override Task<string> RunAsync(TaskActivityContext context, string greeting)
{
return Task.FromResult($"{greeting} How are you today?");
}
}
[DurableTask]
public class FinalizeResponseActivity : TaskActivity<string, string>
{
public override Task<string> RunAsync(TaskActivityContext context, string response)
{
return Task.FromResult($"{response} I hope you're doing well!");
}
}
استخدم حقن الاعتماد للحصول على خدمات مثل ILogger. أضف السمة [DurableTask] لتسجيل النشاط مع العامل.
الأنشطة في مجموعة تطوير المهام الدائمة هي وظائف بسيطة:
import { ActivityContext } from "@microsoft/durabletask-js";
const sayHello = async (_ctx: ActivityContext, name: string): Promise<string> => {
return `Hello ${name}!`;
};
const processGreeting = async (_ctx: ActivityContext, greeting: string): Promise<string> => {
return `${greeting} How are you today?`;
};
const finalizeResponse = async (_ctx: ActivityContext, response: string): Promise<string> => {
return `${response} I hope you're doing well!`;
};
على عكس المنسقين، يمكن للأنشطة تنفيذ عمليات الإدخال/الإخراج مثل استدعاءات HTTP، واستعلامات قواعد البيانات، والوصول إلى الملفات. يتم تمرير الإدخال مباشرة كمعامل.
الأنشطة في مجموعة تطوير المهام الدائمة هي وظائف بسيطة:
from durabletask import task
def say_hello(ctx: task.ActivityContext, name: str) -> str:
"""First activity that greets the user."""
return f"Hello {name}!"
def process_greeting(ctx: task.ActivityContext, greeting: str) -> str:
"""Second activity that processes the greeting."""
return f"{greeting} How are you today?"
def finalize_response(ctx: task.ActivityContext, response: str) -> str:
"""Third activity that finalizes the response."""
return f"{response} I hope you're doing well!"
على عكس المنسقين، يمكن للأنشطة تنفيذ عمليات الإدخال/الإخراج مثل استدعاءات HTTP، واستعلامات قواعد البيانات، والوصول إلى الملفات. يتم تمرير الإدخال مباشرة كمعامل.
تم عرض هذه العينة لأنظمة .NET وJavaScript وJava وPython.
تعرف الأنشطة في Java باستخدام TaskActivityFactory:
import com.microsoft.durabletask.TaskActivity;
import com.microsoft.durabletask.TaskActivityFactory;
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Reverse"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
StringBuilder builder = new StringBuilder(input);
builder.reverse();
return builder.toString();
};
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Capitalize"; }
@Override
public TaskActivity create() {
return ctx -> ctx.getInput(String.class).toUpperCase();
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "ReplaceWhitespace"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
return input.trim().replaceAll("\\s", "-");
};
}
})
سجل كل نشاط لدى باني العامل باستخدام addActivity. يمكن للأنشطة تنفيذ عمليات الإدخال/الإخراج وإعادة النتائج إلى المنسق.
كود العميل لبدء التوزيع الموسيقي
ابدأ نسخة دالة منسق من دالة عميل. استخدم الدالة HttpStart التي تعمل ب HTTP لبدء مثيلات .E1_HelloSequence
public static class HttpStart
{
[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
[DurableClient] IDurableClient 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}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
للتفاعل مع الموزعين، أضف DurableClient ربط إدخال. استخدم العميل لبدء التنسيق وإرجاع استجابة HTTP تتضمن عناوين URL للتحقق من حالة التوزيع الجديد.
نموذج البرمجة V3
HttpStart/function.js
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": ["post"]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "orchestrationClient",
"direction": "in"
}
],
"disabled": false
}
للتفاعل مع الموزعين، أضف durableClient ربط إدخال.
HttpStart/index.js.js
const df = require("durable-functions");
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}'.`);
return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};
استخدمها df.getClient للحصول DurableOrchestrationClient على شيء. استخدم العميل لبدء التنسيق وإرجاع استجابة HTTP تتضمن عناوين URL للتحقق من حالة التوزيع الجديد.
نموذج البرمجة V4
const df = require("durable-functions");
const { app } = require("@azure/functions");
app.http("httpStart", {
route: "orchestrators/{orchestratorName}",
extraInputs: [df.input.durableClient()],
handler: async (request, context) => {
const client = df.getClient(context);
const body = await request.json();
const instanceId = await client.startNew(request.params.orchestratorName, { input: body });
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
},
});
لإدارة وتفاعل مع الموزعين، أضف durableClient ربط مدخلات. حدد الربط في الوسيط extraInputs عند تسجيل الدالة. احصل على رأيه durableClient بالاتصال df.input.durableClient()ب .
استخدمها df.getClient للحصول DurableClient على شيء. استخدم العميل لبدء التنسيق وإرجاع استجابة HTTP تتضمن عناوين URL للتحقق من حالة التوزيع الجديد.
HttpStart/function.js
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": [
"post",
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
]
}
للتفاعل مع المنسقين، يجب أن تتضمن الوظيفة ارتباط إدخال durableClient.
HttpStart/__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(req.route_params["functionName"], None, None)
logging.info(f"Started orchestration with ID = '{instance_id}'.")
return client.create_check_status_response(req, instance_id)
استخدم منشئ DurableOrchestrationClient لإنشاء عميل Durable Functions. استخدم العميل لبدء التنسيق وإرجاع استجابة HTTP تتضمن عناوين URL للتحقق من حالة التوزيع الجديد.
عينة PowerShell قادمة قريبا.
ابدأ التنسيق من تطبيق عميل. العميل يحدد جدولة التوزيع ويمكنه الانتظار حتى الانتهاء.
using System;
using Microsoft.DurableTask.Client;
// Create the client
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();
// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(GreetingOrchestration),
input: "World");
Console.WriteLine($"Started orchestration with ID: {instanceId}");
// Wait for the orchestration to complete
OrchestrationMetadata result = await client.WaitForInstanceCompletionAsync(
instanceId,
getInputsAndOutputs: true);
Console.WriteLine($"Orchestration completed with result: {result.ReadOutputAs<string>()}");
أنشئ DurableTaskClient باستخدام connection string إلى جدولة المهام الدائمة. استخدمها ScheduleNewOrchestrationInstanceAsync لبدء توزيع موسيقي وانتظار WaitForInstanceCompletionAsync الانتهاء.
import {
DurableTaskAzureManagedClientBuilder,
} from "@microsoft/durabletask-js-azuremanaged";
const connectionString =
process.env.DURABLE_TASK_SCHEDULER_CONNECTION_STRING ||
"Endpoint=http://localhost:8080;Authentication=None;TaskHub=default";
const client = new DurableTaskAzureManagedClientBuilder()
.connectionString(connectionString)
.build();
// Schedule a new orchestration instance
const instanceId = await client.scheduleNewOrchestration(greetingOrchestrator, "World");
console.log(`Started orchestration with ID: ${instanceId}`);
// Wait for the orchestration to complete
const state = await client.waitForOrchestrationCompletion(instanceId, true, 30);
console.log(`Orchestration completed with result: ${state?.serializedOutput}`);
أنشئ DurableTaskAzureManagedClientBuilder باستخدام connection string إلى جدولة المهام الدائمة. استخدمها scheduleNewOrchestration لبدء توزيع موسيقي وانتظار waitForOrchestrationCompletion الانتهاء.
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Create the client
client = DurableTaskSchedulerClient(
host_address=endpoint,
secure_channel=endpoint != "http://localhost:8080",
taskhub=taskhub_name,
token_credential=credential
)
# Schedule a new orchestration instance
instance_id = client.schedule_new_orchestration(
function_chaining_orchestrator,
input="World"
)
print(f"Started orchestration with ID: {instance_id}")
# Wait for the orchestration to complete
result = client.wait_for_orchestration_completion(instance_id, timeout=60)
if result and result.runtime_status == "COMPLETED":
print(f"Orchestration completed with result: {result.serialized_output}")
DurableTaskSchedulerClient يتصل ببرنامج جدولة المهام الدائمة. استخدمها schedule_new_orchestration لبدء توزيع موسيقي وانتظار wait_for_orchestration_completion الانتهاء.
تم عرض هذه العينة لأنظمة .NET وJavaScript وJava وPython.
import java.time.Duration;
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.NewOrchestrationInstanceOptions;
import com.microsoft.durabletask.OrchestrationMetadata;
import com.microsoft.durabletask.azuremanaged.DurableTaskSchedulerClientExtensions;
// Create the client
DurableTaskClient client = DurableTaskSchedulerClientExtensions
.createClientBuilder(connectionString)
.build();
// Schedule a new orchestration instance
String instanceId = client.scheduleNewOrchestrationInstance(
"ActivityChaining",
new NewOrchestrationInstanceOptions().setInput("Hello, world!"));
System.out.println("Started orchestration with ID: " + instanceId);
// Wait for the orchestration to complete
OrchestrationMetadata result = client.waitForInstanceCompletion(
instanceId,
Duration.ofSeconds(30),
true);
System.out.println("Orchestration completed with result: " + result.readOutputAs(String.class));
أنشئ DurableTaskClient باستخدام connection string. استخدمها scheduleNewOrchestrationInstance لبدء توزيع موسيقي وانتظار waitForInstanceCompletion الانتهاء.
شغل عينة تسلسل الدوال
لتشغيل التنسيق E1_HelloSequence ، أرسل طلب HTTP POST هذا إلى الدالة HttpStart .
POST http://{host}/orchestrators/E1_HelloSequence
ملحوظة
يفترض مقتطف HTTP السابق أن ملف host.json الخاص بالعينة يزيل البادئة الافتراضية api/ من جميع عناوين دوال المشغلات الخاصة ب HTTP. ابحث عن هذا التكوين في ملف host.json العينة.
على سبيل المثال، إذا كنت تشغل العينة في تطبيق دالة يسمى myfunctionapp، استبدل {host} ب myfunctionapp.azurewebsites.net.
يعيد الطلب HTTP 202 (تم تقليمه للاختصار):
HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
(...trimmed...)
يبدأ التوزيع الموسيقي في الانتظار ويبدأ العمل فورا. استخدم رابط العنوان في الرأس Location للتحقق من حالة التنفيذ.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
يظهر الرد حالة التوزيع الأوركسترالي. وبما أنه ينتهي بسرعة، غالبا ما يكون المثيل في حالة الاكتمال ويعيد ردا مثل هذا (تم تقليصه للاختصار):
HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8
{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}
النسخة runtimeStatusمكتملة، وتحتوي output على النتيجة المتسلسلة JSON لتنفيذ وظيفة المنسق.
ملحوظة
تنفيذ منطق بداية مشابه لأنواع الزناد الأخرى، مثل queueTrigger، eventHubTrigger، أو timerTrigger.
راجع سجلات تنفيذ الوظائف. تبدأ الدالة E1_HelloSequence وتكتمل عدة مرات بسبب سلوك إعادة التشغيل الموصوف في موثوقية التوزيع الأوركسترالي. لكنها E1_SayHello تعمل فقط ثلاث مرات لأن تنفيذ وظائف النشاط لا يعاد تشغيله.
لتشغيل العينة، تحتاج:
تشغيل محاكي جدولة المهام الدائم (للتطوير المحلي):
docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
ابدأ العامل بتسجيل المنظم والأنشطة.
شغل العميل لجدولة توزيع موسيقي وانتظر النتيجة.
يظهر مخرجات العميل نتيجة التوزيع المتسلسل:
Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"
تظهر سجلات العامل تشغيل كل نشاط بالتسلسل ويمرر مخرجاته إلى النشاط التالي.
الخطوات التالية
توضح هذه العينة توزيع توزيع بسيط لسلسلة الدوال. بعد ذلك، نفذ نمط المروحة/المروحة الداخلية.