الفرق بين المراجعتين لصفحة: «Laravel/scheduling»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
 
(17 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE:جدولة المهام في Laravel}}</noinclude>
<noinclude>{{DISPLAYTITLE:جدولة المهام (Task scheduling) في Laravel}}</noinclude>
[[تصنيف:Laravel]]
[[تصنيف:Laravel|{{SUBPAGENAME}}]]
[[تصنيف:Laravel Digging deeper]]
[[تصنيف:Laravel Digging deeper|{{SUBPAGENAME}}]]
 
== مقدمة ==
== مقدمة ==
ربّما ولّدت في الماضي نقطة دخول Cron لكل مهمة أردت جدولتها في الخادم. لكن يمكن أن يصبح هذا متعبًا بسرعة لأن الجدولة أصبحت خارج تحكم المصدر وأصبح عليك أن تدخل ب SSH للخادم لإضافة نقاط دخول Cron.
ربّما ولّدت في الماضي نقطة دخول Cron لكل مهمة أردت جدولتها في الخادم. لكن يمكن أن يصبح هذا متعبًا بسرعة لأن الجدولة أصبحت خارج تحكم المصدر وأصبح عليك أن تدخل ب SSH للخادم لإضافة نقاط دخول Cron.


يسمح مجدول الأوامر في Laravel بتعريف جدول المهام داخل Laravel بطريقة سلسلة وواضحة. عند استخدام جدولة المهام، تحتاج لنقطة دخول Cron واحدة على الخادم. يُعرّف جدول المهام في التابع schedule من الملف app/Console/Kernel.php. لمساعدتك على البداية، يوجد مثال بسيط معرّف في التابع.
يسمح مجدول الأوامر في [[Laravel]] بتعريف جدول المهام داخل [[Laravel|Larave<nowiki/>l]] بطريقة سلسلة وواضحة. عند استخدام جدولة المهام، تحتاج لنقطة دخول Cron واحدة على الخادم. يُعرّف جدول المهام في التابع <code>schedule</code> من الملف <code>app/Console/Kernel.php</code>. لمساعدتك على البداية، يوجد مثال بسيط معرّف في التابع.


=== بدء مُجدول المهام ===
=== بدء مجدول المهام ===
عند استعمال مُجدول المهام، تحتاج فقط لتعريف نقطة دخول Cron على الخادم. إن كنت لا تعرف كيفية العمل ب Cron، يمكنك استعمال خدمات مثل Laravel Forge التي ستغير نقطة دخول Cron:
عند استعمال مُجدول المهام، تحتاج فقط لتعريف نقطة دخول Cron على الخادم. إن كنت لا تعرف كيفية العمل ب Cron، يمكنك استعمال خدمات مثل Laravel Forge التي ستغير نقطة دخول Cron:<syntaxhighlight lang="php">
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
</syntaxhighlight>سينادي هذا الأمر مجدول المهام كل دقيقة. عند تنفيذ الأمر <code>schedule:run</code>، سيقيّم [[Laravel]] المهام المجدولة وينفّذ المهام التي حان وقتها.


<nowiki>*</nowiki> * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
== تعريف جدول المهام ==
يمكنك تعريف كل المهام المجدولة في التابع <code>schedule</code> من الصنف <code>App/Console/Kernel</code>. للبدء، لنلق نظرة على المثال المذكور في التابع. في هذا المثال، سنجدول نطاقًا مغلقًا Closure ليُنفَّذ في كل يوم عند منتصف الليل. في النطاق المغلق Closure، سنُنفِّذ استعلامًا لقاعدة البيانات لتفريغ جدول:<syntaxhighlight lang="php">


سينادي هذا الأمر مجدول المهام كل دقيقة. عند تنفيذ الأمر schedule:run، سيقيّم Laravel المهام المجدولة وينفّذ المهام التي حان وقتها.
== تعريف جدول المهام ==
يمكنك تعريف كل المهام المجدولة في التابع schedule من الصنف App/Console/Kernel. للبدء، لنلق نظرة على المثال المذكور في التابع. في هذا المثال، سنجدول نطاقًا مغلقًا Closure ليُنفَّذ في كل يوم عند منتصف الليل. في النطاق المغلق Closure، سنُنفِّذ استعلامًا لقاعدة البيانات لتفريغ جدول:


<?php
<?php
سطر 24: سطر 22:
use DB;
use DB;


<?php
namespace App\Console;
use DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;


class Kernel extends ConsoleKernel
class Kernel extends ConsoleKernel
{
{


   /**
   /**
    *الأوامر التي يوفرها التطبيق
    *الأوامر التي يوفرها التطبيق
    *
    *
    * @var array
    * @var array
    */
    */


سطر 45: سطر 41:


      //
      //
   ];
   ];


   /**
   /**
    * تعريف جدول المهام.
    * تعريف جدول المهام.
    *
    *
    * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
    * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
    * @return void
    * @return void
    */
    */


   protected function schedule(Schedule $schedule)
   protected function schedule(Schedule $schedule)
   {
   {
       $schedule->call(function () {
       $schedule->call(function () {
           DB::table('recent_users')->delete();
           DB::table('recent_users')->delete();


       })->daily();
       })->daily();
   }
   }
}


}


