Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Bagaimana cara mengembalikan flask render_template setelah pekerjaan latar belakang Redis selesai?

Solusi dasar tetapi bisa diterapkan (inti):

Anda dapat melakukan ini hanya dengan mengarahkan ulang dari rute yang mengantrekan pekerjaan, lalu minta meta tag menyegarkan halaman itu secara berkala. Pertama-tama impor pustaka yang diperlukan:

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

Siapkan koneksi terkait rq, dan tentukan fungsi yang akan dijalankan:

r = Redis(host='redisserver')
q = Queue(connection=r)

def slow_func(data):
    sleep(5)
    return 'Processed %s' % (data,)

Kemudian tentukan template yang dapat menyegarkan halaman setiap 5 detik:

template_str='''<html>
    <head>
      {% if refresh %}
        <meta http-equiv="refresh" content="5">
      {% endif %}
    </head>
    <body>{{result}}</body>
    </html>'''

Kami juga akan membuat fungsi pembantu untuk mengembalikan template itu dengan variabel yang dimasukkan, menggunakan labu render_template_string . Perhatikan bahwa penyegaran default ke False, jika tidak disertakan:

def get_template(data, refresh=False):
    return render_template_string(template_str, result=data, refresh=refresh)

Sekarang buat rute yang akan mengantrekan fungsi kita, dapatkan rq job-id-nya, lalu kembalikan redirect ke result lihat dengan id itu . Ini hanya membutuhkan input dalam string URL, tetapi bisa mendapatkannya dari mana saja:

@app.route('/process/<string:data>')
def process(data):
    job = q.enqueue(slow_func, data)
    return redirect(url_for('result', id=job.id))

Sekarang mari kita tangani hasil sebenarnya, dengan bantuan rq.Job obyek. Logika di sini dapat diubah, karena ini akan menyebabkan penyegaran halaman pada semua nilai kecuali "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)

Jika statusnya "finished" lalu job.result akan berisi nilai kembalian slow_func , jadi kami merender ini di halaman.

Metode ini memiliki kelemahan menyebabkan beberapa permintaan ke server, sambil menunggu penyelesaian pekerjaan. Tag penyegaran meta mungkin agak tidak konvensional. Jika Anda mengirim permintaan pembaruan dari Javascript, maka ada solusi yang dapat mengirim permintaan AJAX pada suatu interval, meskipun ini mengalami masalah beberapa permintaan yang sama.

Alternatifnya adalah menggunakan soket web, atau SSE untuk mengalirkan hasil pekerjaan yang telah diselesaikan ke frontend segera setelah selesai.

PERBARUI:27 Feb 2021

Saya memutuskan untuk mencoba metode SSE memperbarui frontend dengan status pekerjaan. Saya mengetahui bahwa rq memiliki dukungan asli untuk memperbarui meta atribut dalam pekerjaan, dengan mengimpor rq.get_current_job di dalam pekerjaan, yang kemudian dapat diakses secara eksternal setelah pembaruan pekerjaan.

Lihat kode demonstrasi untuk:

Contoh dasar dengan bilah kemajuan (inti):




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Basis data noSQL mana yang terbaik untuk penyisipan/penulisan volume tinggi?

  2. bagaimana cara mendapatkan kunci yang tidak cocok dengan pola tertentu di redis?

  3. Redis:Amazon EC2 vs Elasticache

  4. Bagaimana cara menyalurkan di node.js ke redis?

  5. Bisakah saya membuat dua kolom unik satu sama lain? atau gunakan kunci utama komposit di redis?