24 Eylül 2013 Salı

Hibernate Extra Lazy Collection

OneToMany ilişkilerde Hibernate List arayüzünü gerçekleştiren PersistentBag sınıfını kullanır. 
Bu sınıfın size() metodu aşağıdaki gibidir.

Eğer OneToMany  ilişki lazy tanımlanmış ise yukarıdaki kodda görülen readSize metodu aşağıdaki
if (persister.isExtraLazy()){...} dalına girmez . Grimediği için de en alttaki read() metodunu çağırır ve false döner. Dolayısıyla aşağıdaki gibi bir  Sql cümlesinin çalışmasına sebep olur.

select * from child where child.parentID = ?

Eğer ilişki @LazyCollection(LazyCollectionOption.EXTRA) anotasyonu ile extra lazy olarak tanımlı ise bu sefer if (persister.isExtraLazy()){...}dalına girer ve aşağıdaki gibi bir  Sql cümlesinin çalışmasına sebep olur.
select count(ID) from child where child.parentID =?

.Net
.Net ile Lazy sınıfı geliyor. Bu sınıf aslında PersistentBag ile benzeşiyor. Örneğin veritabanından lazy yükleme yapmak için aşağıdaki gibi yapabiliriz.

Lazy<List<Order>> orders = new Lazy<List<Order>>(() => LoadOrders()); 

List<Order> LoadOrders()
{...}


23 Eylül 2013 Pazartesi

.Net ThreadPool vs. QThreadPool vs. Java ThreadPoolExecutor

Not 1: Linux Scheduler'ları başlıklı yazıda ThreadPool içinde koşan thread'lerin öncelik seviyesinin ayarlanması ile ilgili bilgi bulmak mümkün.
Not 2 : ACE_Thread_Manager ile yeni thread yaratmak başlıklı yazıda ise Process Scheduler ve kernel tarafından kullanılabilen thread modelleri ile ilgili bilgi bulmak mümkün.

.Net 4.0 ThreadPool

.Net 4.0 ile gelen ThreadPool sınıfı yaratılabilecek azami thread sayısını dinamik olarak hesaplıyor.

MSDN'nin dediğine göre :

There is one thread pool per process. Beginning with the .NET Framework version 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. A process can call the GetMaxThreads method to determine the number of threads. The number of threads in the thread pool can be changed by using the SetMaxThreads method. Each thread uses the default stack size and runs at the default priority. 
4 tane Core i5 CPU'ya sahip 3 GB hafıza taşıyan sistemim için bu rakamlar :

1023  tane worker thread ve 1000 tane de I/O completion thread çıkınca bayağı şaşırdım. Bu kadar çok thread açılabileceğini hiç sanmazdım.

Aslında açılan thread sayısını da sınırlamak için bir tedbir de düşünülmüş.
ThreadPool Max Threads sorusuna verilen bir cevapta :

However, there's something else at play: the thread pool doesn't immediately create new threads in all situations. In order to cope with bursts of small tasks, it limits how quickly it creates new threads. IIRC, it will create one thread every 0.5 seconds if there are outstanding tasks, up to the maximum number of threads. I can't immediately see that figure documented though, so it may well change. I strongly suspect that's what you're seeing though. Try queuing a lot of items and then monitor the number of threads over time.

Yani ThreadPool'da akıllı davranıyor ve biraz bekliyor çünkü çoğu işin kısa sürede biteceğini düşünerek iyimser davranıyor.

ThreadPool Available Threads shows very high figures sorusunda ise kaç tane daha thread'in açılabileceğini öğrenmek için ThreadPool.GetAvailableThreads metodunun kullanımına örnek verilmiş.



QT QThreadPool

Öte yandan QT ile gelen QThreadPool sınıfı en fazla sistemdeki core sayısı kadar thread yaratıyor.

Returns the ideal number of threads that can be run on the system. This is done querying the number of processor cores, both real and logical, in the system. 

Yani benim sistemimde bu sayı 4 olacaktı ki .Net ThreadPool sıfınıfa göre sayı yetersiz görünüyor.

Bu arada QT ile yaratılan threadler posix threadleri. Thread'ler pool tarafından join edilecek şekilde yaratılıyorlar. Yani threadler yaratılırken PTHREAD_CREATE_DETACHED flag'i kullanılmıyor. Bu flag'in kullanım amacını buradan okuyabilirsiniz. Böylece thread pool tüm worker thread'lerin bitmesini waitForDone() metodunu çağırarak bekleyebiliyor. waitForDone() metodu ise aslında pthread_join metodunu çağırıyor. Aşağıda pthread_join() metodunun nasıl çalıştığını gösteren bir şekil var.


Yeri gelmişken Avoiding memory leaks in Posix Thread Programming başlıklı yazıda
ls /proc/PID/task | wc -l ve (Bu komut ile aktif threadler sayılıyor)
pmap PID | grep 10240 | wc -l (Bu komut ile yaratılan thread stackleri sayılıyor)
komutları kullanılarak pthread_join() metodu ile bitmesi beklenilmemiş thread'lerin nasıl bulunabileceği anlatılıyor.

Nitekim yaptığımız bir projede karşı cihazı SNMP ile sorgulama işinin biraz uzun sürmesi halinde QThreadPool sınıfının tıkanma noktası oluşturduğunu görüp  açılabilecek max. thread sayısını artırmak zorunda kalmıştık.

Kendi Thread Poolumuz
Aşağıda kendi thread pool nesnemizi kabaca gösteren bir kod parçası var.
class Executor {
  FIFOQueue<Task> m_List;
  FIFOQueue<Task> m_CompletedList;

