الحياة السرية لخدمات عامل امتداد Chrome

May 10, 2024

أثناء عملي على امتداد WebSocket debugger، كنت أحيانًا ألاحظ ظهور نوافذ إضافية بشكل غير متوقع. من الواضح أن خدمة العامل الخاص بالامتداد كانت تُعاد تهيئتها في بعض الأوقات. عند إعادة التشغيل، كان يفحص الإعدادات الخاصة به، ويكتشف الحاجة إلى وجود نافذة مفتوحة، فيقوم بإنشاء نافذة جديدة — دون أن يكون مدركًا للنافذة الموجودة بالفعل. كان الأمر أشبه بأن العامل لديه عقل خاص به، بدلاً من أن يعمل باستمرار في الخلفية. كانت عمليات إعادة التشغيل هذه تحدث في فترات تبدو عشوائية.

اقرأ عن دور خدمات العمال في امتدادات Chrome إذا كنت تريد معرفة المزيد عن استخدامهم. في الأساس، خدمة العامل الخاصة بك هي قلب امتدادك. تعمل عند تثبيت الامتداد وتتعامل مع كل الأعمال الخلفية. فكر بها على أنها تمنح امتدادك قوى خارقة — ولكن كما يُقال، 'مع القوة العظيمة تأتي المسؤولية العظيمة'.

مقتطف كود يعرض إعداد سكريبت الخلفية لخدمة العامل في امتداد Chrome

فهم دورة حياة خدمة العامل لأداء أفضل للامتداد

خدمة العامل لا تبدأ عملها فقط أثناء التثبيت. يمكن تفعيلها في نقاط مختلفة، لذا يجب أن تكون مستعدة للتعامل مع ذلك بسلاسة. هذا يعني فهم مهامها عند كل إعادة تشغيل — ما يجب تهيئته وما قد يكون قيد التقدم بالفعل. النقطة الأساسية هي أنه إذا كانت تعمل مرة أخرى، فهذا يعني أنها تم إنهاؤها في وقت سابق.

لتوفير الذاكرة والطاقة، يمكن لـ Chrome (وسيقوم!) بإنهاء خدمة العامل وحالتها متى لم يكن الامتداد قيد الاستخدام النشط. عادة ما يكون هناك سبب وراء هذا. إليك السيناريوهات الشائعة التي تؤدي إلى الإنهاء:

  • تحديث أو تثبيت الامتداد: تؤدي التغييرات في كود الامتداد إلى ضرورة إعادة تشغيل خدمة العامل.
  • إغلاق Chrome: عند إغلاق المتصفح، يتم إنهاء خدمات العمال.
  • مهلة الخمول (30 ثانية): السبب الأساسي لإنهاء خدمات العمال — يتم ذلك للحفاظ على الموارد.
  • طلب طويل الأمد (أكثر من 5 دقائق): لمنع تجمّد خدمات العمال، يتم إنهاء تلك المتعلقة بالطلبات المطوّلة.
  • تأخير استجابة الجلب (أكثر من 30 ثانية): بالمثل، تؤدي عمليات الجلب التي تستغرق وقتًا طويلًا إلى إنهاء خدمة العامل.

للحصول على التفاصيل الكاملة عن دورة الحياة، اطلع على مستندات مطوري Chrome.

التخزين المحلي لامتدادات Chrome لتجربة مستخدم سلسة

عندما يتم إنهاء خدمة العامل الخاصة بك، تختفي كل المتغيرات والمستمعين لديك. هذا يسبب مشاكل إذا كنت، كمصحح أخطاء WebSocket, تعتمد على تتبع النوافذ المفتوحة والنشطة ومعرفاتها. للحفاظ على سير الأمور بسلاسة، تحتاج إلى تخزين هذه المعلومات بشكل مستمر. بهذه الطريقة، عند إعادة التشغيل، يمكنك استعادتها وإعادة التهيئة بشكل صحيح، وعلى الأرجح، لن يلاحظ المستخدم أي تغيير.

هنا يأتي دور التخزين المحلي في Chrome للإنقاذ. إنه أداة مثالية لحفظ هذه البيانات وأشياء أخرى يحتاج امتدادك لتذكرها.

