The Chromium Chronicle #1: أفضل ممارسات جدولة المهام

يفخر فريق Chrome بتقديم Chromium Chronicle، وهي سلسلة شهرية موجَّهة خصيصًا لمطوّري برامج Chromium، ومطوّري البرامج الذين يطوّرون المتصفّح.

ستركّز خدمة Chromium Chronicle بشكل أساسي على نشر المعرفة التقنية وأفضل الممارسات لكتابة محتوى Chrome وإنشائه واختباره. وتتمثّل خطتنا في عرض المواضيع ذات الصلة والمفيدة لمطوّري برامج Chromium، مثل سلامة الرمز البرمجي والأدوات المفيدة واختبار الوحدات وإمكانية الوصول وغير ذلك الكثير. ستتم كتابة كل مقالة وتعديلها من قبل مهندسي Chrome.

نحن متحمّسون بشأن هذا المسلسل الجديد ونأمل منك مشاركتنا مستوى الحماس نفسه. هل أنت مستعد لخوض التجربة؟ يمكنك إلقاء نظرة على الحلقة الأولى أدناه.

أفضل ممارسات جدولة المهام

الحلقة 1: لـ "غابرييل شاريت" في مونتريال، PQ (نيسان/أبريل 2019)
الحلقات السابقة

إنّ رمز Chrome الذي يحتاج إلى تنفيذ غير متزامن ضمن العملية عادةً ما ينشر المهام في التسلسلات. التسلسلات هي "سلاسل محادثات افتراضية" يديرها Chrome ومُفضَّلة لإنشاء سلسلة محادثات خاصة بك. كيف يعرف الكائن أي تسلسل يجب النشر إليه؟

الإجراءات غير المُوصى بها

النموذج القديم هو الحصول على سلسلة SerialdTaskRunner من منشئ المحتوى:

Foo::Foo(scoped_refptr backend_task_runner)
    : backend_task_runner_(std::move(backend_task_runner)) {}
الإجراءات التي يُنصح بها

النموذج المفضل هو إنشاء تسلسل مهام تسلسلي مستقل:

Foo::Foo()
    : backend_task_runner_(
          base::CreateSequencedTaskRunnerWithTraits({
              base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}

من السهل قراءة وكتابة هذا لأن جميع المعلومات محلية وليس هناك خطر للتبعية المتبادلة مع المهام غير ذات الصلة.

هذا النموذج أفضل أيضًا عندما يتعلق الأمر بالاختبار. وبدلاً من إدخال برامج تشغيل المهام يدويًا، يمكن للاختبارات إنشاء بيئة مهام خاضعة للرقابة لإدارة مهام Foo:

class FooTest : public testing::Test {
 public
  (...)
 protected:
  base::test::TaskEnvironment task_environment_;
  Foo foo_;
};

إن وجود TaskEnvironment أولاً في الإعداد يضمن إدارة بيئة المهام طوال عمر Foo. ستلتقط TaskEnvironment طلب Foo عند الإنشاء لإنشاء SequencedTaskRunner وستدير مهامها ضمن كل FooTest.

لاختبار نتيجة التنفيذ غير المتزامن، استخدِم نموذج RunLoop::Run()+QuitClosure():

TEST_F(FooTest, TestAsyncWork) {
  RunLoop run_loop;
  foo_.BeginAsyncWork(run_loop.QuitClosure());
  run_loop.Run();
  EXPECT_TRUE(foo_.work_done());
}

ويُفضل إجراء ذلك على RunUntillIdle() ، والتي قد تصبح غير مستقرة إذا كان عبء العمل غير المتزامن يتضمّن مهمة خارج نطاق TaskEnvironment، على سبيل المثال، حدث نظام، لذا استخدِم RunUntilIdle() بحرص.

هل تريد الحصول على مزيد من المعلومات؟ يمكنك الاطّلاع على مستنداتنا حول سلسلة المحادثات والمهام أو المشاركة في نقل البيانات إلى TaskEnvironment.