Znalezione na PubSub…

Pisałem już o swoich eksperymentach z PubSub. Zauważyłem, że jeden tytuł ciągle się
w powiadomieniach przewijał (z różnych źródeł): Python Is Not Java. W pewnym momencie dostałem
to nawet cyrylicą. W sumie to interesujące jak się informacja rozchodzi po różnych blogach itp.
W końcu postanowiłem zajrzeć o co chodzi i chyba znalazłem źródło: Python Is Not Java. Rzeczywiście
— ciekawy artykuł. Nie używam, ani za bardzo nie znam Javy, ale miło
poczytać chociażby o przewadze Pythona w niektórych dziedzinach
:-).

Zauważyłem też, że PubSub daleko do śledzenia całego Internetu, a może nawet
oni filtrują (cenzurują, jeśli ktoś woli) częściowo swoje feedy. Utworzyłem sobie subskrypcję która
miała wyłapywać różne erotyczne artykuły (taki eksperyment), ale nic takiego
się nie złapało (chociaż trafień zapytanie trochę miało). Możliwe też, że po
prostu brak feedów RSS dla takich mało ambitnych treści. BTW. wpisywanie zapytania fuck
ma mały sens — w końcu to wildcard do którego wszelkie tematy pasują ;-)

Mam go! :-)

Od wielu miesięcy gnębi mnie jeden błąd w CJC: czasem gdy ja coś robię (np.
przełączam bufory) i jednocześnie coś przychodzi z sieci to się wiesza. Typowe
zakleszczenie (deadlock). Wiadomo, że gdzieś źle blokady wątków zastosowałem,
ale to się strasznie źle debuguje (dlatego IMHO wątków należy unikać jak
ognia). Kiedyś próbowałem, ale bardzo się nie postarałem i poległem. Potem po
prostu problem olewałem (pojawiał się tylko raz na jakiś czas, więc można było
z tym żyć). Wczoraj powiesiło się znowu i postanowiłem dzisiaj coś z tym
zrobić.

Najpierw więc dodałem do CJC obsługę pliku konfiguracyjnego dla modułu
logging ze biblioteki pythona (świetna rzecz!). Potem zapuściłem
na źródłach coś takiego:


find . -name "*.py" | xargs perl -pi -e \
's/^(\s+)([\w.]+\.(acquire|release)\(\))[ \t]*$/\1logging.getLogger("lockdebug").debug("\2..."); \2; logging.getLogger("lockdebug").debug("...\2")/'

Po tej operacji odpaliłem CJC, wszedłem na dwa czaty grupowe i zacząłem
przełączać bufory jak szalony. Po jakiejś minucie, czy dwóch zwiesił się
(Murphy poszedł na piwo?). No i chyba mam go! 🙂


2004-10-24 16:49:38,503 window.py: 167 th#16386 DEBUG self.screen.lock.acquire()...
2004-10-24 16:49:38,516 window.py: 167 th#16386 DEBUG ...self.screen.lock.acquire()
2004-10-24 16:49:38,524 text_buffer.py: 42 th#65540 DEBUG self.lock.acquire()...
2004-10-24 16:49:38,525 text_buffer.py: 42 th#65540 DEBUG ...self.lock.acquire()
2004-10-24 16:49:38,526 window.py: 252 th#65540 DEBUG self.screen.lock.acquire()...
2004-10-24 16:49:38,527 text_buffer.py: 208 th#16386 DEBUG self.lock.acquire()...

Teraz pozostaje to poprawić i liczyć na to, że to odosobniony przypadek
:-)

Staczam się… ;-)

Chyba się staczam… ostatnio zarywam noce kodując w… PHP. ;-)

Wszystko dlatego, że postanowiłem u siebie postawić
system śledzenia błędów dla PLD. Stary był brzydki i
niezbyt wygodny, a przez ostatnie tygodnie nie działał w ogóle — zbytnio
obciążał maszynę na której był postawiony, a poprawiać go nie było komu.

Dyskusja na temat alternatywy powracała już kilka razy na listy zwykle bez
efektu. Jednak pewną tendencję w dyskusjach można było zauważyć — nowy
system powinien być opary o jakieś gotowe rozwiązanie, najlepiej żeby to była
Bugzilla, Mantis lub Flyspray. Bugzilla mi się nie podoba (stanowczo za dużo
kontrolek w formularzach), poza tym wydaje się na tyle skomplikowana, że jej
dostosowanie do naszych potrzeb mogłoby okazać się trudne i długotrwałem.
Mantisa nie znam, a Flyspray, znany
z Buggera po prostu mi się podoba,
a skoro ja użyczam sprzętu i chcę sie tym zająć, to moje zdanie może być
decydujące. :-)

Tak po prostu postawić Flyspray’a to byłoby za mało. On powstał dla
zupełnie innych projektów niż PLD. Np. pole system operacyjny nie ma
u nas sensu, zamiast tego ważniejsza jest architektura. Poza tym w błędzie
najistotniejszy jest pakiet którego dotyczy i jego wersja. Nie chciałem dla
każdego pakietu robić osobnego projektu (osobne projekty są dla poszczególnych
linii dystrybucji (Ra, Ac, Th) i innych projektów związanych z PLD (ten BTS,
LiveCD, RescueCD)), więc wykorzystałem obecne już pole kategoria.
Trzeba było przy tym mocno zmienić interfejs, gdyż pole wyboru pakietu
zawierające listę wszystkich pakietów (tysiące!) to byłoby nieużywalne.
Podobnie z wersjami, które w oryginalnym Flyspray są określane per-projekt,
a u nas muszą być per-pakiet. To wszystko udało się właściwie zrobić.
Udało mi się też przenieść bazę pluskiew ze starego systemu.