مقتطف كود يوضح كيف يستخدم عامل خدمة امتداد Chrome التخزين المحلي

التعامل مع الحالات الخاصة: التحديثات وصيانة الامتداد بسلاسة

لقد تناولنا التهيئة العادية، لكن هناك حالات خاصة، مثل بعد تحديث الامتداد، حيث قد ترغب في مسح الحالة. لحسن الحظ، يسمح لك Chrome بتثبيت مستمع 'onInstalled' داخل خدمة العامل الخاصة بك. هذا هو الشكل الذي يبدو عليه:

مقتطف كود يوضح كيف يهيئ عامل خدمة امتداد Chrome مستمع 'onInstalled'

ملاحظة هامة: إذا تم إعداد مستمع 'onInstalled' الخاص بخدمة العامل قبل الإنهاء، فسيختفي. سيتعين عليك إعادة تثبيته. من المثالي أن يكون هذا أول شيء تفعله خدمة العامل عند إعادة التشغيل، خاصة إذا كانت تعتمد على الأعلام التي يهيئها المستمع.

في تجربتي، يبدو أن مستمع 'onInstalled' يتم تفعيله فور التثبيت، كلما دعت الحاجة، لأن التهيئة نفسها هي حدث تثبيت. لحسن الحظ، لم أواجه أي مشاكل في السباق هنا. مع ذلك، من المهم أن تتذكر أن هذا المستمع لن يُستدعى عند إعادة التشغيل بعد مهلات الخمول أو الطلب أو الجلب التي تسببت في الإنهاء.

مثال: WebSocket debugger — دراسة حالة في إدارة حالة الامتداد

بالنسبة لـ WebSocket debugger على وجه التحديد، من الضروري معرفة ما إذا كانت نافذته مفتوحة بالفعل أو تحتاج إلى الفتح. نظرًا لأن أحداث التثبيت تجبر جميع علامات التبويب والنوافذ المتعلقة بالامتداد على الإغلاق، فإن تحديد ما إذا كانت إعادة التشغيل الحالية بسبب التثبيت يصبح أمرًا حيويًا.

مخطط انسيابي يوضح عملية تهيئة خدمة العامل لامتداد Chrome
مثال على تدفق التهيئة

وهكذا يتعامل WebSocket debugger مع هذا: بمجرد فتح النافذة الخاصة به، يقوم الامتداد بحفظ معرف النافذة في التخزين المحلي. وبهذه الطريقة، إذا تم إنهاء خدمة العامل، فإنه يعرف أن النافذة موجودة وأين يجدها، والأهم من ذلك، أنها مفتوحة وجاهزة بالفعل. بالإضافة إلى ذلك، لدى خدمة العامل مستمعون على النافذة لاكتشاف متى يغلق المستخدم النافذة. إذا حدث ذلك، يتم ضبط حالة تمكين النافذة على ``خطأ``، مع تحديث التخزين المحلي، ووضع علامة على النافذة بأنها مغلقة، ومسح المعرف.

احذر من التطورات غير المتوقعة: وقت الشبكة وموثوقية المستمع

هنا نقطة حاسمة: عندما يتم إنهاء خدمة العامل، تفقد كل مستمعي النوافذ الخاصة بها. إذا أغلق المستخدم نافذة المصحح بينما كانت خدمة العامل غير نشطة، فلن يتم اكتشاف حدث الإغلاق. هذا يؤدي إلى تعارض بين الحالة المخزنة (التي تفترض أن النافذة مفتوحة) والحالة الفعلية (حيث النافذة مغلقة). وبما أننا لا نستطيع معرفة نية المستخدم بشكل قاطع، فإن النهج الأكثر أمانًا هو تعطيل النافذة إذا كانت الحالة المخزنة تشير إلى أنها مفتوحة ولكن لا يمكن العثور عليها. الاستنتاج الرئيسي هو الحاجة إلى التحقق بدقة من متغيرات الحالة الخاصة بك. تأكد من أن أية معلومات يعتقد امتدادك بأنها صحيحة، تنعكس فعليًا في الحالة الحالية للنافذة.

