Perbedaan antara Konsumen / Produsen dan Pengamat / Dapat Diamati

15

Saya sedang mengerjakan desain aplikasi yang terdiri dari tiga bagian:

  • satu utas yang mengawasi peristiwa tertentu yang terjadi (pembuatan file, permintaan eksternal, dll.)
  • N utas pekerja yang merespons peristiwa ini dengan memprosesnya (setiap pekerja memproses dan mengonsumsi satu peristiwa tunggal dan pemrosesan dapat memakan waktu variabel)
  • pengontrol yang mengelola utas tersebut dan melakukan penanganan kesalahan (memulai ulang utas, mencatat hasil)

Meskipun ini cukup mendasar dan tidak sulit untuk diterapkan, saya bertanya-tanya apa yang akan menjadi cara yang "benar" untuk melakukannya (dalam kasus konkret di Jawa, tetapi jawaban abstraksi yang lebih tinggi juga dihargai). Ada dua strategi yang muncul:

  • Pengamat / Dapat Diamati: Utas menonton diamati oleh pengontrol. Jika terjadi peristiwa, pengontrol kemudian diberitahu dan dapat menetapkan tugas baru ke utas gratis dari kumpulan utas cache yang dapat digunakan kembali (atau tunggu dan simpan tugas-tugas dalam antrian FIFO jika semua utas sedang sibuk). Pekerja thread menerapkan Callable dan kembali dengan sukses dengan hasil (atau nilai boolean), atau kembali dengan kesalahan, dalam hal ini pengontrol dapat memutuskan apa yang harus (tergantung pada sifat kesalahan yang telah terjadi).

  • Produser / Konsumen : Utas menonton membagikan BlockingQueue dengan controller (event-queue) dan controller membagikan dua dengan semua pekerja (task-queue dan result-queue). Dalam hal suatu peristiwa, utas menonton menempatkan objek tugas dalam antrian acara. Pengontrol mengambil tugas baru dari antrian acara, meninjaunya dan menempatkannya dalam antrian tugas. Setiap pekerja menunggu tugas baru dan mengambil / mengkonsumsinya dari antrian tugas (pertama datang pertama dilayani, dikelola oleh antrian itu sendiri), menempatkan hasil atau kesalahan kembali ke dalam antrian hasil. Akhirnya, pengontrol dapat mengambil hasil dari antrian hasil dan mengambil langkah-langkah sesuai jika terjadi kesalahan.

Hasil akhir dari kedua pendekatan serupa, tetapi masing-masing memiliki sedikit perbedaan:

Dengan Pengamat, kontrol utas bersifat langsung dan setiap tugas dikaitkan dengan pekerja yang baru melahirkan spesifik. Overhead untuk membuat utas mungkin lebih tinggi, tetapi tidak banyak berkat kumpulan utas yang di-cache. Di sisi lain, pola Observer direduksi menjadi Observer tunggal dan bukan multipel, yang sebenarnya tidak sesuai dengan tujuannya.

Strategi antrian tampaknya lebih mudah diperluas, misalnya menambahkan banyak produsen alih-alih satu secara langsung dan tidak memerlukan perubahan apa pun. Kelemahannya adalah bahwa semua utas akan berjalan tanpa batas, bahkan ketika tidak melakukan pekerjaan sama sekali, dan penanganan kesalahan / hasil tidak terlihat seanggun dalam solusi pertama.

Apa yang akan menjadi pendekatan paling pas dalam situasi ini dan mengapa? Saya merasa sulit untuk menemukan jawaban untuk pertanyaan ini secara online, karena sebagian besar contoh hanya berurusan dengan kasus yang jelas, seperti memperbarui banyak jendela dengan nilai baru dalam kasus Observer atau pemrosesan dengan banyak konsumen dan produsen. Masukan apa pun sangat dihargai.

pengguna183536
sumber

Jawaban:

10

Anda cukup dekat untuk menjawab pertanyaan Anda sendiri. :)

Dalam pola Observable / Observer (perhatikan flip), ada tiga hal yang perlu diingat:

  1. Secara umum, pemberitahuan perubahan, yaitu 'payload', dapat diamati.
  2. Yang bisa diamati ada .
  3. Pengamat harus diketahui oleh yang ada diamati (atau mereka tidak memiliki apa pun untuk diamati).

Dengan menggabungkan poin-poin ini, apa yang tersirat adalah bahwa yang dapat diamati mengetahui apa komponen hilirnya, yaitu para pengamat. Aliran data secara inheren didorong dari yang dapat diamati - pengamat hanya 'hidup dan mati' dengan apa yang mereka amati.

Dalam pola Produser / Konsumen, Anda mendapatkan interaksi yang sangat berbeda:

  1. Secara umum, payload ada secara independen dari produsen yang bertanggung jawab untuk memproduksinya.
  2. Produsen tidak tahu bagaimana atau kapan konsumen aktif.
  3. Konsumen tidak perlu tahu produsen muatannya.

Aliran data sekarang benar-benar terputus antara produsen dan konsumen - semua produsen tahu adalah bahwa ia memiliki output, dan semua konsumen tahu adalah bahwa ia memiliki input. Yang penting, ini berarti bahwa produsen dan konsumen dapat hidup sepenuhnya tanpa kehadiran yang lain.

Perbedaan tidak terlalu halus lain adalah bahwa beberapa pengamat pada yang sama diamati biasanya mendapatkan payload yang sama (kecuali ada implementasi yang tidak konvensional), sedangkan beberapa konsumen dari yang sama produser mungkin tidak. Ini tergantung jika perantara adalah pendekatan antrian atau seperti topik. Yang pertama melewati pesan yang berbeda untuk masing-masing konsumen, sementara yang kedua memastikan (atau berupaya untuk) bahwa semua konsumen memproses berdasarkan per pesan.

Untuk menyesuaikannya dengan aplikasi Anda:

  • Dalam pola Observable / Observer, setiap kali utas menonton Anda menginisialisasi, ia harus tahu cara memberi tahu pengontrol. Sebagai pengamat, pengontrol kemungkinan menunggu pemberitahuan dari utas menonton sebelum memungkinkan utas menangani perubahan.
  • Dalam pola Produser / Konsumen, utas tontonan Anda hanya perlu mengetahui keberadaan antrian acara, dan berinteraksi hanya dengan itu. Sebagai konsumen, pengontrol kemudian memilih antrian acara, dan begitu mendapat muatan baru, ia membiarkan utas menanganinya.

Oleh karena itu, untuk menjawab pertanyaan Anda secara langsung: jika Anda ingin mempertahankan beberapa tingkat pemisahan antara utas tontonan Anda dan pengontrol Anda sehingga Anda dapat mengoperasikannya secara independen, Anda harus cenderung ke arah pola Produser / Konsumen.

hjk
sumber
2
Terima kasih atas jawaban terinci Anda. Sayangnya saya tidak dapat menghapusnya karena reputasi yang hilang, jadi saya menandainya sebagai solusi. Kemandirian temporal antara kedua bagian yang Anda sebutkan adalah sesuatu yang positif yang belum saya pikirkan sampai sekarang. Antrian dapat mengelola ledakan singkat dari banyak acara dengan jeda panjang di antara jauh lebih baik daripada tindakan langsung setelah peristiwa diamati (jika jumlah utas maksimum ditetapkan dan relatif rendah). Jumlah utas juga dapat ditingkatkan / dikurangi secara dinamis tergantung pada jumlah item antrian saat ini.
user183536
@ user183536 Tidak ada masalah, senang bisa membantu! :)
hjk