العوامل المُشغَّلة بالأحداث مقابل العوامل المجدولة: أيّ نمط لأيّ عمل
استخدم العوامل المُشغَّلة بالأحداث حين تستلزم إجراءات المستخدم ردّاً فورياً — أيّ تأخير يتجاوز ثوانٍ قليلة يُفسد التجربة. استخدم العوامل المجدولة للعمل الدوري أو المجمّع حيث يكون التوقيت قابلاً للتنبؤ. القيد: يجب أن تكون العوامل المُشغَّلة بالأحداث عديمة الحالة وسريعة؛ أما المجدولة فيمكنها أن تكون حاملة للحالة وأبطأ.
كل أربعاء. أكثر من 28,400 مشترك. بدون حشو.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
جدول المحتويات
محدَّث مايو 2026.
TL;DR: استخدم العوامل المُشغَّلة بالأحداث حين تستلزم إجراءات المستخدم ردّاً فورياً — أيّ تأخير يتجاوز ثوانٍ قليلة يُفسد التجربة. استخدم العوامل المجدولة للعمل الدوري أو المجمّع حيث يكون التوقيت قابلاً للتنبؤ. القيد: يجب أن تكون العوامل المُشغَّلة بالأحداث عديمة الحالة وسريعة؛ أما المجدولة فيمكنها أن تكون حاملة للحالة وأبطأ.
[منظور المشغِّل] أُدير أكثر من 30 عاملاً في بيئة الإنتاج عبر علامتي التجارية الاستشارية وPickleland، منشأة بيكلبول في Pflugerville، TX. كلٌّ منها ينتمي إلى أحد نمطين: يُفعَّل بحدث، أو يُفعَّل بساعة. الخطأ في هذا الاختيار يُهدر المال ويُسلِّم تجارب معطوبة.
النمطان بلغة مبسّطة
العامل المُشغَّل بالأحداث يصحو لأن شيئاً ما حدث. وصل حجز. نُشر تعليق. أُرسل نموذج. المشغِّل خارجي وغير متوقع التوقيت. المهمة: الرد السريع.
العامل المجدوَل يصحو لأن الساعة قالت ذلك. كلّ صباح الساعة السابعة. كلّ أحد الساعة السادسة مساءً. كلّ ساعة عند الساعة الكاملة. المشغِّل داخلي وقابل للتنبؤ تماماً. المهمة: تأدية عمل دقيق ومتأنٍّ.
هذا كلّ شيء. لا تُعقِّد الأمر. تنبع البنية من الإجابة عن سؤال واحد: هل يحتاج المستخدم أو النظام إلى ردٍّ الآن، أم يمكن الانتظار حتى وقت محدد؟
المُشغَّل بالأحداث: عامل الردّ على التعليقات في وسائل التواصل الاجتماعي
يُفعَّل عامل ردّي على التواصل الاجتماعي كلّما ظهر تعليق جديد على منشور Facebook خاضع للمراقبة. يقرأ العامل التعليق، ويُصنِّف النية (سؤال، شكوى، إطراء، بريد مزعج)، ويصيغ ردّاً، ثم ينشره — أو يُضيفه لقائمة المراجعة البشرية إن كانت الثقة منخفضة.
يجب أن تنتهي الدورة الكاملة في أقل من 30 ثانية، وإلا بدا الردّ متأخراً. هذه مشكلة نمط التفعيل بالأحداث.
إليك Cloudflare Worker مبسَّطاً يعالج الـwebhook من خدمة مراقبة اجتماعية:
// workers/social-reply.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== "POST") {
return new Response("Method not allowed", { status: 405 });
}
// التحقق من توقيع الـwebhook
const sig = request.headers.get("x-webhook-signature") ?? "";
const body = await request.text();
const valid = await verifySignature(body, sig, env.WEBHOOK_SECRET);
if (!valid) return new Response("Unauthorized", { status: 401 });
const event = JSON.parse(body) as SocialCommentEvent;
// التصنيف والردّ — إبقاؤه async للإعادة السريعة بـ200
env.REPLY_QUEUE.send(event);
return new Response("OK", { status: 200 });
},
};
// مستهلك الطابور — يُنجز العمل الحقيقي للذكاء الاصطناعي
export const queue: ExportedHandlerQueueHandler<Env, SocialCommentEvent> =
async (batch, env) => {
for (const msg of batch.messages) {
const comment = msg.body;
const classification = await classifyComment(comment.text, env);
if (classification.intent === "spam") {
msg.ack();
continue;
}
const reply = await draftReply(comment, classification, env);
if (classification.confidence > 0.85) {
await postReply(comment.postId, comment.id, reply, env);
} else {
await flagForReview(comment, reply, env);
}
msg.ack();
}
};شيئان تجدر ملاحظتهما. أولاً، يُعيد معالج الـfetch الاستجابة 200 فوراً ويُحيل العمل الحقيقي إلى طابور. هذا يُبقي استجابة الـwebhook سريعة ويمنع خدمة المراقبة من إعادة المحاولة. ثانياً، يُنفِّذ مستهلك الطابور استدعاء الذكاء الاصطناعي الفعلي — التصنيف والصياغة — دون ضغط زمني من اتصال HTTP مفتوح.
المجدوَل: مروِّج فعاليات Pickleland
يُدير Pickleland ملاعب وفعاليات. كلّ أسبوع يحتاج أحدهم إلى نشر الفعاليات القادمة في مجموعات Facebook المناسبة لملء المقاعد. هذا عمل دُفعي دوري بحت — لا يُشغِّله أيّ إجراء من المستخدم، ولا حاجة لأن يحدث في الوقت الفعلي.
يعمل مروِّج فعاليات Pickleland على cron، ويتحقق من نظام الحجز للفعاليات في الأيام الأربعة القادمة، ويصيغ منشورات خاصة بكل مجموعة Facebook مطابقة، ويعرضها لمراجعتي قبل أن يُنشَر أيّ شيء.
// workers/event-promoter.ts
export default {
async scheduled(
event: ScheduledEvent,
env: Env,
ctx: ExecutionContext
): Promise<void> {
ctx.waitUntil(runPromoter(env));
},
};
async function runPromoter(env: Env): Promise<void> {
// سحب الفعاليات من نظام الحجز
const upcomingEvents = await fetchUpcomingEvents(env, { daysAhead: 4 });
if (upcomingEvents.length === 0) return;
const drafts: PromoDraft[] = [];
for (const event of upcomingEvents) {
// مطابقة كل فعالية مع مجموعات FB المناسبة
const groups = await matchFacebookGroups(event, env);
for (const group of groups) {
const post = await draftPromoPost(event, group, env);
drafts.push({ event, group, post });
}
}
// حفظ المسوَّدات في Airtable للمراجعة — لا شيء يُنشَر تلقائياً
await saveDraftsForReview(drafts, env);
// إشعاري عبر Slack
await notifyOperator(
`${drafts.length} مسوَّدات ترويجية جاهزة للمراجعة`,
env
);
}إعداد wrangler الذي يربط كلّ شيء:
# wrangler.toml
[[triggers]]
crons = ["0 18 * * 0"] # كل أحد الساعة 18:00 UTCلاحظ ما يستطيع العامل المجدوَل فعله ممّا يعجز عنه المُشغَّل بالأحداث: يتكرر عبر فعاليات متعددة، ويكتب إلى قاعدة بيانات، ويُرسل إشعاراً ملخَّصاً. إنه يؤدّي عملاً دُفعياً. على العامل المُشغَّل بالأحداث أن يظل خفيفاً ويعيد الاستجابة بسرعة.
المجدوَل: الموجز اليومي
كلّ صباح الساعة السابعة يعمل عامل الموجز اليومي الخاص بي. يسحب رسائل البريد الإلكتروني الليلية، وتقويمي، والمهام العُليا، وأيّ أخبار وضعتُ عليها علامة مناسبة. يُنسِّق كلّ شيء في مستند واحد ويضعه في مجلد AI Workspace.
هذا محدوَل بحت. لا يوجد حدث يُشغِّله — أريده ببساطة كلّ صباح قبل أن أبدأ العمل.
// workers/daily-brief.ts
export default {
async scheduled(
event: ScheduledEvent,
env: Env,
ctx: ExecutionContext
): Promise<void> {
ctx.waitUntil(buildDailyBrief(env));
},
};
async function buildDailyBrief(env: Env): Promise<void> {
const [emails, calendar, tasks] = await Promise.all([
fetchOvernightEmails(env),
fetchTodayCalendar(env),
fetchTopTasks(env),
]);
const brief = await synthesizeBrief({ emails, calendar, tasks }, env);
await writeToWorkspace(brief, env);
}[[triggers]]
crons = ["0 7 * * *"] # كل يوم الساعة 7:00 UTCPromise.all المتوازي مقصود. العوامل المجدولة ليس ثمة إنسان ينتظر — لكنها لا ينبغي أن تكون أبطأ مما ينبغي. اسحب جميع مصادر البيانات بالتوازي، ثم أجرِ تركيب الذكاء الاصطناعي مرة واحدة.
متى تفشل العوامل المُشغَّلة بالأحداث
نمط الفشل الأكثر شيوعاً: يبني أحدهم عاملاً مُشغَّلاً بالأحداث يؤدّي عملاً كثيراً داخل المعالج.
يصل حجز. يسحب العامل ملف تعريف العميل، ويُثريه من ثلاثة واجهات برمجية خارجية، ويشغِّل نموذج التخصيص، ويكتب إلى CRM، ويرسل بريد التأكيد، ويُحدِّث لوحة بيانات. يستغرق الأمر برمّته 45 ثانية. تُعيد المنصة المحاولة لأنها لم تتلقَّ 200 بسرعة كافية. الآن يعمل العامل مرتين.
الحلّ كما في عامل ردّ التعليقات: أعِد 200 فوراً، ادفع الحدث إلى الطابور، دع مستهلك الطابور يُنجز العمل الثقيل بشكل غير متزامن.
نمط الفشل الآخر: استخدام التفعيل بالأحداث لعمل دوري في حقيقته. “إرسال ملخّص أسبوعي” ليس حدثاً. لا تربطه بـwebhook cron اصطناعي — استخدم مشغِّلاً مجدولاً مناسباً.
متى تفشل العوامل المجدولة
تفشل العوامل المجدولة حين يكون العمل حساساً للكمون في حقيقته. إن أرسل مستخدم نموذجاً والعامل المعالِج له يعمل على cron كلّ 5 دقائق، فسيحدق المستخدم في مؤشر تحميل لمدة تصل إلى 5 دقائق. هذا ليس عملاً مجدولاً — إنه عمل مُشغَّل بأحداث بطيء يتظاهر بأنه مجدول.
الفشل الآخر: العوامل المجدولة التي تتوسع في عمل غير محدود. إن عمل الـcron كل دقيقة واستطاع كل استدعاء معالجة مئات السجلات، ستصطدم بحدود CPU في Cloudflare بسرعة. إما أطِل فترة الـcron، أو أضف طابوراً لتقييد العمل لكل استدعاء، أو انتقل إلى Durable Objects للتنسيق طويل الأمد.
الجمع بين النمطين: خطّ معالجة الحجوزات
تحتاج بعض سيرورات العمل فعلاً إلى كليهما. يعمل خطّ معالجة حجوزات Pickleland هكذا:
- مُشغَّل بالأحداث: webhook حجز جديد ← تأكيد الحجز، إرسال الإيصال للعميل، تحديث الإتاحة. يجب أن يكتمل في أقل من 10 ثوانٍ.
- مجدوَل: كلّ أحد ← مراجعة جميع حجوزات الأسبوع الماضي، إنشاء تقرير ملخَّص، الإشارة إلى الشذوذات (حجوزات مكرَّرة، معدلات إلغاء غير معتادة).
نفس المجال، نمطان، عاملان. المُشغَّل بالأحداث يمتلك تجربة المستخدم في الوقت الفعلي. المجدوَل يمتلك المراجعة التشغيلية الأسبوعية. يتشاركان قاعدة بيانات لا غير.
لا تحاول دمجهما في عامل واحد يفعل “كلّ شيء”. ستنتهي بشيء بطيء جداً للأحداث ومترابط جداً مع التدفق الفعلي للعمل الدُّفعي.
Cloudflare Workers: لماذا هو البنية التحتية المناسبة لكليهما
يتعامل Cloudflare Workers مع كلا النمطين بشكل أصلي:
- معالج
fetch← مُشغَّل بالأحداث (webhooks، استدعاءات API) - معالج
scheduled← مستند إلى cron (عبر[[triggers]]في wrangler.toml) - مستهلك
queue← معالجة غير متزامنة مفصولة عن طبقة HTTP
يعني النشر على الحافة أن عواملك المُشغَّلة بالأحداث تستجيب بسرعة عالمياً. المستوى المجاني سخيٌّ بما يكفي لاختبار كلا النمطين دون إنفاق أيّ شيء. والإعداد الموحَّد لـwrangler.toml يعني أنك لا تُدير منظومتي بنية تحتية منفصلتين لنمطين.
الشيء الوحيد الذي لا يحلّه Workers جيداً: العوامل التي تحتاج إلى العمل لأكثر من بضع دقائق. لهذه، ألجأ إلى Durable Objects أو فوِّض الأمر إلى خلفية أطول أمداً.
خلاصة المشغِّل
اختر نمطك قبل كتابة سطر واحد من كود العوامل. مُشغَّل بالأحداث لكلّ ما ينتظره إنسان؛ مجدوَل لكلّ ما يسير وفق ساعة. أبقِ معالجات المُشغَّل بالأحداث رشيقة — أعِد الاستجابة بسرعة، وضع العمل في الطابور. أبقِ العوامل المجدولة متوازية — لا تُسلسل ما يمكن تشغيله بالتوازي. البنية بسيطة. انتهاكها هو مصدر التعقيد.
كل أربعاء. أكثر من 28,400 مشترك. بدون حشو.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
احصل على دليل الذكاء الاصطناعي في صندوق بريدك
كل أربعاء. أكثر من 28,400 مشترك. بدون حشو.
Check your inbox.
We sent you a confirmation email — click the link inside to complete your subscription. Check spam if you don't see it within a minute.
You're subscribed.
Welcome — the next edition lands in your inbox soon.
You're already on the list — look for it every Wednesday.