حل لمراقبة الوقت: مؤقت المراقب لامتدادات قوية

هناك مشكلة أخرى تتعلق بدورة حياة WebSocket debugger، وهذه المشكلة خاصة بالآلة (بالتأكيد مشكلة على أجهزة Mac). عند التعامل مع بيانات WebSocket، جميع الطوابع الزمنية تكون نسبية لنقطة زمنية محددة تُسمى وقت الشبكة الموحد (network monotonic time). كل أحداث الشبكة تشترك في هذا الوقت، وعلى الرغم من أن بداية العهد الدقيقة ليست بالضرورة حاسمة، إلا أنها عادة ما تكون صفر عند بدء تشغيل المتصفح.

الحل بسيط: قم بتسجيل وقت الساعة الحائطية جنبًا إلى جنب مع أول طابع زمني موحد للشبكة لديك. مع بعض الرياضيات البسيطة، يمكنك بعد ذلك تحويل أي طوابع زمنية موحدة مستقبلية إلى الوقت الحقيقي.

كود لتحويل الطوابع الزمنية الموحدة إلى الوقت الحقيقي في خدمة عامل امتداد Chrome

التعامل مع غير المتوقع: عندما يتوقف وقت الشبكة الموحد أثناء وضع السكون

إنه حل بسيط وجيد ... حتى يذهب الكمبيوتر المحمول إلى وضع السكون ويستيقظ. لقد تناولنا إنهاء خدمة العامل، لكن هناك منعطف آخر: وقت الشبكة الموحد يتوقف عندما ينام جهازك! يبدأ من جديد عندما يستيقظ الجهاز. هذا جيد إذا تم إنهاء خدمة العامل أيضًا (نظرًا لإعادة تعيين كل المتغيرات). ومع ذلك، إذا ظلت خدمة العامل نشطة، فإن وظيفة تحويل الوقت الخاصة بك تبدأ فجأة في إرجاع الوقت الخاطئ. الساعة الحقيقية تحركت للأمام، لكن وقت الشبكة الموحد كان متجمدًا. إذا نمت لمدة ساعة، ستكون الطوابع الزمنية متأخرة الآن بساعة!

حل: تنفيذ مؤقت المراقب

لمواجهة هذا، نحتاج إلى آلية لاكتشاف دورات السكون/الاستيقاظ وضبط مرجع وقت الشبكة الموحد لدينا وفقًا لذلك. هنا يأتي دور مؤقت المراقب. إليك كيف يعمل في WebSocket debugger:

التهيئة: أثناء بدء خدمة العامل، يتم تعيين مؤقت للتشغيل بفواصل منتظمة (مثل كل دقيقة).

اليقظة: يقوم المؤقت بمقارنة الفاصل الزمني المتوقع مع الوقت الفعلي المنقضي منذ آخر فحص. يشير الانحراف الكبير إلى أن الجهاز على الأرجح دخل في وضع السكون.

إعادة التعيين: إذا تم اكتشاف السكون، تتم مسح نقاط مرجع وقت الشبكة الموحد وإعادة تهيئتها، مما يضمن بقاء الطوابع الزمنية متزامنة مع الوقت الحقيقي.

 مقتطفات الكود التي تبرز الجوانب الأساسية لعامل خدمة امتداد Chrome

كتابة امتدادات Chrome كانت رحلة مليئة بالتحديات! إنها تحدٍ مستمر لإنشاء شيء موثوق ومتسق عندما يكون لديك قدرة قليلة جدًا على التحكم المباشر في البيئة التي يعمل فيها كودك. لكن، من لا يحب بعض التحديات؟

لقطة شاشة لتتبع Websocket أثناء تصحيح متصفح
لقطة شاشة لـ Websocket Debugger

حول المؤلف

Kate Wilkins هي مهندسة رئيسية في Deriv ولديها شغف مدى الحياة بالتعلم المستمر، ليس فقط التكنولوجيا ولكن لكل شيء من لغات البرمجة، الأُطُر، والتقنيات الأساسية إلى الإبحار والبناء.

المحتويات