2011-09-06 12 views
6

क्या यह संभवतः रेक कार्य को निष्पादित करने के लिए संभव है यदि यह पहले से नहीं चल रहा है, मैं कुछ रेक कार्यों को निष्पादित करने के लिए क्रॉन का उपयोग करना चाहता हूं लेकिन पिछले कॉल समाप्त होने पर रेक कार्य शुरू नहीं होना चाहिए धन्यवादरेक की जांच पहले से चल रही है

उत्तर

12

मैं lockrun का उपयोग कई बार चलने से क्रॉन कार्य को रोकने के लिए (यह केवल काम करता है जब एक ही lockrun मंगलाचरण के माध्यम से आदेश लागू, इसलिए यदि आप विभिन्न मंगलाचरण रास्तों से बचाने के लिए की जरूरत है, तो आप अन्य तरीकों के लिए देखने के लिए की आवश्यकता होगी)।

अपने crontab में, आप इसे इस तरह आह्वान:

*/5 * * * * /usr/local/bin/lockrun --lockfile=/tmp/this_task.lockrun -- cd /my/path && RAILS_ENV=production bundle exec rake this:task 
+1

उत्तर के लिए धन्यवाद कभी भी लॉक्रून – Fivell

+2

के बारे में कभी नहीं सुना है कुछ प्रणालियों पर झुंड (अक्सर/usr/bin/झुंड में) भी है - प्रश्न ने ओएस निर्दिष्ट नहीं किया है। –

+0

झुंड के साथ समस्या यह है कि आप एक से अधिक तर्क के साथ कमांड नहीं चला सकते हैं, इसलिए 'रेक कार्य_नाम' दो तर्क हैं और इसलिए विफल रहता है। – yekta

5

इसका सामान्य गैर-रेक विशिष्ट समाधान लॉक के रूप में एक पिड फ़ाइल का उपयोग करना है। आप रेक कार्य को उस स्क्रिप्ट में लपेटेंगे जो इस फ़ाइल को रेक बनाता है, जब इसे रेक खत्म हो जाता है, तो इसे हटा देता है, और शुरुआत से पहले इसके लिए जांच करता है।

सुनिश्चित नहीं है कि रेक में कुछ बनाया गया है, मुझे कुछ भी पता नहीं है।

+0

मैंने php के साथ ऐसी चीजें की और 1 बार प्रति माह लॉक फ़ाइल को किसी भी तरह से हटाया नहीं गया था ... इसलिए मुझे लगता है कि यह 100% प्रतिशत समाधान नहीं है – Fivell

+1

यदि आप फ़ाइल में पीआईडी ​​डालते हैं, और यह देखने के लिए जांचें कि यह चल रहा है (फ़ाइल के अस्तित्व के बजाय), तो आप लॉक को और अधिक विश्वसनीय रूप से हटा सकते हैं। – spike

+0

अच्छा विचार! धन्यवाद – Fivell

2

यदि आप बस इस रेक कार्य को छोड़ना चाहते हैं, तो आप कार्य प्रगति के बारे में जानकारी संग्रहीत करने के लिए डेटाबेस का उपयोग भी कर सकते हैं (उदाहरण के लिए जब आप किसी दिए गए कार्य को शुरू करते हैं और पूरा करते हैं तो फ़ील्ड अपडेट करें) और प्रत्येक कार्य को चलाने से पहले उस जानकारी को जांचें।

हालांकि, यदि आप कतार जैसी व्यवहार चाहते हैं, तो आप कार्यों को संभालने के लिए एक डिमन बनाने पर विचार करना चाहेंगे। प्रक्रिया बहुत सरल है और आपको बहुत अधिक नियंत्रण देता है। इसके बारे में बहुत अच्छा रेलवेकास्ट है: Custom Daemon

डिमन दृष्टिकोण रेल कार्य को प्रत्येक कार्य पर फिर से लोड होने से रोक देगा। यह विशेष रूप से उपयोगी होता है यदि आपके रेक कार्य अक्सर होते हैं।

6

इसके अलावा, आप एक lockfile उपयोग कर सकते हैं, लेकिन कार्य में इसे संभाल:

def lockfile 
    # Assuming you're running Rails 
    Rails.root.join('tmp', 'pids', 'leads_task.lock') 
end 

def running! 
    `touch #{lockfile}` 
end 

def done! 
    `rm #{lockfile}` 
end 

def running? 
    File.exists?(lockfile) 
end 

task :long_running do 
    unless running? 
    running! 
    # long running stuff 
    done! 
    end 
end 

यह शायद कुछ में निकाला जा सकता मॉड्यूल की तरह, लेकिन आपको विचार मिलता है।

1

रेल रेक कार्यों के लिए फ़ाइल लॉक के साथ मेरा संस्करण यहां है।

अपने रेक कार्य फ़ाइल में इस रखो (नेमस्पेस के अंतर्गत, तो यह अभ्यस्त अन्य रेक कार्यों के साथ ओवरलैप):

def cron_lock(name) 
    path = Rails.root.join('tmp', 'cron', "#{name}.lock") 
    mkdir_p path.dirname unless path.dirname.directory? 
    file = path.open('w') 
    return if file.flock(File::LOCK_EX | File::LOCK_NB) == false 
    yield 
end 

उपयोग:

cron_lock 'namespace_task_name' do 
    # your code 
end 

पूर्ण उदाहरण:

namespace :service do 
    def cron_lock(name) 
    path = Rails.root.join('tmp', 'cron', "#{name}.lock") 
    mkdir_p path.dirname unless path.dirname.directory? 
    file = path.open('w') 
    return if file.flock(File::LOCK_EX | File::LOCK_NB) == false 
    yield 
    end 

    desc 'description' 
    task cleaning: :environment do 
    cron_lock 'service_cleaning' do 
     # your code 
    end 
    end 
end 
संबंधित मुद्दे

 संबंधित मुद्दे