Poza zmianami przystosowawczymi wprowadziłem też inne ulepszenia.
Np. język interfejsu jest konfigurowalny per-użytkownik, a domyślnie brany
z ustawień przeglądarki. Poza tym włączyłem serwowanie stron jak
application/xhtml+xml dla przeglądarek które to akceptują. To
zresztą uziemiło system na jakiś czas, bo się okazało, że XHTML to strony
generowane przez Flyspraya mają tylko w DOCTYPE. No na głównej stronie nie
było źle, nie walidowała się jedynie z powodu pustego <optgroup/>.
Niestety większość pozostałych stron nie była nawet well-formed XML
przez co przestała się w ogóle wyświetlać. Wczoraj udało mi się większość
z tego poprawić, więc już się wyświetla w przeglądarkach obsługujących XML,
ale raczej Valid XHTML Strict to w większości nie jest.

No i dzisiaj wreszcie udało mi się uruchomić narzędzie, które w poprawianiu
tego XHTMLa może mi pomóc:
HTML Validator dla Mozilli
. Polecam! Niestety to rozszerzenie w postaci
gotowej do zainstalowania dostępne jest jest jedynie dla Windowsów.
W Linuksowym Firefoksie instaluje się bez zająknięcia, ale po prostu nie
działa. Okazało się, że w środku siedzi binarka nstidy.dll,
nstidy.so trzeba sobie samemu skompilować (źródła rozszerzenia są
dostępne). Do kompilacji teoretycznie potrzebne są źródła Mozilli, ale nie
uśmiechało mi się ich instalowanie i kompilowanie, więc jakoś poradziłem sobie
bez tego — w końcu hacker jestem! ;-)

Poza BTSem podłubałem trochę w automatyce builderów (małe zlecenie do
Havnera). To już była czysta przyjemność, bo automatyka jest w Pythonie.
:-) Niestety okazało się, że przy okazji coś po psułem
i w niedzielę w nocy, zamiast iść spać musiałem poprawiać…

Rozpowszechnianie standardów…

Już pisałem o tym, że do generowania dokumentacji do PyXMPP używam
Epydoc. Bardzo ładnie wyciąga
dokumentację z kodu, ale… zajrzałem wczoraj do wygenerowanego HTMLa.
Najpierw miła niespodzianka, DOCTYPE XHTML 1.0 Transitional. Jednak
radość znikła gdy zapuściłem na tym xmllint --valid
--noout
. Nawet well-formed to nie było. xmllint
--html
nie lepiej. Ani o XHTML, ani HTML. Gdy zajrzałem do środka
moje obawy się potwierdziły — koszmarek. Wstyd mi by było to na stronie
projektu publikować.

Wczoraj więc wypełniłem bugreporta na SourceForge, a
dzisiaj w tym podłubałem i conieco porawiłem. Już się waliduje, niestety nie
jako XHTML Strict, bo to ramek używa. Ale i tak usunąłem wszystkie
<center/>,
<font/>,
<b/>,
<i/>, itp.,
zamieniając na coś odpowiedniejszego i dodając odpowiedni styl. Poprawiłem
też funkcję kolorującą regexpy (w dokumentacji pyxmpp.jid wrzucała znak bajt 0
do wyniku) oraz obcinającą za długie fragmenty HTMLu (żeby zamykała tagi).
Patcha dołączyłem do bugreportu i opisałem na liście dyskusyjnej. Zobaczymy co
z tego wyniknie ;-). Mam nadzięję, że patch nie zostanie olany.

Coś nie tak z resolverem…

Już jakiś czas temu ktoś miał problemy z CJC, które nie łączyło się z tym co
trzeba, czy nie mogło znaleźć serwera. Pomyślałem, że to mój resolver nawala,
ale user który to zgłosił stwierdził, że miał bzdury w swojej konfiguracji
(/etc/resolv.conf).

Dzisiaj dwóch (a może jeden wczoraj, nie pamiętam) użytkowników zgłosiło mi,
że CJC zwraca błąd, że serwer odrzucił połączenie. Poprosiłem o logi i w
jednym z tych logów jak byk było, że CJC szuka
jabber.bnet.pl, a potem łączy się z
209.73.243.23, który to adres IP nie ma nic z
jabber.bnet.pl wspólnego. Drugi user w logach nie miał nic na ten
temat (nie wiem czemu), ale zaczęło mu działać dopiero po podaniu adresu IP
serwera w konfiguracji CJC.

Czyli jakiś błąd ewidentnie jest, ale ja nie wiem jak go szukać. Bo oczywiście
u mnie działa.

Mix-ins

Gdy w CJC użyłem osobnej klasy (nazwijmy ją A) do
rozszerzenia funkcjonalności innej klasy (B), ale tak, że to
B dziedziczyło po A, to myślałem że stosuję jakiś dziwny,
brudny trik dla własnej wygody. Później czytając dokumentację do
pylinta spotkałem się z określeniem mix-in class, nie
wiedziałem co to jest, ale tak jakoś mi się skojarzyło z tym co zrobiłem w
CJC.

Teraz coś podobnego chcę zrobić w PyXMPP, aby podzielić
jeden wielki moduł pyxmpp.stream na mniejsze kawałki.
Przypomniałem sobie o mix-in class i wrzuciłem to w Google. Okazało się,
że miałem rację. Dowiedziałem, że to znana technika programowania
obiektowego, która wcale nie jest zła. Znalazłem nawet artykuł o tym jak używać mix-ins w
Pythonie
. Rzeczywiście Python bardzo ułatwia stosowanie tej techniki.

No to teraz, gdy się podszkoliłem, mogę z czystym sumieniem wziąć się za
wydzielanie StreamSASLMixIn i StreamTLSMixIn.
:-)