الانتظار، والوصول إليك
منذ v1.0.303 صار لنصفَي المشكلة الواحدة جوابان. فالدورُ كثيراً ما يضطرّ أن يكون خاملاً — بناءٌ بدأه للتوّ، أو حدُّ معدَّلٍ ينتظر انقضاءه، أو تصييرٌ يحتاج عشر دقائق — وحتى ذلك الحين لم تكن هناك طريقةٌ صادقة ليكون. ولم تكن لوولفيش طريقةٌ للوصول إليك بعد أن تُشيح بنظرك: ينتهي دور، أو تظهر بطاقةُ موافقةٍ وتنتظر، وإن لم تكن النافذةُ أمامك فلا شيء يقول ذلك. الأولى هي أداةُwait. والثانية هي إشارة انتباه نظام التشغيل. وهما آليّتان منفصلتان — هذه تُبقي الدور حيّاً، وتلك تربت على كتفك — وتغطّي هذه الصفحة كلتيهما.
أداة wait
كانت ثلاثةُ خياراتٍ سيّئة تملأ هذا الفراغ: sleep في الصدفة لا تراه ولا تقاطعه، أو استدعاءُ الأداة نفسها مراراً في حلقة استقصاء، أو التسليم والقول إنه سيعود لاحقاً، وهذا يعني البدء من الصفر.
والآن تحجز wait الدورَ للمدّة التي تطلبها بالضبط:
- بلا سقف. عشرُ ثوانٍ أو أربعُ ساعات، ما يحتاجه العملُ فعلاً. وزمنُ التنفيذ لا يقيّدها عمداً — فالسقفُ يعيدك إلى حلقة الاستقصاء التي وُجدت لتحلّ محلّها. ومرّر المدة بوحدةٍ واحدة؛ والنموذج مُوجَّهٌ أن يطلب المدة الحقيقية بدل تقسيم انتظارٍ واحد إلى عدّة.
- السبب مطلوب، سطرٌ واحد بكلماتك، ويصبح عنوانَ البطاقة. فوقفةٌ بلا تفسير لا تُميَّز عن تعليق، فترفض الأداة بدونها.
- انتظارٌ واحد لكلّ محادثة. فاستدعاءُ
waitثانٍ متزامن عطلٌ في النموذج لا طلبٌ في الطابور، فيُرفض بدل أن يُكدَّس.
البطاقة
أثناء عمل الانتظار تعرض المحادثةُ بطاقةً تقول لماذا هو خامل ومتى سيستيقظ، بعدّادٍ تنازليّ — وصندوقاً تكتب فيه لتنهي الانتظار فوراً. وكلُّ ما ترسله يفعل ذلك: الصندوقُ نفسه، أو المحرِّر، أو هاتفك، أو تيليجرام، أو واتساب، أو الطرفيّة. ورسالتُك لا يستهلكها الانتظار — تبقى في صندوق منتصف الدور وتصل كأوّل ما يقرأه الوكيل، بالترتيب الذي أرسلتَه. انظر قول شيءٍ وهو يعمل. وللانتظار ثلاثُ نهايات، وتسمّي نتيجةُ الأداة أيَّها وقعت:الدورُ كلُّه ينجو
هذا هو الفرقُ الحقيقيّ بينwait وكلّ حلٍّ مؤقّت. فالدورُ لا ينتهي ويُعاد، بل يُحتجَز. الملفّاتُ التي كانت مفتوحة، وما استنتجه بالفعل، وبقيّةُ خطّته: كلُّ ذلك ما زال هناك حين يعود الانتظار، وينطلق استدعاءُ الأداة التالي من تلك الحالة بعينها.
ولهذا تُصرّ العقيدةُ على أداةٍ واحدة لكلّ موقف، والثلاثُ كانت تتشابك:
عدّادٌ ليس انتظاراً
يبدوان من الخارج متشابهين، وهما في الجوهر نقيضان. فـwait يُبقي الدور وكلَّ ما فيه، وأنت تنوي إتمام العمل بنفسك. وcountdown_start ينهي الدور أولاً ثمّ يشغّل استدعاءَ أداةٍ واحداً بالضبط ولا شيء بعده — ولهذا وُجد: لإعادة تشغيلٍ أو إغلاقٍ أو خروجٍ أو أيّ خطوةٍ لا رجعة فيها تقطع الرسالةَ التي تُعلنها. ويظهر كبطاقةٍ بعدّادٍ حيّ وزرّ إلغاء، ويُسلَّح كآخر فعلٍ في الدور.
قول شيءٍ وهو يعمل
منذ v1.0.296 تُسلَّم الرسالةُ المكتوبة في دورٍ جارٍ إلى العمل الجاري بدل أن تقف في طابورٍ خلفه. ويقرأها الوكيل في خطوته التالية — لحظةَ ينتهي دفعةُ استدعاءات الأدوات التي يشغّلها، قبل أن يختار التي بعدها.- تهبط كرسالةٍ حقيقيّةٍ لك، في الموضع الذي قُرئت فيه بالضبط. فـ_«تجاوز مجلّد الاختبارات»_ و_«استخدم الملفّ الآخر»_ و_«هذا يكفي، لخّص ما لديك»_ تفعل ما تقوله والدورُ ما يزال جارياً.
- وقبل أن تُقرأ تجلس كفقاعةٍ خاصّةٍ بها موسومة «تُقرأ في الخطوة التالية»، مع × يعيدها إلى المحرِّر كمسوَّدة. ومتى قرأها الوكيل ذهبت الـ×، لأنّ رسالةً سُلِّمت صارت جزءاً من المحادثة.
- وتعمل في كلّ مكان: التطبيق، والطرفيّة (
escيستعيد الأخيرة)، وهاتفك، وتيليجرام، وواتساب — والرسائلُ الصوتيّة تُحتسَب، تُنسَخ نصّاً قبل تسليمها. - ومنذ v1.0.300 تُكتب كلُّ رسالةٍ في منتصف الدور إلى القرص قبل أن يُقال لك إنها قُبلت، ولا تُطلق إلا بعد أن تسكن في مكانٍ آخر بشكلٍ مؤكَّد — في المحادثة، أو في نصّها عند الموضع الذي قُرئت فيه. فسطحُ مكتبٍ يغلق، أو هاتفٌ ينام في اللحظة الخطأ، أو دورٌ توقفه ورسالتُك غير مقروءة، لم يبقَ يستطيع أخذ كلماتك معه. وكلُّ ما عدا ذلك يُعاد: يُرسَل دوراً عاديّاً، أو يُعاد إلى المحرِّر كمسوَّدة حين تكون إعادةُ الإرسال إعادةَ تشغيل عملٍ أوقفتَه عمداً.
الرسالةُ التي تصل والوكيل يكتب جوابه الأخير تُبقي الدور حيّاً، فيجيبك في الدور نفسه بدل أن ينتهي ويبدأ من جديد. ومنذ v1.0.306 يخدم الصندوقُ نفسه العملَ المجدول — أتمتةً أو إجراءً أو مهمّةَ نبض — وهو بالضبط حيث يهمّ التوجيهُ أكثر ما يهمّ، لأنّ تلك الأدوار تعمل بلا إشرافٍ دقائقَ طويلة. انظر توجيه دورٍ أثناء الطيران.
إشارة انتباه نظام التشغيل
يستخدم وولفيش الإشارةَ التي يمتلكها نظامُ تشغيلك لهذا الأمر بالضبط، ولا يستحقّها إلا في لحظتين:
ومعنيان، يُبقيان منفصلين عمداً:
- انتهاءُ دورٍ خبر، فيأخذ نظرة — قفزةً واحدة ثمّ سكون. وعلى macOS هذا مستوى المعلومة.
- بطاقةٌ لا تستطيع المضيّ بدونك — موافقةٌ أو سؤال — طلبٌ لا خبر، فتظلّ تقفز حتى تعود فعلاً. وذلك مستوى الحرج، ولهذا وُجد المستويان منفصلين.
- لا شيءَ يقع وأنت تنظر إلى النافذة. نافذةٌ في المقدّمة تعني لا إشارةَ إطلاقاً.
- تُسحَب الإشارةُ لحظةَ عودتك إلى التطبيق أو إجابتك على البطاقة.
- العائقُ يعلو على الخبر. فبطاقةٌ تُركت منتظرة تحتفظ بقفزتها حتى لو انتهى دورٌ آخر وهي تنتظر — فلا يستطيع خبرُ جارةٍ أن يخفّض موافقةً قائمةً إلى نظرةِ ثانية.
- والأدوارُ الواردة من غير هنا لا تفعلها. فدورٌ جاء من هاتفك أو من تيليجرام أو واتساب أو من أتمتةٍ مجدولة لا يُقفز نافذةً لا ينتظر عندها أحد — فلكلٍّ من تلك طريقته في الوصول إليك. ولا تستدعيها إلا القناةُ داخل التطبيق.
- والإقلاعُ بلا واجهة لا يفعل شيئاً: بلا نافذةٍ مُحدَّدة (إقلاع
--headlessعلى خادم) يعود كلُّ استدعاءٍ قبل أن يلمس واجهةَ النظام.
انظر أيضاً
المسار
أين تجري خطوات الدور، وكيف ينتهي
الأتمتات
الأدوارُ المجدولة، وتوجيه أحدها أثناء الطيران
واجهة الطرفيّة
بطاقةُ الانتظار في الطرفيّة، ومراسلة منتصف الدور عبر SSH
إشعارات الهاتف
الوصولُ إليك حين لا تكون النافذةُ هي السطح