31 Mart 2016 Perşembe

DDS ve Ağ Merkezli Muharebe üzerine

DDS Standartları
DDS'in şu anda v1.2 sürümü mevcut. RTPS'in ise v2.1 sürümü mevcut.

DDS Nerede Kullanılmaz
DDS her yerde mutlaka kullanılması gereken her derde deva bir altyapıymış gibi sunuluyor. DDS Silver Bullet değildir. Kullanılması gereken ve gerekmeyen yerler vardır.

Remote Method Invocation
DDS Java'daki terminoloji ile RMI tarzı çağrılar gerektiren işler için uygun değildir. İsteğe karşı cevap bekleniyorsa, cevabı başka bir Topic üzerinden almak gerekir. İstek ve cevap arasında JMS'teki gibi otomatik ilişki kurma yeteneği de sağlamadığı için bu tür kullanım şeklinde sıkıntıya sebep olur.

CORBA da bu tür işler için daha uygun olabilir. CORBA şöyle ilklendirilir.
java.util.Properties props = new java.util.Properties();
props.put("org.omg.CORBA.ORBInitialPort", initialPort);
props.put("org.omg.CORBA.ORBInitialHost", initialHost);
props.put("com.sun.CORBA.giop.ORBGIOPVersion", "1.0");
orb=org.omg.CORBA.ORB.init(args,props);

Wide Area Network
DDS discovery protokolü broadcast yöntemini kullandığı için WAN üzerinde kullanıma uygun değildir. DDS nodlarının birbirlerini bulabilmeleri için tünel açmak gerekir.

DDS
Ağ merkezli muharebenin temel özelliklerinden birisi savaş alanındaki unsurların bir veri aktarım yolunu kullanarak birbirleri ile mümkünse gerçeğe yakın zamanlı ilişki kurabilmesidir.
DDS diğer iletişim altyapıların göre gerçek zamanlı veri aktarımına daha müsait bir yapıya sahiptir. Aşağıdaki şekli buradan aldım ve bu fikri destekliyor.


QoS Parametreleri
DDS QoS Parametreleri Listesi yazısına taşıdım.

DDS Standartları
DDS Interoperability Write Protocol (DDSI) çeşitli DDS üreticilerinin byte seviyesinde aynı dili konuşmasını sağlıyor. DDS API'si ise kod seviyesinde standartlaşmayı sağlıyor. Böylece DDS kullanan uygulama farklı bir DDS ürünü ile entegre edilebiliyor.

DDS ve Nesneye Yönelik Tasarım
DDS ile Nesneye Yönelik Tasarım arasında çok temel bir fark var. Nesneye Yönelik Tasarımda nesne veri + davranıştan oluşur. DDS nesneleri ise sadece veriden ibarettir. Gerçek anlamda nesne olduklarını düşünmüyorum. Bu amaç için DDS nesneleri başka nesneler ise sarmalanarak kullanılabilir.

DDS Temel Sınıfları
DDS ile kullanılan temel sınıfları gösteren bir şekli buradan aldım.

DDS Temel Kavramları
Data Centric Publish Subscribe (DCPS) :
Örnek yaz

Data Local Reconstruction Layer (DLRL) :
Bu kavramda tüm nesnelerin türediği Java'daki gibi bir "Object" sınıfı kullanılıyor. Ben DLRL'nin her yerde kullanılmasını doğru bulmuyorum. DLRL birbiriyle ilişkili verileri, örneğin bir ağaç yapısını oluşturmayı güçleştiriyor. Bu tür yapıların bellekte kendi veri yapımızı içinde tutulması, DLRL kullanmaktan daha iyi diye düşünüyorum.
 

Instance : Aynı topic içinde "key" değerleri farklı olan nesneler.
Sample : Aynı Instance'a ait farklı zamanlardaki veri.
Instance Sample için Resource Limits QoS  başlıklı yazıya göz atabilirsiniz.

Publisher
Bir tane yaratılır. "The publisher acts on behalf of one or several DataWriter objects that belong to it". Yani kısaca DataWriter'lar için factory sınıfı. Burada ilginç olan publisher hem bir factory ama aynı zamanda yarattığı nesnelerin kendisi üzerinden çalışmasını istiyor. Yani ilginç bir tasarım!

DataListener

Gelen veriyi dinlemek için örnek:
DDS::DataReaderListener* pListener = //...
DDS::DataReader* pDataReader = //...
DDS::StatusMask listenerMask = DDD::DATA_AVAILABLE_STATUS;
DDS::ReturnCode_t result = pDataReader->set_listener (pListener, listenerMask);

Listener şöyle yazılmalı

