Требовать справки Структурирование параллельных HTTP-запросов
Вот мой случай. У меня три стола Book
, Publisher
а также Price
, У меня есть команда управления, которая зацикливается на каждой книге, и для каждой книги она запрашивает издателя, чтобы получить цену, которую он затем сохраняет в таблице цен. Это очень простой HTTP GET или UDP запрос, который я делаю, чтобы узнать цену. Вот как выглядит скелет моего кода:
@transaction.commit_on_success
def handle(self, *args, **options):
for book in Book.objects.all():
for publisher book.publisher_set.objects.all():
price = check_the_price(publisher.url, book.isbn)
Price.objects.create(book=book, publisher=publisher, price=price)
Код прост, но он становится очень медленным и отнимает много времени, когда у меня 10000 книг. Я мог бы легко ускорить это, делая параллельные запросы HTTP. Я мог бы сделать 50 параллельных запросов, это было бы сделано в один миг, но я не знаю, как структурировать этот код.
Мой сайт сам по себе очень маленький и легкий, и я стараюсь держаться подальше от RabbitMQ/Celery. Я просто чувствую, что сейчас это важно.
Любые рекомендации о том, как это сделать при сохранении целостности транзакций?
Редактировать #1: Это используется как аналогия с тем, что я на самом деле делаю. При написании этой аналогии я забыл упомянуть, что мне также нужно сделать несколько UDP-запросов.
1 ответ
Вы можете использовать пакет запросов, который обеспечивает квазипараллельную обработку запросов на основе зеленых потоков gevent. requests
позволяет вам создать несколько объектов запроса, которые затем выполняются "параллельно". Смотрите этот пример.
Зеленые потоки на самом деле не работают параллельно, но совместно обеспечивают контроль выполнения. gevent
может исправлять функции ввода / вывода стандартной библиотеки (например, те, которые используются urllib2), чтобы выдавать управление всякий раз, когда они блокируют ввод / вывод в противном случае. request
Пакет упаковывает это в один вызов функции, который принимает несколько запросов и возвращает несколько объектов ответа. Это не намного легче, чем это.