بالإضافة لجدولة استعمال Closure، يمكنك استعمال كائنات قابلة للاستدعاء. الكائنات القابلة للاستدعاء هي أصناف PHP بسيطة تحتوي التابع invoke_:
</syntaxhighlight>


بالإضافة لجدولة استعمال Closure، يمكنك استعمال كائنات قابلة للاستدعاء. الكائنات القابلة للاستدعاء هي أصناف [[PHP]] بسيطة تحتوي التابع <code>invoke_</code>:<syntaxhighlight lang="php">
$schedule->call(new DeleteRecentUsers)->daily();
$schedule->call(new DeleteRecentUsers)->daily();
</syntaxhighlight>


=== جدولة أوامر artisan ===
=== جدولة أوامر artisan ===
بالإضافة لجدولة نداءات النطاق المغلق Closure، يمكنك جدولة أوامر artisan و أوامر نظام التشغيل. على سبيل المثال، يمكنك استعمال التابع command لجدولة أمر artisan بذكر إمّا اسمه وإمّا صنفه:
بالإضافة لجدولة نداءات النطاق المغلق Closure، يمكنك جدولة أوامر [[Laraval/artisan|Artisan]] و أوامر نظام التشغيل. على سبيل المثال، يمكنك استعمال التابع <code>command</code> لجدولة أمر Artisan بذكر إمّا اسمه وإمّا صنفه:<syntaxhighlight lang="php">
$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();


$schedule->command('emails:send --force')->daily();


$schedule->command(EmailsCommand::class, ['--force'])->daily();
</syntaxhighlight>


=== جدولة الوظائف في الطوابير ===
=== جدولة الوظائف في الطوابير ===
يُستعمل التابع job لجدولة الوظائف في الطوابير. توفّر هذه الطريقة جدولة سهلة دون استخدام التابع call وإنشاء نطاق مغلق Closure لإضافة المهام للطابور يدويًّا:
يُستعمل التابع <code>job</code> لجدولة الوظائف في الطوابير. توفّر هذه الطريقة جدولة سهلة دون استخدام التابع <code>call</code> وإنشاء نطاق مغلق Closure لإضافة المهام للطابور يدويًّا:<syntaxhighlight lang="php">
 
$schedule->job(new Heartbeat)->everyFiveMinutes();
$schedule->job(new Heartbeat)->everyFiveMinutes();
//إضافة المهمة لقائمة انتظار
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();


//إضافة المهمة لقائمة انتظار


$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();
</syntaxhighlight>


=== جدولة أوامر Shell ===
=== جدولة أوامر Shell ===
يُستعمل الأمر exec لجدولة أوامر نظام التشغيل :
يُستعمل الأمر <code>exec</code> لجدولة أوامر نظام التشغيل :<syntaxhighlight lang="php">
 
$schedule->exec('node /home/forge/script.js')->daily();
$schedule->exec('node /home/forge/script.js')->daily();
</syntaxhighlight>


