Проверьте, существует ли предыдущий результат с Python-RQ

Я использую Python-RQ для создания вакансии, когда вы создаете вакансию, вы получаете job.id:

f311ae30-b623-4b38-9dcb-0edd0133a6e6

Затем я использую этот идентификатор, чтобы проверить, закончен ли результат, и это здорово.

Затем этот результат кэшируется в течение (500 секунд).

Теперь вот где я запутался.

Когда в течение этого 500-секундного таймфрейма поступает другой запрос с тем же набором входов:

{'blah': u'123456', 'title': u' Some Title', 'variable': 123}

Как мне вернуть кешированный результат этой работы против создания другой работы.

Моя проблема заключается в том, что job.id - это какой-то хеш, включая временные метки и тому подобное, поэтому я не уверен, как посмотреть результат в redis.

Я искал везде, но нигде не видел этого документированного, чтобы найти лучший способ использовать кэшированные результаты без создания новой работы.

1 ответ

Решение

Я придумал решение, которое могло бы быть полезным для других.

По сути, создайте дайджест входных данных (для работника RQ), чтобы у нас было что посмотреть, когда поступит другой идентичный запрос, это будет имя хеша. Ключом будет "job_key", а значением будет job.id, который нам нужен.

Когда поступит другой запрос, идентичный ранее обработанному, у нас теперь будет возможность найти и предоставить результаты, не выполняя ту же работу снова.

Кроме того, в качестве отказоустойчивого устройства добавлено несколько дополнительных секунд к заданию, поэтому, когда кэшированный job.result запрашивается другой функцией, он все еще будет там и не будет удален сборщиком мусора между вызовами.

* Запрос, если у кого-то есть понимание, есть ли лучший способ обработки хеша -> job.id (ключ, значение) по потреблению памяти, аналогично этому и этому, пожалуйста, дайте мне знать. (Эти две ссылки относятся к тому, как вы можете использовать наименьшую память, используя хеш против обычной строки для хранения ключа / значения определенным образом, используя некоторый алгоритм, чтобы иметь 100 ключей / значений на хеш).

На хорошие вещи:

# Seconds before cached records expire
cache_expire = 500

# Create hash of parameters, to use as a lookup for job.id (cache)
hash = hashlib.sha1()
for param in search:
    hash.update(str(search[param]))
url_hash = 'url:{0}'.format(hash.hexdigest())

# Check if we have a cached result, need old job_key
job_key = r.hget(url_hash, 'job_key')
if job_key:
    job_hash = 'rq:job:{0}'.format(job_key)
    ttl = r.ttl(job_hash)
    if ttl:
        # Add 30 more seconds of buffer room
        # to ensure job.result doesn't get deleted pre-maturely
        r.expire(job_hash, ttl+30)
        return jsonify(search_id=job_key)
    else:
        # Job result has already been deleted, clear lookup hash
        r.delete(url_hash)

# Create new job
job = q.enqueue_call(func=worker.search, args=(search,), result_ttl=cache_expire)
# Create job.id lookup using hash as key (for cache)
if r.hsetnx(url_hash, 'job_key', job.id):
    r.expire(url_hash, cache_expire)

return jsonify(search_id=job.id)
Другие вопросы по тегам