Zaloguj się

Jog Jajcusia

xmpp:jajcus@jajcus.net

Obfalkać drzwi...

Gdy wychodziliśmy z Krysią na spacerek kichnąłem. Tak porządnie i w kierunku drzwi sąsiadów. Krysię bardzo to rozśmieszyło. Zażartowałem, że obsmarkałem drzwi sąsiadów. Śmiała się jeszcze bardziej, powtarzając obfalkał drzwi. Później jej przeszło.

Gdy wracaliśmy, piętro pod naszymi drzwiami Krysia pociągnęła mnie w kierunku drzwi, mówiąc: obfalkać drzwi!, ja na to nie obsmarkam drzwi sąsiadom, ona: dzidzia obfalka!. Podeszła do drzwi i dmuchnęła nosem. Była bardzo z siebie zadowolona.

A za chwilkę zabieram się za optymalizacją PyXMPP. Teraz w CJC jak napisze /chat ktos@ i nacisnę dwa razy TAB, to ponad minutę muszę czekać aż dostanę dwa pasujące JIDy do wyboru. Tak raczej być nie może. Myślę, że cache JID-ów i wyników stringprep pomoże. Wcześniej muszę jednak z JID-ów zrobić obiekty immutable i nie wiem czy dużo nie będę musiał poprawiać (API się zmieni odrobinkę).

4 komentarze do wpisu „Obfalkać drzwi...”


Porządki w kodzie i na Joggerze

Wywaliłem z PyXMPP wsparcie dla Pythona 2.2 i spróbowałem użyć modułu datetime do obsługi timestampów. Okazało się, że jednak nie rozwiązuje on moich problemów. Zapewnia interfejs do zamiany czasu pomiędzy lokalnym a UTC, ale... tylko wtedy jak mu się poda klasy reprezentujące odpowiednie strefy czasowe. A Python w module datetime udostępnia jedynie abstrakcyjną klasę bazową. Resztę trzeba sobie napisać. UTC to nie problem, ale przecież nie będę pisał klas opisujących strefy czasowe wszystkich potencjalnych użytkowników CJC! Jest gdzieś w sieci moduł zawierający gotowe klasy, ale ja nie chcę dodawać kolejnej zależności, szczególnie, że przecież w systemie już jest informacja o strefie czasowej użytkownika.

Zajrzałem do dokumentacji glibc, żeby zobaczyć jak się to w C robi. Jest tam nawet potrzebna mi funkcja, nazywa się timegm, ale:

*Portability note:* `mktime' is essentially universally available. `timegm' is rather rare. For the most portable conversion from a UTC broken-down time to a simple time, set the `TZ' environment variable to UTC, call `mktime', then set `TZ' back.

Fajnie, że podali przenośny sposób, ale zastosowanie jego w aplikacji wielowątkowej to byłaby zbrodnia. A więc sposobu praktycznie nie ma. Jednak nie będę przecież użytkownikom pokazywał czasu UTC, więc zacząłem kombinować i nawet coś wykombinowałem: zamiana czasu UTC na lokalny medodą kolejnych przybliżeń. Z moich testów — z czasem letnim i zimowym z różnymi ustawieniami zmiennej $TZ — wynika że to nawet działa :-). Ciekawe jak bardzo przekombinowałem.

Dzisiaj, nie mając wiele do roboty w pracy, urządziłem bug fixing day dla CJC. Poprawiłem już dwa błędy zgłoszone na JS oraz kilka zgłoszonych przez Jabbera. Poczekam jeszcze na jakieś bugreporty i może zrobię kolejne wydanie PyXMPP i CJC. MUC jeszcze dość niekompletny, ale używalny, a wydać warto chociażby z powodu błędów poprawionych w stosunku do 0.4.

Oprócz porządków w kodzie zrobiłem też porządki na Joggerze. Uzupełniłem polecane Jogi o nowe pozycje i atrybuty title na linkach. Usunąłem też linki erotycznie, ale nie dlatego że nagle sporządniałem — po prostu nie chciało mi się ich uaktualniać. Poprawiłem jeszcze ostatnią notkę — zamieniłem - na w kilku miejscach. Od dziś postaram się trzymać zasad typografii. Z poprawianiem starszych notek byłoby za dużo roboty.

Dodaj komentarz do wpisu „Porządki w kodzie i na Joggerze”


Zaginiona entropia i stary Python musi odejść

Wczoraj w firmie przeżyliśmy chwilę grozy. Zaczęło się niewinnie. Nie mogłem commitnąć zmian w systemie zarządzania użytkownikami. svn commit zawisał, strace pokazywało, że na dostępie do /dev/random. Nie było to pilne, więc bardzo się tym nie przejąłem. Potem dzwonił gościu, że poczty nie może odebrać. Chwila śledztwa wykazała, że zacina się na autoryzacji DIGEST-MD5. Od razu skojarzyłem to z problemami z /dev/random. Potem było już tylko gorzej — przy niedziałającym /dev/random posłuszeństwa odmówił też PostgreSQL. A ja ciągle nie wiedziałem co się dzieje. /proc/sys/kernel/random/entropy_avail pokazywało 0 i nie chciało nawet drgnąć. Nie pomogło też wybicie procesów korzystających z /dev/random i /dev/urandom. Wyglądało na to, że coś się zacieło. Ten serwer już długo działał, a jeszcze nie było takich problemów.