  void Initialize (int threadCount){
    for (int index = 0; index < threadCount; index++) {
      Worker thread = new Worker (this);
       t.start ();
    }
  }

  bool ExecuteTask () {
    Task* pTask = m_List.Dequeue ();
    pTask->Perform ();
    m_CompletedList.Enqueue (pTask);
  }

  Task* GetCompletedTask () {
    return m_CompletedList.Dequeue ();
  }
};

class Worker : public Thread {
Executor* m_pExecutor;
  void Execute () {
    while (runFlag){
        m_pExecutoer->ExecuteTask ();
    }
  }  
};

Java ThreadPoolExecutor

ThreadPoolExecutor aslında karmaşık bir hiyerarşinin parçası. Bu hiyerarşiye kısaca bakarsak herşey Executor ve ExecutorService arayüzleri ile başlıyor.

Arayüzleri gösteren bir diğer şekli ise buradan aldım.

 Bir ExecutorService yaratmayı kolaylaştırmak için Executors sınıfı mevcut. Örneğin aşağıdaki kod parçasıyla
ExecutorService sendingService = Executors.newSingleThreadExecutor();

buradan aldığım şekildeki gibi herşeyi sırayla işleyen tek threadli bir servis yaratılabilir.



Java ile gelen ThreadPoolExecutor ise kendisi kaç tane thread açması gerektiğini hesaplamıyor bile. Her şeyi programlayacının inisiyatifine bırakmış ne kadar istersen o kadar aç ben karışmam diyor.Aşağıdaki şekli buradan aldım.



Yalnız ThredPoolExecutor sınıfının bir güzel özelliği işlemediği görevleri için bir rejection handler kullanması. Aşağıda buradan aldığım hazır kullanılabilen rejection handler sınıflarının şekli var.


Özel bir çeşit thread pool olan ScheduledThreadPoolExecutor sınıfının hiyerarşi şeklini ise buradan aldım.

Özet
Özet olarak .Net ThreadPool sınıfı ise işin bloke olabileceğini farz edip core sayısından kat kat fazla thread açılabilmesine imkan tanıyor.Çıtayı çok yüksek tutmuş.


 QThreadPool sınıfı kendine verilen işlerin çok çabuk biteceğini farz ediyor ve işin bloke olmasını kabul etmiyor. Dolayısıyla çıtayı alçak tutup azami thread sayısını düşük tutmuş.

Esasen QThreadPool sınıfını da 1023 thread açabilecek hale getirdikten sonra problem kalmıyor ancak iki thread pool sınıfı arasındaki felsefe farkına dikkat çekmek istedim.

Jaba ThreadPoolExecutor ise ben bilmem  beyim bilir yöntemini seçmiş ve her şeyi programlayıcıya bırakmış.

20 Eylül 2013 Cuma

Spring Bean XML Tanımları

Spring IoC XML tanımları ile ilgili aldığım notlar aşağıda.

Yaratılmış Olan Bean'e Değer Atamak
Tek Parametreli Setter İle Bir Başka Bean Atamak
Örnek buradan geldi.
<property name="beanTwo" ref="yetAnotherBean"/>
Tek Parametreli Setter İle Değer Atamak
Örnek buradan geldi.
<property name="name" value="myvalue" />
Tek Parametreli Setter İle List Atamak
Örnek buradan geldi.
<property name="list">
    <list>
        <value>1</value>
    </list>
</property>
Bean Yaratmak
Constructor metoduna parametre geçmek
Örnekte constructor parametreleri string ise aynen geçilir. int long tipleri ise XML'de hangi tip oldukları belirtilir.

<bean id="Pool" class="org.apache.commons.pool.impl.GenericKeyedObjectPool">
  <constructor-arg type = "int" name = "maxActive" value="3" />
  <constructor-arg type = "long" name = "maxWait" value="3000" />
  <constructor-arg name = "testOnBorrow"  value="true" />
</bean>

Factory Sınıf ile Bean Yaratmak
Elimizdeki sınıfın bean yaratmak için static bir metodu varsa aşağıdaki gibi kullanabiliriz. Örnekte Pattern sınıfının static olan compile metodu yeni bir bean yaratmak için kullanılıyor.
<bean id="pattern" class="java.util.regex.Pattern" factory-method="compile">
    <constructor-arg value="abc"/>
</bean>

6 Eylül 2013 Cuma

SSH

SSH ile key üretmek için ssh-keygen yazılımı kullanılıyor. Bu yazılım bir private bir de public key üretir.
 Public key her zaman karşıdakine verilen dosyadır. Aşağıda bu durumu gösteren ve buradan aldığım bir örnek resim var.
Bir başka örnekte ise public/private key oluşturmak için aşağıdaki komut kullanılıyor. -f seçeneği ile private key'in hangi dosyaya konulacağı belirtiliyor.
ssh-keygen -t rsa -f ~/.ssh/id_rsa
Public karşıdaki sistemin ~/.ssh/authorized_keys dosyasına eklenir. Örneğin ismi id_rsa.pub olan public key dosyasını eklemek için aşağıdaki komut kullanılabilir.
 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Karşı Sistemde Komut Çalıştırmak
Örnek:
ssh root@mypc "opt/mycode/check.sh"

Eğer istersek bir betik yazıp ssh'a parametre geçip geçilmediğini de kontrol edebiliriz. Örnek:
if [ $# - eq 2 ]; then
  ssh root@mypc $1
fi