=== جدولة خيارات التواتر Frequency options ===
=== جدولة خيارات التواتر Frequency options ===
بالطبع توجد أكثر من جدولة يمكن تعيينها للمهمة:
بالطبع توجد أكثر من جدولة يمكن تعيينها للمهمة:
{| class="wikitable"
{| class="wikitable"
|التعريف
!التابع
|التابع
!التعريف
|-
|-
| <code>;('* * * * *')‎->cron</code>
|تنفيذ جدول cron مخصص
|تنفيذ جدول cron مخصص
|<nowiki>->cron(*****)</nowiki>
|-
|-
| <code>;()‎->everyMinute</code>
|تنفيذ المهمة كل دقيقة
|تنفيذ المهمة كل دقيقة
|<nowiki>->everyMinute()</nowiki>
|-
|-
|<code>;()‎->everyFiveMinutes</code>
|تنفيذ المهمة كل خمس دقائق
|تنفيذ المهمة كل خمس دقائق
|<nowiki>->everyFiveMinutes()</nowiki>
|-
|-
| <code>;()‎->everyTenMinutes</code>
|تنفيذ المهمة كل عشر دقائق
|تنفيذ المهمة كل عشر دقائق
|<nowiki>->everyTenMinutes()</nowiki>
|-
|-
| <code>;()‎->everyFifteenMinutes</code>
|تنفيذ المهمة كل خمس عشرة دقيقة
|تنفيذ المهمة كل خمس عشرة دقيقة
|<nowiki>->everyFifteenMinutes()</nowiki>
|-
|-
| <code>;()‎->everyThirtyMinutes</code>
|تنفيذ المهمة كل نصف ساعة
|تنفيذ المهمة كل نصف ساعة
|<nowiki>->everyThirtyMinutes()</nowiki>
|-
|-
| <code>;()‎->hourly</code>
|تنفيذ المهمة كل ساعة
|تنفيذ المهمة كل ساعة
|<nowiki>->hourly()</nowiki>
|-
|-
| <code>;(‎->(hourlyAt(17</code>
|تنفيذ المهمة في الدقيقة 17 من كل ساعة
|تنفيذ المهمة في الدقيقة 17 من كل ساعة
|<nowiki>->hourlyAt(17)</nowiki>
|-
|-
|<code>;()‎‎->daily</code>
|تنفيذ المهمة كل يوم منتصف الليل
|تنفيذ المهمة كل يوم منتصف الليل
|<nowiki>->daily()</nowiki>
|-
|-
|<code>;('‎->dailyAt(‘13:00</code>
|تنفيذ المهمة كل يوم الساعة 13:00
|تنفيذ المهمة كل يوم الساعة 13:00
|<nowiki>->dailyAt(‘13:00’)</nowiki>
|-
|-
|<code>;(‎->twiceDaily(1, 13</code>
|تنفيذ المهمة يوميا على الساعة 1 و 13:00
|تنفيذ المهمة يوميا على الساعة 1 و 13:00
|<nowiki>->twiceDaily(1, 13)</nowiki>
|-
|-
|<code>;()‎->weekly</code>
|تنفيذ المهمة أسبوعيا
|تنفيذ المهمة أسبوعيا
|<nowiki>->weekly()</nowiki>
|-
|-
|<code>;('‎->weeklyOn(1, ‘8:00</code>
|تنفبذ المهمة أسبوعيا يوم الاثنين الساعة 8:00
|تنفبذ المهمة أسبوعيا يوم الاثنين الساعة 8:00
|<nowiki>->weeklyOn(1, ‘8:00’)</nowiki>
|-
|-
|<code>;()‎->monthly</code>
|تنفيذ المهمة كل شهر
|تنفيذ المهمة كل شهر
|<nowiki>->monthly()</nowiki>
|-
|-
|<code>;('‎->monthlyOn(4, ‘15:00</code>
|تنفيذ المهمة اليوم 4 الساعة 15:00 من كل شهر
|تنفيذ المهمة اليوم 4 الساعة 15:00 من كل شهر
|<nowiki>->monthlyOn(4, ‘15:00’)</nowiki>
|-
|-
| <code>;()‎->quarterly</code>
|تنفيذ المهمة كل رباعية
|تنفيذ المهمة كل رباعية
|<nowiki>->quarterly()</nowiki>
|-
|-
| <code>;()‎->yearly</code>
|تنفيذ المهمة سنويا
|تنفيذ المهمة سنويا
|<nowiki>->yearly()</nowiki>
|-
|-
|<code>;('‎->timezone(‘America/New_York</code>
|اختيار المنطقة الزمنية
|اختيار المنطقة الزمنية
|<nowiki>->timezone(‘America/New_York’)</nowiki>
|}
|}
يمكن دمج هذه التوابع مع ضوابط إضافية لإنشاء جداول زمنية مضبوطة بدقّة تُنفّذ في أيام محدّدة كل أسبوع. على سبيل المثال، لضبط أمر لينفَّذ يوم الاثنين من كل أسبوع:
يمكن دمج هذه التوابع مع ضوابط إضافية لإنشاء جداول زمنية مضبوطة بدقّة تُنفّذ في أيام محدّدة كل أسبوع. على سبيل المثال، لضبط أمر لينفَّذ يوم الاثنين من كل أسبوع:<syntaxhighlight lang="php">
 
// التنفيذ يوم الاثنين الساعة 1
// التنفيذ يوم الاثنين الساعة 1


$schedule->call(function () {
$schedule->call(function () {
  //
  //


سطر 174: سطر 161:


         ->weekdays()
         ->weekdays()
         ->hourly()
         ->hourly()
         ->timezone('America/Chicago')
         ->timezone('America/Chicago')
         ->between('8:00', '17:00');


         ->between('8:00', '17:00');


في ما يلي بعض القيود الإضافية:
</syntaxhighlight>في ما يلي بعض القيود الإضافية:
{| class="wikitable"
{| class="wikitable"
|التعريف
!التابع
|التابع
!التعريف
|-
|-
|<code>;()‎->weekdays</code>
|حدّ المهمة في أيام الأسبوع
|حدّ المهمة في أيام الأسبوع
|<nowiki>->weekdays()</nowiki>
|-
|-
|<code>;()‎->sundays</code>
|حدّ المهمة في أيام الأحد
|حدّ المهمة في أيام الأحد
|<nowiki>->sundays()</nowiki>
|-
|-
|<code>;()‎->mondays</code>
|حدّ المهمة في أيام الاثنين
|حدّ المهمة في أيام الاثنين
|<nowiki>->mondays()</nowiki>
|-
|-
|<code>;()‎->tuesdays</code>
|حدّ المهمة في أيام الثلاثاء
|حدّ المهمة في أيام الثلاثاء
|<nowiki>->tuesdays()</nowiki>
|-
|-
|<code>;()‎->wednesday</code>
|حدّ المهمة في أيام الإربعاء
|حدّ المهمة في أيام الإربعاء
|<nowiki>->wednesday()</nowiki>
|-
|-
|<blockquote><code>;()‎->thursdays</code></blockquote>
|حدّ المهمة في أيام الخميس
|حدّ المهمة في أيام الخميس
|<nowiki>->thursdays()</nowiki>
|-
|-
|<code>;()‎->fridays</code>
|حدّ المهمة في أيام الجمعة
|حدّ المهمة في أيام الجمعة
|<nowiki>->fridays()</nowiki>
|-
|-
|<code>;()‎->saturdays</code>
|حدّ المهمة في أيام السبت
|حدّ المهمة في أيام السبت
|<nowiki>->saturdays()</nowiki>
|-
|-
|<code>;(between($start, $end-<</code>
|حدّ المهمة بين تاريخ بداية ونهاية
|حدّ المهمة بين تاريخ بداية ونهاية
|between($start, $end)
|-
|-
|<code>;(‎->when(Closure</code>
|حدّ المهمة باختبارات الصّحة
|حدّ المهمة باختبارات الصّحة
|<nowiki>->when(Closure)</nowiki>
|}
|}


==== القيد الزمني Between ====
==== القيد الزمني <code>Between</code> ====
يمكن استعمال التابع between لضبط تنفيذ مهمة حسب وقت معين من اليوم:
يمكن استعمال التابع <code>between</code> لضبط تنفيذ مهمة حسب وقت معين من اليوم:<syntaxhighlight lang="php">
 
$schedule->command('reminders:send')
$schedule->command('reminders:send')


                   ->hourly()
                   ->hourly()
                   ->between('7:00', '22:00');
                   ->between('7:00', '22:00');


بنفس الطريقة، يُستعمل التابع unlessbetween لمنع تنفيذ مهمة في وقت معين من اليوم:


</syntaxhighlight>بنفس الطريقة، يُستعمل التابع <code>unlessbetween</code> لمنع تنفيذ مهمة في وقت معين من اليوم:<syntaxhighlight lang="php">
$schedule->command('reminders:send')
$schedule->command('reminders:send')


                   ->hourly()
                   ->hourly()
                   ->unlessBetween('23:00', '4:00');


                   ->unlessBetween('23:00', '4:00');
</syntaxhighlight>


==== قيود اختبارات الصّحة ====
==== قيود اختبارات الصّحة ====
يُستعمل التابع when لضبط تنفيذ مهمة بنتيجة اختبار صحّة. أي إن أعاد النطاق المغلق Closure القيمة true، تُنفّذ المهمة المبرمَجة ما لم تكن هناك ضوابط أخرى تمنع التنفيذ:
يُستعمل التابع <code>when</code> لضبط تنفيذ مهمة بنتيجة اختبار صحّة. أي إن أعاد النطاق المغلق Closure القيمة <code>true</code>، تُنفّذ المهمة المبرمَجة ما لم تكن هناك ضوابط أخرى تمنع التنفيذ:<syntaxhighlight lang="php">
 
$schedule->command('emails:send')->daily()->when(function () {
$schedule->command('emails:send')->daily()->when(function () {
   return true;
   return true;


});
});


يمكن اعتبار التابع skip عكس when. إن أعاد التابع skip النتيجة true لا تُنفّذ المهمة:


</syntaxhighlight>يمكن اعتبار التابع <code>skip</code> عكس <code>when</code>. إن أعاد التابع <code>skip</code> النتيجة <code>true</code> لا تُنفّذ المهمة:<syntaxhighlight lang="php">
$schedule->command('emails:send')->daily()->skip(function () {
$schedule->command('emails:send')->daily()->skip(function () {


سطر 251: سطر 234:
});
});


عند استعمال توابع when متسلسلة، تُنفّذ المهمة في حال أعادت جميعا القيمة true.
 
</syntaxhighlight>
 
عند استعمال توابع <code>when</code> متسلسلة، تُنفّذ المهمة في حال أعادت جميعا القيمة <code>true</code>.


=== المناطق الزمنية ===
=== المناطق الزمنية ===
باستعمال التابع timezone، يمكنك تحديد أن المهمة المجدولة تنفَّذ بوقت المنطقة الزمنية المحددة:
باستعمال التابع <code>timezone</code>، يمكنك تحديد أن المهمة المجدولة تنفَّذ بوقت المنطقة الزمنية المحددة:<syntaxhighlight lang="php">
 
$schedule->command('report:generate')
$schedule->command('report:generate')
        ->timezone('America/New_York')
        ->timezone('America/New_York')
        ->at('02:00')


        ->at('02:00')


تنبيه: تذكر أنّ المناطق الزمنية تستعمل التوقيت الصيفي. عند حدوث تغيير للتوقيت الصيفي، قد تُنفّذ المهام المجدولة مرتين أو لا تُنفّذ إطلاقًا. لهذا يُنصح بعدم استخدام الجدولة باعتماد المناطق الزمنية إن أمكن.
</syntaxhighlight>تنبيه: تذكر أنّ المناطق الزمنية تستعمل التوقيت الصيفي. عند حدوث تغيير للتوقيت الصيفي، قد تُنفّذ المهام المجدولة مرتين أو لا تُنفّذ إطلاقًا. لهذا يُنصح بعدم استخدام الجدولة باعتماد المناطق الزمنية إن أمكن.


=== منع تداخل المهام ===
=== منع تداخل المهام ===
في العادة، ستُنفّذ المهام المجدولة حتى إن لم يكتمل تنفيذ نسخة السابقة من المهمّة. لإيقاف هذا السلوك، يمكن استعمال التابع withoutOverlapping:
في العادة، ستُنفّذ المهام المجدولة حتى إن لم يكتمل تنفيذ نسخة السابقة من المهمّة. لإيقاف هذا السلوك، يمكن استعمال التابع <code>withoutOverlapping</code>:<syntaxhighlight lang="php">
 
$schedule->command('emails:send')->withoutOverlapping();
$schedule->command('emails:send')->withoutOverlapping();
</syntaxhighlight>


في هذا المثال، سيُنفّذ الأمر emails:send كل دقيقة إن لم يكن يٌنفّذ في ذلك الحين. يكون التابع withoutOverlapping مفيدًا خاصة إذا كان لديك مهام تختلف مدّة تنفيذها جذريًّا من نسخة لأخرى ممّا يمنعك من تحديد مدة التنفيذ بدقّة.
في هذا المثال، سيُنفّذ الأمر <code>emails:send</code> كل دقيقة إن لم يكن يٌنفّذ في ذلك الحين. يكون التابع <code>withoutOverlapping</code> مفيدًا خاصة إذا كان لديك مهام تختلف مدّة تنفيذها جذريًّا من نسخة لأخرى ممّا يمنعك من تحديد مدة التنفيذ بدقّة.
 
يمكنك تحديد عدد الدقائق التي يجب أن تنقضي قبل إلغاء القفل "without overlapping". افتراضيًّا، يلغى القفل بعد 24 ساعة:


يمكنك تحديد عدد الدقائق التي يجب أن تنقضي قبل إلغاء القفل "without overlapping". افتراضيًّا، يلغى القفل بعد 24 ساعة:<syntaxhighlight lang="php">
$schedule->command('emails:send')->withoutOverlapping();
$schedule->command('emails:send')->withoutOverlapping();
</syntaxhighlight>


=== تنفيذ المهام على نفس الخادم ===
=== تنفيذ المهام على نفس الخادم ===
سطر 280: سطر 264:
إن كان التطبيق يعمل على عدّة خوادم، يمكنك حدّ تنفيذ مهمة على خادم معيّن. على سبيل المثال، إن كان لديك مهمة تنتج تقريرا كل ليلة جمعة، إن كان منفّذ المهام يعمل على ثلاث خوادم، سينفّذ المهمة ثلاث مرّات و ينتج ثلاث تقارير.
إن كان التطبيق يعمل على عدّة خوادم، يمكنك حدّ تنفيذ مهمة على خادم معيّن. على سبيل المثال، إن كان لديك مهمة تنتج تقريرا كل ليلة جمعة، إن كان منفّذ المهام يعمل على ثلاث خوادم، سينفّذ المهمة ثلاث مرّات و ينتج ثلاث تقارير.


للإشارة إلى أنّ المهمة يجب أن تنفّذ على خادم واحد، استعمل التابع onOneServer عند جدولة المهمة. سينشأ الخادم الأول الذي سيحصل على المهمة قفلًا ذريًّا لمنع بقية الخوادم من تنفيذ المهمة في نفس الوقت:
للإشارة إلى أنّ المهمة يجب أن تنفّذ على خادم واحد، استعمل التابع <code>onOneServer</code> عند جدولة المهمة. سينشأ الخادم الأول الذي سيحصل على المهمة قفلًا ذريًّا لمنع بقية الخوادم من تنفيذ المهمة في نفس الوقت:<syntaxhighlight lang="php">
 
$schedule->command('report:generate')
$schedule->command('report:generate')


               ->fridays()
               ->fridays()
               ->at('17:00')
               ->onOneServer();


               ->at('17:00')


               ->onOneServer();
</syntaxhighlight>


=== وضع الصيانة ===
=== وضع الصيانة ===
لن تعمل جدولة المهام في Laravel إن كان التطبيق في وضع الصيانة حيث لا نريد أن تتعامل المهام مع أي جزء غير مكتمل تحت الصيانة. لكن إن أردت فرض تنفيذ مهمة ما رغم وضع الصيانة، استعمل التابع evenIfMaintenanceMode:
لن تعمل جدولة المهام في [[Laravel]] إن كان التطبيق في وضع الصيانة حيث لا نريد أن تتعامل المهام مع أي جزء غير مكتمل تحت الصيانة. لكن إن أردت فرض تنفيذ مهمة ما رغم وضع الصيانة، استعمل التابع <code>evenIfMaintenanceMode</code>:<syntaxhighlight lang="php">
 
$schedule->command('emails:send')->evenInMaintenanceMode();
$schedule->command('emails:send')->evenInMaintenanceMode();
</syntaxhighlight>


== مخرجات المهام ==
== مخرجات المهام ==
يوفّر منظم المهام في Laravel طرقا سهلة للعمل مع المُخرجات الناتجة عن المهام المجدولة. أولًا، باستعمال التابع sendOutputTo، يمكنك إرسال المخرجات لملف محدد لفحصها لاحقًا:
يوفّر منظم المهام في [[Laravel]] طرقا سهلة للعمل مع المُخرجات الناتجة عن المهام المجدولة. أولًا، باستعمال التابع <code>sendOutputTo</code>، يمكنك إرسال المخرجات لملف محدد لفحصها لاحقًا:<syntaxhighlight lang="php">
 
$schedule->command('emails:send')
$schedule->command('emails:send')


        ->daily()
        ->daily()
        ->sendOutputTo($filePath);
        ->sendOutputTo($filePath);


إذا أردت إضافة المخرجات لملف موجود، استعمل التابع appendOutputTo


</syntaxhighlight>إذا أردت إضافة المخرجات لملف موجود، استعمل التابع <code>appendOutputTo</code>:<syntaxhighlight lang="php">
$schedule->command('emails:send')
$schedule->command('emails:send')


        ->daily()
        ->daily()
        ->appendOutputTo($filePath);
        ->appendOutputTo($filePath);


باستعمال التابع emailOutputTo يمكنك إرسال المخرجات ببريد إلكتروني لعنوان من اختيارك. قبل إرسال البريد، يجب ضبط خدمة إرسال البريد في Laravel:


</syntaxhighlight>باستعمال التابع <code>emailOutputTo</code> يمكنك إرسال المخرجات ببريد إلكتروني لعنوان من اختيارك. قبل إرسال البريد، يجب ضبط خدمة إرسال البريد في [[Laravel]]:<syntaxhighlight lang="php">
$schedule->command('foo')
$schedule->command('foo')


        ->daily()
        ->daily()
        ->sendOutputTo($filePath)
        ->sendOutputTo($filePath)
        ->emailOutputTo('[]');


        ->emailOutputTo('[[mailto:foo@example.com|foo@example.com]]');


تنبيه: التوابع emailOutputTo و endOutputTo و appendOutputTo خاصة فقط بالتابعين exec و command.
</syntaxhighlight>تنبيه: التوابع <code>emailOutputTo</code> و <code>endOutputTo</code> و <code>appendOutputTo</code> خاصة فقط بالتابعين <code>exec</code> و <code>command</code>.
 
= خطّافو المهام Task Hooks =
باستعمال التابعين before و after، يمكنك تحديد شيفرة تنفّذ قبل أو بعد انتهاء المهمة المجدولة:


= خطاطيف المهام Task Hooks =
باستعمال التابعين <code>before</code> و <code>after</code>، يمكنك تحديد شيفرة تنفّذ قبل أو بعد انتهاء المهمة المجدولة:<syntaxhighlight lang="php">
$schedule->command('emails:send')
$schedule->command('emails:send')


        ->daily()
        ->daily()
        ->before(function () {
        ->before(function () {
           // قبل بداية المهمة...
           // قبل بداية المهمة...


سطر 338: سطر 315:


        ->after(function () {
        ->after(function () {
           // بعد المهمة ..
           // بعد المهمة ..


        });
        });


==== استعلام عناوين URL ====
 
باستعمال التابعين pingBefore و thenPing، بإمكان منظم المهام اختبار الاتصال بعنوان URL معين قبل أو بعد تنفيذ مهمة مجدولة. هذه التوابع مفيدة في حال أردت إعلام خدمات خارجية مثل Laravel Envoyer بأن مهمة ما ستبدأ أو انتهت:<syntaxhighlight lang="php">
</syntaxhighlight>
 
=== استعلام عناوين URL ===
باستعمال التابعين <code>pingBefore</code> و <code>thenPing</code>، بإمكان منظم المهام اختبار الاتصال بعنوان URL معين قبل أو بعد تنفيذ مهمة مجدولة. هذه التوابع مفيدة في حال أردت إعلام خدمات خارجية مثل Laravel Envoyer بأن مهمة ما ستبدأ أو انتهت:<syntaxhighlight lang="php">
$schedule->command('emails:send')
$schedule->command('emails:send')


سطر 352: سطر 331:




</syntaxhighlight>استعمال pingBefore أو thenPing يتطلب أولًا المكتبة Guzzle HTTP. يمكنك تثبيت Guzzle للتطبيق باستعمال منظم الحزمات Composer:<syntaxhighlight lang="php">
</syntaxhighlight>استعمال <code>pingBefore</code> أو <code>thenPing</code> يتطلب أولًا المكتبة Guzzle HTTP. يمكنك تثبيت Guzzle للتطبيق باستعمال منظم الحزمات Composer:<syntaxhighlight lang="php">
composer require guzzlehttp/guzzle
composer require guzzlehttp/guzzle
</syntaxhighlight>
</syntaxhighlight>

المراجعة الحالية بتاريخ 14:12، 24 أكتوبر 2018

مقدمة

ربّما ولّدت في الماضي نقطة دخول Cron لكل مهمة أردت جدولتها في الخادم. لكن يمكن أن يصبح هذا متعبًا بسرعة لأن الجدولة أصبحت خارج تحكم المصدر وأصبح عليك أن تدخل ب SSH للخادم لإضافة نقاط دخول Cron.

يسمح مجدول الأوامر في Laravel بتعريف جدول المهام داخل Laravel بطريقة سلسلة وواضحة. عند استخدام جدولة المهام، تحتاج لنقطة دخول Cron واحدة على الخادم. يُعرّف جدول المهام في التابع schedule من الملف app/Console/Kernel.php. لمساعدتك على البداية، يوجد مثال بسيط معرّف في التابع.

بدء مجدول المهام

عند استعمال مُجدول المهام، تحتاج فقط لتعريف نقطة دخول Cron على الخادم. إن كنت لا تعرف كيفية العمل ب Cron، يمكنك استعمال خدمات مثل Laravel Forge التي ستغير نقطة دخول Cron:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

سينادي هذا الأمر مجدول المهام كل دقيقة. عند تنفيذ الأمر schedule:run، سيقيّم Laravel المهام المجدولة وينفّذ المهام التي حان وقتها.

تعريف جدول المهام

يمكنك تعريف كل المهام المجدولة في التابع schedule من الصنف App/Console/Kernel. للبدء، لنلق نظرة على المثال المذكور في التابع. في هذا المثال، سنجدول نطاقًا مغلقًا Closure ليُنفَّذ في كل يوم عند منتصف الليل. في النطاق المغلق Closure، سنُنفِّذ استعلامًا لقاعدة البيانات لتفريغ جدول:

<?php

namespace App\Console;

use DB;

<?php
namespace App\Console;

use DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{

   /**
    *الأوامر التي يوفرها التطبيق
    *
    * @var array
    */

   protected $commands = [

      //
   ];

   /**
    * تعريف جدول المهام.
    *
    * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
    * @return void
    */

   protected function schedule(Schedule $schedule)
   {
       $schedule->call(function () {
           DB::table('recent_users')->delete();

       })->daily();
   }
}

بالإضافة لجدولة استعمال Closure، يمكنك استعمال كائنات قابلة للاستدعاء. الكائنات القابلة للاستدعاء هي أصناف PHP بسيطة تحتوي التابع invoke_:

$schedule->call(new DeleteRecentUsers)->daily();

جدولة أوامر artisan

بالإضافة لجدولة نداءات النطاق المغلق Closure، يمكنك جدولة أوامر Artisan و أوامر نظام التشغيل. على سبيل المثال، يمكنك استعمال التابع command لجدولة أمر Artisan بذكر إمّا اسمه وإمّا صنفه:

$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();

جدولة الوظائف في الطوابير

يُستعمل التابع job لجدولة الوظائف في الطوابير. توفّر هذه الطريقة جدولة سهلة دون استخدام التابع call وإنشاء نطاق مغلق Closure لإضافة المهام للطابور يدويًّا:

$schedule->job(new Heartbeat)->everyFiveMinutes();
//إضافة المهمة لقائمة انتظار
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();

جدولة أوامر Shell

يُستعمل الأمر exec لجدولة أوامر نظام التشغيل :

$schedule->exec('node /home/forge/script.js')->daily();

جدولة خيارات التواتر Frequency options

بالطبع توجد أكثر من جدولة يمكن تعيينها للمهمة:

التابع التعريف
;('* * * * *')‎->cron تنفيذ جدول cron مخصص
;()‎->everyMinute تنفيذ المهمة كل دقيقة
;()‎->everyFiveMinutes تنفيذ المهمة كل خمس دقائق
;()‎->everyTenMinutes تنفيذ المهمة كل عشر دقائق
;()‎->everyFifteenMinutes تنفيذ المهمة كل خمس عشرة دقيقة
;()‎->everyThirtyMinutes تنفيذ المهمة كل نصف ساعة
;()‎->hourly تنفيذ المهمة كل ساعة
;(‎->(hourlyAt(17 تنفيذ المهمة في الدقيقة 17 من كل ساعة
;()‎‎->daily تنفيذ المهمة كل يوم منتصف الليل
;('‎->dailyAt(‘13:00 تنفيذ المهمة كل يوم الساعة 13:00
;(‎->twiceDaily(1, 13 تنفيذ المهمة يوميا على الساعة 1 و 13:00
;()‎->weekly تنفيذ المهمة أسبوعيا
;('‎->weeklyOn(1, ‘8:00 تنفبذ المهمة أسبوعيا يوم الاثنين الساعة 8:00
;()‎->monthly تنفيذ المهمة كل شهر
;('‎->monthlyOn(4, ‘15:00 تنفيذ المهمة اليوم 4 الساعة 15:00 من كل شهر
;()‎->quarterly تنفيذ المهمة كل رباعية
;()‎->yearly تنفيذ المهمة سنويا
;('‎->timezone(‘America/New_York اختيار المنطقة الزمنية

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

// التنفيذ يوم الاثنين الساعة 1

$schedule->call(function () {
  //

})->weekly()->mondays()->at('13:00');

// التنفيذ كل ساعة من 8 إلى 17 كل أيام الأسبوع

$schedule->command('foo')

         ->weekdays()
         ->hourly()
         ->timezone('America/Chicago')
         ->between('8:00', '17:00');

في ما يلي بعض القيود الإضافية:

التابع التعريف
;()‎->weekdays حدّ المهمة في أيام الأسبوع
;()‎->sundays حدّ المهمة في أيام الأحد
;()‎->mondays حدّ المهمة في أيام الاثنين
;()‎->tuesdays حدّ المهمة في أيام الثلاثاء
;()‎->wednesday حدّ المهمة في أيام الإربعاء

;()‎->thursdays

حدّ المهمة في أيام الخميس
;()‎->fridays حدّ المهمة في أيام الجمعة
;()‎->saturdays حدّ المهمة في أيام السبت
;(between($start, $end-< حدّ المهمة بين تاريخ بداية ونهاية
;(‎->when(Closure حدّ المهمة باختبارات الصّحة

القيد الزمني Between

يمكن استعمال التابع between لضبط تنفيذ مهمة حسب وقت معين من اليوم:

$schedule->command('reminders:send')

                   ->hourly()
                   ->between('7:00', '22:00');

بنفس الطريقة، يُستعمل التابع unlessbetween لمنع تنفيذ مهمة في وقت معين من اليوم:

$schedule->command('reminders:send')

                   ->hourly()
                   ->unlessBetween('23:00', '4:00');

قيود اختبارات الصّحة

يُستعمل التابع when لضبط تنفيذ مهمة بنتيجة اختبار صحّة. أي إن أعاد النطاق المغلق Closure القيمة true، تُنفّذ المهمة المبرمَجة ما لم تكن هناك ضوابط أخرى تمنع التنفيذ:

$schedule->command('emails:send')->daily()->when(function () {
   return true;

});

يمكن اعتبار التابع skip عكس when. إن أعاد التابع skip النتيجة true لا تُنفّذ المهمة:

$schedule->command('emails:send')->daily()->skip(function () {

   return true;

});

عند استعمال توابع when متسلسلة، تُنفّذ المهمة في حال أعادت جميعا القيمة true.

المناطق الزمنية

باستعمال التابع timezone، يمكنك تحديد أن المهمة المجدولة تنفَّذ بوقت المنطقة الزمنية المحددة:

$schedule->command('report:generate')
        ->timezone('America/New_York')
        ->at('02:00')

تنبيه: تذكر أنّ المناطق الزمنية تستعمل التوقيت الصيفي. عند حدوث تغيير للتوقيت الصيفي، قد تُنفّذ المهام المجدولة مرتين أو لا تُنفّذ إطلاقًا. لهذا يُنصح بعدم استخدام الجدولة باعتماد المناطق الزمنية إن أمكن.

منع تداخل المهام

في العادة، ستُنفّذ المهام المجدولة حتى إن لم يكتمل تنفيذ نسخة السابقة من المهمّة. لإيقاف هذا السلوك، يمكن استعمال التابع withoutOverlapping:

$schedule->command('emails:send')->withoutOverlapping();

في هذا المثال، سيُنفّذ الأمر emails:send كل دقيقة إن لم يكن يٌنفّذ في ذلك الحين. يكون التابع withoutOverlapping مفيدًا خاصة إذا كان لديك مهام تختلف مدّة تنفيذها جذريًّا من نسخة لأخرى ممّا يمنعك من تحديد مدة التنفيذ بدقّة.

يمكنك تحديد عدد الدقائق التي يجب أن تنقضي قبل إلغاء القفل "without overlapping". افتراضيًّا، يلغى القفل بعد 24 ساعة:

$schedule->command('emails:send')->withoutOverlapping();

تنفيذ المهام على نفس الخادم

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

إن كان التطبيق يعمل على عدّة خوادم، يمكنك حدّ تنفيذ مهمة على خادم معيّن. على سبيل المثال، إن كان لديك مهمة تنتج تقريرا كل ليلة جمعة، إن كان منفّذ المهام يعمل على ثلاث خوادم، سينفّذ المهمة ثلاث مرّات و ينتج ثلاث تقارير.

للإشارة إلى أنّ المهمة يجب أن تنفّذ على خادم واحد، استعمل التابع onOneServer عند جدولة المهمة. سينشأ الخادم الأول الذي سيحصل على المهمة قفلًا ذريًّا لمنع بقية الخوادم من تنفيذ المهمة في نفس الوقت:

$schedule->command('report:generate')

               ->fridays()
               ->at('17:00')
               ->onOneServer();

وضع الصيانة

لن تعمل جدولة المهام في Laravel إن كان التطبيق في وضع الصيانة حيث لا نريد أن تتعامل المهام مع أي جزء غير مكتمل تحت الصيانة. لكن إن أردت فرض تنفيذ مهمة ما رغم وضع الصيانة، استعمل التابع evenIfMaintenanceMode:

$schedule->command('emails:send')->evenInMaintenanceMode();

مخرجات المهام

يوفّر منظم المهام في Laravel طرقا سهلة للعمل مع المُخرجات الناتجة عن المهام المجدولة. أولًا، باستعمال التابع sendOutputTo، يمكنك إرسال المخرجات لملف محدد لفحصها لاحقًا:

$schedule->command('emails:send')

        ->daily()
        ->sendOutputTo($filePath);

إذا أردت إضافة المخرجات لملف موجود، استعمل التابع appendOutputTo:

$schedule->command('emails:send')

        ->daily()
        ->appendOutputTo($filePath);

باستعمال التابع emailOutputTo يمكنك إرسال المخرجات ببريد إلكتروني لعنوان من اختيارك. قبل إرسال البريد، يجب ضبط خدمة إرسال البريد في Laravel:

$schedule->command('foo')

        ->daily()
        ->sendOutputTo($filePath)
        ->emailOutputTo('[]');

تنبيه: التوابع emailOutputTo و endOutputTo و appendOutputTo خاصة فقط بالتابعين exec و command.

خطاطيف المهام Task Hooks

باستعمال التابعين before و after، يمكنك تحديد شيفرة تنفّذ قبل أو بعد انتهاء المهمة المجدولة:

$schedule->command('emails:send')

        ->daily()
        ->before(function () {
           // قبل بداية المهمة...

        })

        ->after(function () {
           // بعد المهمة ..

        });

استعلام عناوين URL

باستعمال التابعين pingBefore و thenPing، بإمكان منظم المهام اختبار الاتصال بعنوان URL معين قبل أو بعد تنفيذ مهمة مجدولة. هذه التوابع مفيدة في حال أردت إعلام خدمات خارجية مثل Laravel Envoyer بأن مهمة ما ستبدأ أو انتهت:

$schedule->command('emails:send')

        ->daily()
        ->pingBefore($url)
        ->thenPing($url);

استعمال pingBefore أو thenPing يتطلب أولًا المكتبة Guzzle HTTP. يمكنك تثبيت Guzzle للتطبيق باستعمال منظم الحزمات Composer:

composer require guzzlehttp/guzzle

مصادر