I have a long task that goes off into a python-rq worker queue.
@cache.cached(timeout=2592000)
@app.route('/as/<keyword>', methods=['GET'])
@db_session
def auto_suggest(keyword):
job = q.enqueue(find_keyword, keyword)
while not job:
time.sleep(1)
return jsonify(word=job)
I'm using flask-cache
to try and save the result as its a calculation that only needs to be run once a week at most, once a month is sufficient as well.
The problem I am having is when this runs, it caches the failed response, and not the actual solution.
Any other way to do this? Or suggestion in how I should approach this?
You are trying to JSON-encode the Job
proxy object, not the result of the job. You do want to check for the job result here:
job = q.enqueue(find_keyword, keyword)
while not job.result:
time.sleep(1)
return jsonify(word=job.result)
This should be cached just fine.
You could instead memoize the result of the find_keyword
function, using the Cache.memoize()
decorator:
@cache.memoize(30 * 24 * 60 * 60)
def find_keyword(keyword):
# ....
This will cache the results of the find_keyword()
function for a month, based entirely on the keyword
argument (results for different keywords are cached independently).
One more note: when applying extra decorators to a view function, make sure you put the @app.route()
decorator at the top (to be applied last). Any decorator applied 'later' is ignored as it is not their output that is being registered as the view:
@app.route('/as/<keyword>', methods=['GET'])
@cache.cached(timeout=2592000)
@db_session
def auto_suggest(keyword):
job = q.enqueue(find_keyword, keyword)
while not job.result:
time.sleep(1)
return jsonify(word=job.result)