Требовать справки Структурирование параллельных HTTP-запросов - PullRequest
0 голосов
/ 07 февраля 2012

Вот мой случай. У меня есть три таблицы 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 Ответ

3 голосов
/ 07 февраля 2012

Вы можете использовать пакет запросов , который обеспечивает обработку квазипараллельных запросов на основе gevent зеленых потоков .requests позволяет создавать несколько объектов запроса, которые затем выполняются «параллельно».См. этот пример .

Зеленые потоки на самом деле не работают параллельно, но совместно обеспечивают контроль выполнения.gevent может исправлять функции ввода / вывода стандартной библиотеки (например, те, которые используются urllib2), чтобы выдавать управление всякий раз, когда они блокируют ввод / вывод в противном случае.Пакет request объединяет его в один вызов функции, который принимает несколько запросов и возвращает несколько объектов ответа.Это не намного легче, чем это.

...