Tüketici / Üretici ile Gözlemci / Gözlemlenebilir Arasındaki Fark


16

Üç bölümden oluşan bir uygulamanın tasarımı üzerinde çalışıyorum:

  • belirli olayları izleyen tek bir iş parçacığı (dosya oluşturma, dış istekler vb.)
  • Bu olaylara işleyerek yanıt veren N çalışan iş parçacığı (her çalışan tek bir olayı işler ve tüketir ve işleme değişken zaman alabilir)
  • bu iş parçacıklarını yöneten ve hata işleme (denetleyicilerin yeniden başlatılması, sonuçların kaydedilmesi) yapan bir denetleyici

Bu oldukça basit ve uygulanması zor olmasa da, bunu yapmanın "doğru" yolunun ne olacağını merak ediyorum (Java'daki bu somut durumda, ancak daha yüksek soyutlama cevapları da takdir edilmektedir). İki strateji akla geliyor:

  • Gözlemci / Gözlemlenebilir: İzleyen iplik denetleyici tarafından izlenir. Bir olay olması durumunda, denetleyici bilgilendirilir ve yeni görevi yeniden kullanılabilir önbelleğe alınmış bir iş parçacığı havuzundan ücretsiz bir iş parçacığına atayabilir (veya tüm iş parçacıkları şu anda meşgulse FIFO kuyruğundaki görevleri bekleyebilir ve önbelleğe alabilir). Çalışan iş parçacıkları Callable uygular ve sonuçla (veya bir boole değeriyle) başarılı bir şekilde döndürür veya bir hata ile geri döner; bu durumda denetleyici ne yapılacağına karar verebilir (meydana gelen hatanın niteliğine bağlı olarak).

  • Yapımcı / Tüketici : İzleme iş parçacığı bir BlockingQueue'yu denetleyiciyle (olay kuyruğu) paylaşır ve denetleyici ikisini tüm çalışanlarla (görev kuyruğu ve sonuç kuyruğu) paylaşır. Bir olay olması durumunda, izleme dizisi olay kuyruğuna bir görev nesnesi koyar. Denetleyici olay kuyruğundan yeni görevler alır, bunları inceler ve görev kuyruğuna koyar. Her işçi yeni görevleri bekler ve bunları görev kuyruğundan alır / tüketir (önce önce servis yapılır, kuyruğun kendisi tarafından yönetilir), sonuçları veya hataları sonuç kuyruğuna geri koyar. Son olarak, kontrolör sonuçları sonuç kuyruğundan alabilir ve hata durumunda uygun adımları atabilir.

Her iki yaklaşımın da sonuçları benzerdir, ancak her birinin küçük farklılıkları vardır:

Gözlemciler ile, iş parçacıklarının kontrolü doğrudandır ve her görev belirli bir yeni doğmuş işçiye atfedilir. İş parçacığı oluşturmak için ek yük daha yüksek olabilir, ancak önbelleğe alınmış iş parçacığı havuzu sayesinde çok fazla değil. Öte yandan, Gözlemci modeli, tam olarak ne için tasarlandığı değil, çoklu yerine tek bir Gözlemciye indirgenir.

Kuyruk stratejisinin genişletilmesi daha kolay görünüyor, örneğin bir yerine birden çok üretici eklemek basittir ve herhangi bir değişiklik gerektirmez. Dezavantajı, herhangi bir iş yapmasa bile tüm iş parçacıklarının süresiz olarak çalışması ve hata / sonuç işlemenin ilk çözümdeki kadar zarif görünmemesidir.

Bu durumda en uygun yaklaşım ne olabilir ve neden? Bu sorunun cevabını çevrimiçi olarak bulmakta zorlandım, çünkü çoğu örnek yalnızca çok sayıda pencereyi Gözlemci durumunda yeni bir değerle güncellemek veya birden fazla tüketici ve üretici ile işlem yapmak gibi açık vakalarla ilgilidir. Herhangi bir girdi büyük beğeni topluyor.

Yanıtlar:


10

Kendi sorunuzu cevaplamaya oldukça yakınsınız. :)