void MyListener::on_data_available(DDS::DataReader* reader)
{
   MsgSeq received_data; //IDL'den üretilen sınıf
   SampleInfoSeq sample_info; //DDS sınıfı
   MsgDataReader reader = MsgDataReader::narrow(reader);//IDL'den üretilen reader
   reader->take (received_data,sample_info, ...);
}

Dinlemeyi durdumak için örnek:
pDataReader->set_listener (pListener, 0);

DataWriter
DataWriter yazısına taşıdım.

DataReader
Temel olarak take() ve read() şeklinde iki metod sunar. take() şeklindeki metodlarla sample arakatman belleğinden silinir. read() şeklindeki metodlarla sample arakatmanda yaşamaya devam eder.
Örnek:

Sequence<Msg> seq;
reader->take (seq,sample_info_seq,1,
                      DDS:NOT_READ_SAMPLE_STATE,
                      DDS::ANY_VIEW_STATE,
                      DDS::ANY_INSTANCE_STATE);

WaitSet
WaitSet'e bir Condition verilir. DataReader WaitSet üzerinde bekler.Condition'lar ReadCondition, StatusCondition, QueryCondition, GuardCondition olarak ayrılırlar.

Filtreler

DDS ile iki çeşit filtre tanımlama imkanı bulunmaktadır.

Birinci çeşit filtreler içerik filtrelerdir (content filter). Bu filtreler ile gönderilen bilgi taşıdığı veriye göre uygulama seviyesine çıkmadan filtrelenebilir.

İkinci çeşit filtre ise zamana bağlı filtrelerdir (time based filter). Bu filtreler ile gönderilen verilen tümü değil de bizim ayarladığımız periyotlarda güncellemeler okunur. Yayın yapan birime göre daha yavaş kalan abonelerin fazlasıyla istifade edebilecekleri bir özellik olduğunu düşünüyorum. Aşağıda buradan aldığım bir şekil ile filtre konusu görülebilir.

İçerik Filtresi

Zaman Filtresi


Filtreler DataReader sınıfına uygulamanın ilgilendiği ve okumak istediği bilgileri bildirir .DataReader ağ üzerinden gelen bilgilerden sadece belirtilen kriterlere uyanları uygulamaya geçirir, uymayanları ise kaale almaz.

Örneğin ben okuyan taraf olarak hızı belli bir değerin üzerinde olan ve teşhis bilgisi "dost" olan izleri görmek isteyebilir. Bu durumda yapmam gereken DataReader'ıma bu filtreleri vermek ve sadece verdiğim parametrelere uyan bilgiler geldiği zaman haberdar edilmeyi beklemek olacaktır.

Aşağıdaki kısım sayın Ertan D.'nin uyarısı ile değiştirildi. Aslında RTPS 2.1 versiyonunda halen "DataWriter side filtering" kısmı isteğe bağlı olarak geçiyor ancak bu işlevi yerine getirmeyen ara katman yazılımı en azından büyükler arasında kalmadı sanırım. Yine de eski sürümlerde üstü çizili olan cümlelere dikkat etmek gerekebilir.

Ancak dikkat edilmesi gereken bir nokta filtrelerin sadece DataReader tarafından bilindiği hususudur. Yani bize bilgi yollayan birim, bizim ilgilendiğimiz kriterlerden haberdar değildir. Yani filtreler bant kullanımını azaltmak için işe yaramaz. Sadece uygulamanın kendi içinde fazladan kod yazarak filtreleme yapma işleminin ara katmanının üzerine yıkar.

Kanımca eğer filtreleme işlemi de DataWriter tarafından yapılıyor olsaydı bant genişliği problemi bir nebze daha halledilmiş olurdu.

Esasen DDS'in çıkış noktası yerel ağlara sahip gemi sistemleri olduğu için (ve gemilerde bant genişliği uzak mesafe iletişimde olduğu kadar ciddi problem olmadığı için) bant genişliği problemi henüz daha gündeme gelmemiş olabilir.

DDS'in kullanımı yaygınlaştıkça filtreleme işleminin daha dağıtık bir yapıya dönüşüp, bu problemin de bir şekilde halledileceğini umuyorum.

2 yorum:

  1. DDS RTPS protokolu DataReader tarafinda tanimlanan filtrelerin DataWriter'lara iletilmesini ve verinin DataWriter tarafinda filtrelenmesine izin verir.

    YanıtlaSil
  2. Çok güzel bir yorum. Dikkatiniz için teşekkürler. DDSI spec'ini sayenizde bir daha kontrol ettim. 2.1 versiyonunda şöyle yazıyor.

    8.7.3.3 Requirements for Interoperability
    Writer side filtering constitutes an optimization and is optional, so it is not required for interoperability.

    Writer side filtering implement edilmemiş olabilir ama sanırım artık belli başlı üreticiler etmişler. Yazıyı da düzeltmem gerekiyor :-)

    YanıtlaSil