Pertanyaan keamanan thread untuk koleksi Python di Scrapy Item Pipelines (menggunakan Twisted untuk konkurensi)

Scrapy memiliki gagasan tentang Item Pipelines yang secara bersamaan memproses (melalui Twisted) item yang dikembalikan dari Laba-laba. Contoh kode berikut disediakan untuk memfilter item duplikat (kode disalin di bawah). Bagaimana caranya agar set dapat digunakan dengan aman melalui panggilan bersamaan ke process_item? Tampaknya Scrapy memanggil saluran item di sini .

from scrapy.exceptions import DropItem

class DuplicatesPipeline:

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['id'])
            return item

person Jessica    schedule 29.05.2020    source sumber


Jawaban (1)


Twisted dan Scrapy sebagian besar berulir tunggal. Alih-alih multi-threading preemptif, mereka menyediakan konkurensi melalui multi-tasking kooperatif. Dalam sistem multitasking kooperatif, tidak ada preemption. Artinya fungsi seperti process_item di atas sangat aman dengan asumsi self.ids_seen tidak akan berubah antara baris pertama dan kedua hingga terakhir. Hanya metode process_item ini yang berjalan. Tidak ada pekerjaan lain yang dapat terjadi sampai process_item secara kooperatif menyerahkan kendali. Hal ini dilakukan dengan memunculkan pengecualian atau mengembalikan nilai. Ketika ini terjadi, kontrol kembali ke pemanggilnya (atau apa pun pengendali except terdekatnya). Kode itu kemudian dijalankan hingga memutuskan untuk melepaskan kendali, dan seterusnya. Akhirnya kendali dikembalikan ke Twisted reactor yang memilih kejadian lain untuk dilayani dengan memanggil beberapa metode aplikasi. Kemudian prosesnya berulang.

person Jean-Paul Calderone    schedule 29.05.2020