كرون السيناريو بمثابة طابور أو طابور كرون ؟

StackOverflow https://stackoverflow.com/questions/226473

  •  03-07-2019
  •  | 
  •  

سؤال

أنا أراهن أن شخصا ما قد حل بالفعل هذا و ربما أنا الخطأ باستخدام مصطلحات البحث جوجل أن تقول لي الجواب, ولكن هنا هو بلدي الوضع.

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

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

ما أفكر به هو جعل السيناريو أن يتحقق myhappyschedule كل 5 دقائق و يجمع تلك التي من المقرر أن يضع لهم في طابور حيث نصي آخر يمكن تنفيذ كل 'وظيفة' أو التواجد في قائمة الانتظار في النظام.والتي كل هذا يبدو فوضوي.

لجعل هذا يعد - أود أن أقول أن أنا مما يسمح للمستخدمين جدولة الأمور في myhappyschedule وليس تحرير crontab.

ما الذي يمكن عمله حيال ذلك ؟ الملف أقفال النصوص الدعوة النصية ؟

هل كانت مفيدة؟

المحلول

إضافة عمود exec_status إلى myhappytable (ربما أيضا time_started و time_finished, انظر شبة الكود)

تشغيل التالية كرون النصي كل x دقيقة

شبة الكود من كرون النصي:

[create/check pid lock (optional, but see "A potential pitfall" below)]
get number of rows from myhappytable where (exec_status == executing_now)
if it is > 0, exit
begin loop
  get one row from myhappytable
    where (exec_status == not_yet_run) and (scheduled_time <= now)
    order by scheduled_time asc
  if no such row, exit
  set row exec_status to executing_now (maybe set time_started to now)
  execute whatever command the row contains
  set row exec_status to completed
  (maybe also store the command output/return as well, set time_finished to now)
end loop
[delete pid lock file (complementary to the starting pid lock check)]

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

إمكانية شرك: إذا كرون النصي قتل مهمة مجدولة سيبقى في "executing_now" الدولة.هذا ما pid قفل في بداية ونهاية هو:لمعرفة ما إذا كان كرون إنهاء البرنامج النصي بشكل صحيح.شبة الكود من إنشاء/تحقق pidlock:

if exists pidlockfile then
  check if process id given in file exists
  if not exists then
    update myhappytable set exec_status = error_cronscript_died_while_executing_this   
      where exec_status == executing_now
    delete pidlockfile
  else (previous instance still running)
    exit
  endif
endif
create pidlockfile containing cron script process id

نصائح أخرى

ويمكنك استخدام في (1) القيادة داخل السيناريو الخاص بك لتحديد موعد شوطه المقبل. قبل خروجها، يمكن أن تحقق myhappyschedule لوقت التشغيل القادم. لا تحتاج كرون في كل شيء، حقا.

جئت عبر هذا السؤال حين البحث عن حل لهذه المشكلة الطابور.لصالح أي شخص آخر البحث هنا هو الحل.

الجمع بين هذا مع كرون الذي يبدأ وظائف كما من المقرر (حتى لو كانوا من المقرر أن يتم تشغيلها في نفس الوقت) و هذا يحل المشكلة التي وصفها كذلك.

المشكلة


  • في أكثر من مثيل واحد من البرنامج النصي يجب أن تكون قيد التشغيل.
  • نحن نريد أن جديلة تصل الطلبات إلى عملية في أسرع وقت ممكن.

ie.نحن بحاجة إلى أنابيب إلى البرنامج النصي.

الحل:


إنشاء خط أنابيب إلى أي برنامج نصي.يتم ذلك باستخدام صغيرة باش النصي (أسفل).

السيناريو يمكن أن يسمى
./pipeline "<any command and arguments go here>"

على سبيل المثال:

./pipeline sleep 10 &
./pipeline shabugabu &
./pipeline single_instance_script some arguments &
./pipeline single_instance_script some other_argumnts &
./pipeline "single_instance_script some yet_other_arguments > output.txt" &
..etc

السيناريو يخلق جديد المسمى من أجل كل أمر.لذا أعلاه سيتم إنشاء أنابيب الاتصال المسماة: sleep, shabugabu, ، single_instance_script

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

هذا السيناريو سوف كتلة الطالبة العمليات لذلك يطلق عليه كخلفية وظيفة (& في النهاية) أو منفصل العملية مع at (at now <<< "./pipeline some_script")

#!/bin/bash -Eue

# Using command name as the pipeline name
pipeline=$(basename $(expr "$1" : '\(^[^[:space:]]*\)')).pipe
is_reader=false

function _pipeline_cleanup {
        if $is_reader; then
                rm -f $pipeline
        fi
        rm -f $pipeline.lock

        exit
}
trap _pipeline_cleanup INT TERM EXIT

# Dispatch/initialization section, critical
lockfile $pipeline.lock
        if [[ -p $pipeline ]]
        then
                echo "$*" > $pipeline
                exit
        fi

        is_reader=true
        mkfifo $pipeline
        echo "$*" > $pipeline &
rm -f $pipeline.lock

# Reader section
while read command < $pipeline
do
        echo "$(date) - Executing $command"
        ($command) &> /dev/null
done
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top