Pomyślałem o sprzętowym generatorze liczb losowych — podobno niektóre płyty takie coś mają. find /lib/modules -name "*rng*" pokazało dwa moduły. Jeden (amd768_rng) miał nazwę podobną do chipsetu płyty. Załadowałem i nawet działa — cat /dev/misc/amd768_rng pokazywało krzaczki. Jednak aplikacje odwoływały się do /dev/random, a tam dalej bez zmian. Spróbowałem ln -s /dev/misc/amd768_rng /dev/randomPermission denied, mv /dev/random /dev/random.orig — to samo. Cholerny devfs - próbuje być mądrzejszy ode mnie! Zawsze lubiłem ideę devfs — w /dev/ jest tylko to co mam w komputerze, a dysk o konkretnym SCSI-id podłączony do konkretnego kontrolera ma zawsze tę samą nazwę, a nie zależną od tego co jeszcze jest podłączone. Jednak implementacja jest fatalne, a ten przypadek przeważył — devfs wyleciał z tego serwera. I tak robiliśmy reboot, bo innych pomysłów nie było.

Po reboocie okazało się, że /dev/amd768_rng nie jest całkiem zgodny z /dev/random — po podlinkowaniu niektóre aplikacje (w szczególności SVN) zawisały przy próbie korzystania z tegoż. Jednak /proc/sys/kernel/random/entropy_avail było już większe od zera, więc problem chwilowo zniknął. Jednak nie na długo — entropy_avail zaczęło się zmniejszać i znowu doszło do zera blokując wiele usług. Zamiany /dev/random na /dev/urandom nie brałem pod uwagę - po to używam SSL, SASL itp. żeby było bezpiecznie, a /dev/urandom bez entropii generuje liczby bardzo pseudolosowe, a więc do kryptografii niespecjalnie się nadające. Na szczęście kumpel znalazł winowajcę — iptables -m random. Jedna taka regułka była w naszym firewallu i po podłączeniu któregoś klienta najwyraźniej zabrakło na nią entropii. Po zamianie tego na coś innego entropy_avail urosło do sensownej wartości i wszystko zaczęło znowu działać. Ufff...

W PyXMPP i CJC obsługa MUC zaczyna działać. Można już wejść na takiego czata i pogadać. Ale pierwszym felerem, który się rzuca w oczy, są niewłaściwe czasy przy wiadomościach z historii pokoju. Jest tam czas aktualny, zamiast tego podanego w <x xmlns="jabber:x:delay"/>. JEP-91 jest banalnie prosty, więc postanowiłem go od razu zaimplementować. Oczywiste było, że przydałby się typ opisujący czas, którego w Pythonie zawsze brakowało. Zwykle używałem mx.Datetime, ale nie chciałem dla takiej dupereli do PyXMPP dodawać kolejnej zależności. Więc użyłem modułu time, ale on jest do bani. Można pobrać aktualny czas, przedstawić ją w postaci UTC, czy czasu lokalnego, czy skonwertować tekst o znanym formacie na czas — ale tylko w czasie lokalnym. Na zamianę czasu UTC w postaci tekstowej na czas lokalny nie znalazłem sposobu. Poczytałem dokumentację — z niej wynikało że %Z w formacie dla time.strptime czasem może działać — u mnie nie działa. Pogooglałem i okazało się że moje wiadomości na temat braku typu dla czasu są nieaktualne. W Pythonie 2.3 jest moduł datetime, który daje wszystko co potrzebuję wraz z sensownym interfejsem. Dotychczas jednak PyXMPP działało także na pythonie 2.2.x. Chyba przestanie — już dawno zastanawiałem się nad porzuceniem wsparcia dla Pythona 2.2 — chociażby dlatego, że nie ma w nim obsługi stringprep, czy IDN (oba standardy wymagane przez XMPP). Teraz PyXMPP zawiera moją własną implementację stringprep dla Pythona 2.2 (wraz z wymaganą przez nią normalizacją Unicode — to było sporo roboty), a IDN po prostu nie są obsługiwane gdy używany jest Python 2.2 (użycie znaku nie-ASCII w domenie JID powoduje bład). Ciekawe dla ilu użytkowników takie podniesienie wymagań będzie dużym kłopotem. A może w ogóle się tym nie przejmować? W końcu już teraz użytkownicy Debiana muszą kombinować, żeby z PyXMPP skorzystać, bo standardowo mają historyczne wersje Pythona i libxml2. Chyba jednak wywalę obsługę pythona 2.2 — kodowi wyjdzie to tylko na dobre.

7 komentarzy do wpisu „Zaginiona entropia i stary Python musi odejść”



[szpieg] Jesteście obserwowani...