Gözlemlenebilir / Gözlemci modelinde (kapağı not edin) akılda tutulması gereken üç şey vardır:

  1. Genel olarak, değişikliğin bildirimi, yani 'faydalı yük' gözlemlenebilir niteliktedir.
  2. Gözlenebilir var .
  3. Gözlemciler mevcut gözlemlenebilir tarafından bilinmelidir (veya gözlemleyecek hiçbir şeyleri yoktur).

Bu noktaları birleştirerek ima edilen, gözlemlenebilir olanın, aşağı akım bileşenlerinin ne olduğunu, yani gözlemcilerin ne olduğunu bilmesidir. Veri akışı doğası gereği gözlemlenebilir - yönlendiricilerden sadece gözlemledikleri şeyle “yaşar ve ölür”.

Üretici / Tüketici modelinde çok farklı bir etkileşim elde edersiniz:

  1. Genel olarak, yük taşıma kapasitesinden sorumlu üreticiden bağımsız olarak bulunur.
  2. Üreticiler nasıl ve ne zaman aktif olduklarını bilmiyorlar .
  3. Tüketicilerin faydalı yükün üreticisini bilmesi gerekmez.

Veri akışı artık bir üretici ile bir tüketici arasında tamamen kopmuştur - üreticinin bildiği tek şey onun bir çıktısı olduğudur ve tüm tüketicinin bir girdisi olduğunu bilir. Önemli olarak, bu, üreticilerin ve tüketicilerin tamamen diğerinin varlığı olmadan var olabileceği anlamına gelir.

Bu kadar ince olmayan bir başka fark, aynı gözlemlenebilirdeki birden fazla gözlemcinin genellikle aynı yükü almasıdır (geleneksel olmayan bir uygulama olmadığı sürece), aynı üreticiden birden fazla tüketici bunu yapamayabilir. Bu, aracının sıraya veya konuya benzer bir yaklaşım olup olmadığına bağlıdır. Birincisi her tüketici için farklı bir mesaj iletir, ikincisi ise tüm tüketicilerin mesaj başına işlemesini sağlar (veya dener).

Bunları uygulamanıza sığdırmak için:

  • Gözlemlenebilir / Gözlemci deseninde, izleme diziniz her başlatıldığında, denetleyiciyi nasıl bilgilendireceğini bilmelidir. Gözlemci olarak denetleyici, iş parçacıklarının değişikliği gerçekleştirmesine izin vermeden önce izleme iş parçacığından bir bildirim bekler.
  • Yapımcı / Tüketici modelinde, izleme dizinizin yalnızca olay sırasının varlığını bilmesi gerekir ve yalnızca bununla etkileşime girer. Tüketici olarak, denetleyici daha sonra olay kuyruğunu yoklar ve yeni bir yük yüklediğinde, iş parçacıklarının işleyebilmesini sağlar.

Bu nedenle, sorunuzu doğrudan cevaplamak için: İzleme ipliğiniz ile kontrol cihazınız arasında bağımsız olarak çalıştırabilecek şekilde bir miktar ayrım yapmak istiyorsanız, Üretici / Tüketici modeline yönelmeniz gerekir.


2
Ayrıntılı cevabınız için teşekkür ederim. Ne yazık ki, eksik itibarı nedeniyle onu değerlendiremiyorum, bu yüzden bunun yerine bir çözüm olarak işaretledim. Bahsettiğiniz her iki bölüm arasındaki zamansal bağımsızlık, şimdiye kadar düşünmediğim olumlu bir şey. Kuyruklar, olaylar gözlemlendikten sonra doğrudan eylemden çok daha iyi arasında uzun duraklamaları olan birçok olayın kısa patlamalarını yönetebilir (maksimum iplik sayısı sabit ve nispeten düşükse). İş parçacığı sayısı, geçerli kuyruk öğesi sayılarına bağlı olarak dinamik olarak artırılabilir / azaltılabilir.
user183536

@ user183536 Sorun değil, yardımcı olmaktan mutluluk duyarız! :)
hjk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.