मैं एलिक्सिर या फीनिक्स फ्रेमवर्क में हर कुछ घंटों में कोड को कैसे शेड्यूल कर सकता हूं?


194

तो चलिए बताते हैं कि मैं ईमेल का एक गुच्छा भेजना चाहता हूं या साइटमैप या हर 4 घंटे में फिर से बनाना चाहता हूं, मैं फीनिक्स में या एलिक्जिर के साथ कैसे करूंगा?

जवाबों:


387

एक सरल विकल्प है जिसे किसी बाहरी निर्भरता की आवश्यकता नहीं है:

defmodule MyApp.Periodically do
  use GenServer

  def start_link do
    GenServer.start_link(__MODULE__, %{})
  end

  def init(state) do
    schedule_work() # Schedule work to be performed at some point
    {:ok, state}
  end

  def handle_info(:work, state) do
    # Do the work you desire here
    schedule_work() # Reschedule once more
    {:noreply, state}
  end

  defp schedule_work() do
    Process.send_after(self(), :work, 2 * 60 * 60 * 1000) # In 2 hours
  end
end

अब आपकी देखरेख में पेड़:

worker(MyApp.Periodically, [])

168
इस भाषा से प्यार करना असंभव नहीं है :)
NoDisplayName

3
मुझे यह फ़ाइल कहाँ रखनी चाहिए? फीनिक्स परियोजना के लिब / डायरेक्टरी के तहत? परीक्षण / समय-समय पर / परीक्षण करने के लिए कहाँ जाते हैं?
यूगज़ोल

9
क्योंकि यह एक लंबी चलने वाली प्रक्रिया है। आप परीक्षण को जो कुछ भी समझ में आता है, हो सकता है "परीक्षण / my_app / periodically_test.exs"।
जोस वालिम

2
किसी विशेष कारण के लिए Process.send_afterअपने स्वयं के कार्य में नहीं जाने के लिए ताकि फ़ंक्शन दोनों से initऔर कहा जा सके handle_info?
रयान बिग जी

24
@ कोडीपोल :timer.send_intervalठीक है लेकिन ध्यान रखें कि अंतराल स्थिर रहेगा। तो कल्पना कीजिए कि आप हर मिनट में कुछ करना चाहते हैं और भविष्य में, कार्य में एक मिनट से अधिक समय लगता है। ऐसे मामलों में, आप हर समय काम कर रहे होंगे और आपकी संदेश कतार बिना रुके बढ़ती जाएगी। उपरोक्त समाधान हमेशा काम पूरा होने के बाद दी गई अवधि का इंतजार करेगा ।
जोस वैलिम

33

क्वांटम आपको रनटाइम पर नौकरियां बनाने, खोजने और हटाने की सुविधा देता है।

इसके अलावा, आप एक cronjob बनाते समय कार्य फ़ंक्शन के लिए तर्क पास कर सकते हैं, और यहां तक ​​कि अगर आप UTC से खुश नहीं हैं तो टाइमज़ोन को भी संशोधित कर सकते हैं।

यदि आपका ऐप कई अलग-थलग उदाहरणों (जैसे हरोकू) के रूप में चल रहा है, तो PostgreSQL या Redis द्वारा समर्थित जॉब प्रोसेसर हैं, जो कार्य निर्धारण का भी समर्थन करते हैं:

ओबन: https://github.com/sorentwo/oban

Exq: https://github.com/akira/exq

टोनिक: https://github.com/joakimk/toniq

Verk: https://github.com/edgurgel/verk


1
मुझे लगता है कि यह बहुत सारे सरल कार्यों के लिए एक ओवरकिल होगा, जिनके लिए इसकी आवश्यकता नहीं है लेकिन फिर भी उत्तर के लिए धन्यवाद।
NoDisplayName 22

उपलब्ध पुस्तकालयों की सूची होना मेरे लिए मददगार था।
शेल्डनक्रेगर

24

आप उसके लिए एर्लक्रॉन का उपयोग कर सकते हैं । आप इसका उपयोग करें

job = {{:weekly, :thu, {2, :am}},
  {:io, :fwrite, ["It's 2 Thursday morning~n"]}}

:erlcron.cron(job)

A jobएक 2-तत्व टपल है। पहला तत्व एक टपल है जो नौकरी के लिए अनुसूची का प्रतिनिधित्व करता है और दूसरा तत्व फ़ंक्शन या एक एमएफए (मॉड्यूल, फ़ंक्शन, एरीटी) है। उपर्युक्त उदाहरण में, हम :io.fwrite("It's 2 Thursday morning")प्रत्येक गुरुवार को प्रातः 2 बजे भागते हैं ।

उम्मीद है की वो मदद करदे!


हाँ, यह कुछ भी नहीं से बेहतर है, धन्यवाद। मैं कुछ समय के लिए अनुत्तरित प्रश्न छोड़ दूंगा, शायद अन्य सुझाव होंगे
NoDisplayName

4
आपका स्वागत है! वहाँ भी है github.com/c-rack/quantum-elixir जो एक अमृत काम है, अगर आप पसंद करते हैं
Gjaldon

6

मैंने क्वांटम लाइब्रेरी क्वांटम- एलिक्सिर का इस्तेमाल किया ।
निर्देशों का पालन करें।

#your_app/mix.exs
defp deps do
  [{:quantum, ">= 1.9.1"},  
  #rest code
end



#your_app/mix.exs
def application do
  [mod: {AppName, []},
   applications: [:quantum,
   #rest code         
 ]]
end

#your_app/config/dev.exs
config :quantum, :your_app, cron: [
  # Every minute
  "* * * * *": fn -> IO.puts("Hello QUANTUM!") end
]

सब तैयार। नीचे कमांड चलाकर सर्वर शुरू करें।

iex -S mix phoenix.server 


1

मुझे :timer.send_interval/2थन के साथ उपयोग करने के लिए थोड़ा अधिक एर्गोनोमिक लगता GenServerहै Process.send_after/4( स्वीकृत उत्तर में प्रयुक्त )।

हर बार जब आप इसे संभालते हैं तो अपनी अधिसूचना को पुनर्निर्धारित करने के बजाय, :timer.send_interval/2एक अंतराल सेट करते हैं, जिस पर आपको एक संदेश प्राप्त होता है - schedule_work()स्वीकृत उत्तर उपयोगों की तरह कॉल करने की आवश्यकता नहीं है ।

defmodule CountingServer do
  use GenServer

  def init(_) do
    :timer.send_interval(1000, :update)
    {:ok, 1}
  end

  def handle_info(:update, count) do
    IO.puts(count)
    {:noreply, count + 1}
  end
end

प्रत्येक 1000 एमएस (यानी, एक बार एक सेकंड), IntervalServer.handle_info/2को बुलाया जाएगा, वर्तमान प्रिंट करें count, और जेनरवर की स्थिति को अपडेट करें ( count + 1), आपको जैसे आउटपुट देते हैं:

1
2
3
4
[etc.]


0

क्वांटम महान है, हम इसे फ़ीनिक्स फ्रंट-एंड के साथ क्रोन प्रतिस्थापन के रूप में काम में उपयोग करते हैं और हम वास्तविक समय में भी नौकरियां जोड़ते हैं जो बहुत साफ - सुथरा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.