[Gelistirici] YALI'daki donma problemi ve processEvents meselesi

Gökçen Eraslan gokcen at pardus.org.tr
28 Ağu 2010 Cmt 12:41:50 EEST


Selamlar,

Dün dizüstü bilgisayarımda da 2011 alfanın YALI donma problemi ile 
karşılaştım, formatlamadan sonra paket kurulumuna geçildiğinde progress %0'da 
kaldı ve devam etmedi. Log da aynı yerde durmuştu. Hiç bir yerde de herhangi 
bir exception yoktu. İşin ilginç tarafı 2009.2'nin YALI'sını kullanıyoruz ve 
YALI'nın processEvents ve PisiEvent tarafları, çoook uzun zamandan beri hiç 
bir değişikliğe uğramamış. 2011 için ilerde kullanacağımız YALI'da da o kodlar 
aynı şekilde. 2009 ya da Kurumsal2'de de aynı sorunları yaşamıyor olmamızın 
nedeni, bu sorunun 2011 ile tetikleniyor olması mı bilemedim.

Sorunun nedenini incelerken yali/gui/ScrInstall.py dosyasındaki PisiUI 
sınıfında QEvent kullanımı dikkatimi çekti. Kod şu şekilde:

class PisiUI(QObject, pisi.ui.UI):

    def __init__(self, *args):
        pisi.ui.UI.__init__(self)
        apply(QObject.__init__, (self,) + args)
        self.lastPackage = ''

    def notify(self, event, **keywords):
        if event == pisi.ui.installing or event == pisi.ui.configuring:
            qevent = PisiEvent(QEvent.User, EventPisi) #EventPisi=1001
            data = [keywords['package'], event]
            self.lastPackage = keywords['package'].name
            qevent.setData(data)
            objectSender(qevent) #postEvent ile GUI threade gidiyor

    def display_progress(self, operation, percent, info, **keywords):
        pass

Sanırım Qt4.7 ya da 2011'de kullandığımız yeni bir şeyden dolayı, 
PkgInstaller'ın start methodunun çağrılmasından itibaren, GUI thread'ine hiç 
sıra gelmiyor. Böylece PkgInstaller thread'inin GUI thread'ine gönderdiği 
PisiEvent'ler de hiç işlenmiyor. Bunun için eskiden biryerlerde processEvent 
konmuştu diye hatırlıyorum ama processEvents sadece 
yali/gui/YaliWindow.py'daki processEvents methodunda var ki bu da doğrudan 
QApplication.processEvents çağırmak yerine bir sinyal yayınlıyor ve 
yali/gui/runner.py'de de bu sinyal işlenip self._app.processEvents çağrılıyor.

Eventlerin hiç işlenmemesini, pis bir workaround olarak, her PisiEvent'in GUI 
thread'ine gönderilmesinden sonra QApplication.processEvents çağırarak çözdüm, 
yama ekte. Ancak YALI'nın bu haliyle 2011 kurabildim. Ekteki yama yüksek 
ihtimalle tüm donma problemlerini çözecektir ama zaten yeterince karmaşık olan 
thread'lerin haberleşme mekanizmasını 0.1 kat daha karmaşıklaştıracak.

Özet olarak bu sorun için şunlar denenebilir diye düşünüyorum:

1- GUI thread'ine gönderilen her PisiEvent'ten sonra 
(yali/gui/runner.py'dekinden farklı olarak) doğrudan 
QApplication.processEvents çağırmak (bkz. ekteki yama),

2- yali/gui/ScrInstall.py'daki objectSender'taki postEvent'i sendEvent'e 
çevirerek, event'in queue'ya girmeden çalıştırılmasını sağlamak, (bunu denedim 
ama bir sonuç alamadım, detaylı bakmak lazım)

3- 	QThread + Event based iletişim yerine Python threading/multiprocessing + 
PisiUI sınıfının notify callback'ini kullanarak iletişim kurmak,

Şimdilik aklıma gelenler bunlar. Başka fikri olan?

-- 
Gökçen Eraslan
Pardus Developer
-------------- sonraki bölüm --------------
A non-text attachment was scrubbed...
Name: fix-yali-freeze.diff
Type: text/x-patch
Size: 460 bytes
Desc: kullanılamıyor
URL: <http://liste.pardus.org.tr/gelistirici/attachments/20100828/d8c73bd1/attachment-0002.bin>
-------------- sonraki bölüm --------------
A non-text attachment was scrubbed...
Name: kullanılamıyor
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://liste.pardus.org.tr/gelistirici/attachments/20100828/d8c73bd1/attachment-0002.pgp>


Gelistirici mesaj listesiyle ilgili daha fazla bilgi