एक बुनियादी लेकिन व्यावहारिक समाधान (सारांश):
आप इसे केवल उस मार्ग से पुनर्निर्देशित करके कर सकते हैं जो नौकरी को जोड़ता है, फिर उस पृष्ठ को समय-समय पर मेटा टैग रीफ्रेश करें। पहले आवश्यक पुस्तकालयों को आयात करें:
from flask import Flask, redirect, url_for, render_template_string
app = Flask(__name__)
from time import sleep
from rq import Queue
from rq.job import Job
from redis import Redis
rq संबंधित कनेक्शन सेट करें, और चलाने के लिए फ़ंक्शन को परिभाषित करें:
r = Redis(host='redisserver')
q = Queue(connection=r)
def slow_func(data):
sleep(5)
return 'Processed %s' % (data,)
फिर एक टेम्प्लेट परिभाषित करें जो हर 5 सेकंड में पेज को रिफ्रेश कर सके:
template_str='''<html>
<head>
{% if refresh %}
<meta http-equiv="refresh" content="5">
{% endif %}
</head>
<body>{{result}}</body>
</html>'''
हम फ्लास्क render_template_string
का उपयोग करके उस टेम्पलेट को सम्मिलित किए गए चर के साथ वापस करने के लिए एक सहायक कार्य भी करेंगे। . ध्यान दें कि यदि आपूर्ति नहीं की गई है, तो डिफ़ॉल्ट को गलत पर रीफ्रेश करें:
def get_template(data, refresh=False):
return render_template_string(template_str, result=data, refresh=refresh)
अब एक रूट बनाएं जो हमारे फंक्शन को एनक्यू करेगा, उसका rq जॉब-आईडी प्राप्त करें, फिर result
पर रीडायरेक्ट लौटाएं उस id
. के साथ देखें . यह सिर्फ URL स्ट्रिंग में इनपुट लेता है, लेकिन इसे कहीं से भी प्राप्त कर सकता है:
@app.route('/process/<string:data>')
def process(data):
job = q.enqueue(slow_func, data)
return redirect(url_for('result', id=job.id))
अब rq.Job
. की सहायता से वास्तविक परिणाम को देखते हैं वस्तु। यहां तर्क को बदला जा सकता है, क्योंकि इससे "finished"
को छोड़कर सभी मानों पर एक पृष्ठ ताज़ा हो जाएगा :
@app.route('/result/<string:id>')
def result(id):
job = Job.fetch(id, connection=r)
status = job.get_status()
if status in ['queued', 'started', 'deferred', 'failed']:
return get_template(status, refresh=True)
elif status == 'finished':
result = job.result
# If this is a string, we can simply return it:
return get_template(result)
अगर स्थिति "finished"
. है फिर job.result
इसमें slow_func
. का रिटर्न वैल्यू होगा , इसलिए हम इसे पृष्ठ पर प्रस्तुत करते हैं।
काम पूरा होने की प्रतीक्षा करते हुए, इस पद्धति में सर्वर के लिए कई अनुरोध करने का नुकसान है। मेटा रीफ्रेश टैग थोड़ा अपरंपरागत हो सकता है। यदि आप जावास्क्रिप्ट से अपडेट के लिए अनुरोध भेज रहे हैं, तो ऐसे समाधान हैं जो एक अंतराल पर AJAX अनुरोध भेज सकते हैं, हालांकि यह एक ही एकाधिक अनुरोध समस्या से ग्रस्त है।
विकल्प यह है कि वेबसाकेट, या एसएसई का उपयोग पूर्ण किए गए कार्य के परिणाम को पूरा होते ही फ़्रंटएंड पर स्ट्रीम करने के लिए किया जाए।
अपडेट करें:27 फरवरी 2021
मैंने नौकरी की स्थिति के साथ फ्रंटएंड को अपडेट करने की एसएसई पद्धति पर जाने का फैसला किया। मैंने सीखा है कि rq
meta
. को अपडेट करने के लिए मूल समर्थन है rq.get_current_job
. आयात करके नौकरी के भीतर विशेषता जॉब के अंदर, जिसे जॉब रिफ्रेश के बाद बाहरी रूप से एक्सेस किया जा सकता है।
इसके लिए प्रदर्शन कोड देखें:
प्रगति पट्टी के साथ एक बुनियादी उदाहरण (जिस्ट):