Django 1.2

Właśnie przestawiłem ten serwis na Django 1.2.1. Migracja i dostosowanie kodu zajęły nie więcej niż pół godziny, pomimo sporych zmian jakie były wprowadzone w wersji 1.2. Jak zwykle jestem pod wrażeniem dbałości o zgodność wsteczną i wzorowej dokumentacji projektu.

I niestety tradycyjnie już memory footprint aplikacji wzrósł — nieznacznie, ale od 1.0.x w sumie jest to już ok. 50% większe zapotrzebowanie na pamięć. Z wersji na wersję Django pożera wciąż więcej i więcej.

Piwko, piweczko, piwesio...

Ku własnej wygodzie i pożytkowi potomności zamieszczam parę linków do serwisów poświęconych piwowarstwu amatorskiemu i sklepów, gdzie można kupić artykuły do warzenia piwa.

  • Browar.biz, największy serwis poświęcony piwu, m.in. także piwowarstwu amatorskiemu, sklep Centrum Piwowarstwa
  • Piwo.org, serwis bardziej społecznościowy, m.in. wiki i forum, ale także sklep HomeBrewing
  • Browamator, najstarszy w Polsce sklep z artykułami dla piwowarów
  • Piwodziej.pl, sklep z tanią dostawą w Warszawie, niestety "tanio" zwykle znaczy również "długo"
  • Piwowar, normalny sklep w Warszawie, z tanią lokalną dostawą (i jego drugie wcielenie)
  • WES, sklep wolsztyńskiej Wytwórni Ekstraktów i Słodów
  • TwojBrowar.pl, sklep jakich wiele

Ze sklepów spokojnie mogę polecić BA, CP i HB, ceny są zbliżone, ale asortyment różni się w szczegółach, czas oczekiwania na realizację dostawy jest zbliżony. TB ma trochę nieładu w katalogu i nie zawsze łatwo jest znaleźć to, czego się szuka, ale zamówienia realizują równie szybko, jak pozostali. Piwodziejom z kolei dużo czasu zajmuje dowóz towaru na terenie Warszawy, ale podejrzewam że realizacja innych zamówień też nie jest ekspresowa.

Mądrości Google

Nie wiesz? Zapytaj Google! Może nie otrzymasz odpowiedzi na swoje pytanie, ale na pewno otrzymasz jakieś odpowiedzi na inne pytania, pewnie nawet ciekawsze...

Pewna reorganizacja

Zamierzam trochę pozmieniać konfigurację uruchamiania tego serwisu (a przy okazji może dorobię się ciut wygodniejszego deploymentu, do ponownego wykorzystania), więc w ciągu kilku najbliższych dni można się spodziewać niespodziewanych przerw w działaniu.

Expect unexpected, but prepare for better.

O nauce na własnych błędach

Po raz kolejny BitBucket poszedł w pioch. I kolejne tłumaczenia, że to nie ich wina, że to Amazon skrewił. Symptomatyczne i typowe dla Web2.0 — na codzień będziemy się puszyć, jacy to my fajni jesteśmy i nowocześni, ale jak coś się sypie, to słychać tylko skamlenie.

Again, this is not our fault, and we have to wait for Amazon to fix this. They've been alarmed, and we've forked out for a "Gold plan" support subscription, so they can act as quickly as possible.

Skoro już wiadomo, że to Amazon skrewił (a nie jest to pierwszy raz), to jaki jest plan B? Jak się okazuje, planu B nie ma, oprócz pomiaukiwania na Twitterze i mglistych obietnic, że przeniosą się do innej chmury (co samo w sobie nie jest rozwiązaniem, bo problem leży gdzie indziej). Gdy kilka miesięcy temu BitBucket zniknął z sieci na kilkanaście godzin także za sprawą jakiegoś padu usług AWS, można się było spodziewać, że właściciele BB podejmą jakieś kroki, żeby mieć wyjście awaryjne na wypadek powtórzenia się scenariusza. Z częstotliwości komunikatów o różnych awariach chmur można wywnioskować, że jest to zjawisko immanentne, więc wypadałoby na wypadek awarii mieć jakieś rozwiązanie zastępcze. Tak zrobiłby każdy, kto poważnie traktuje swoje źródło dochodów, ale jak widać panowie od BitBucket nie traktują poważnie swoich klientów, którzy płacą na ich rachunki za prąd, wodę i mieszkanie. Cieszę się, że nie jestem jednym z tych pechowców. Czy też może, mając na względzie historię awarii BB, frajerów.

Już nawet nie chodzi o to, że ktoś nie może się dobrać do swojego kodu na BB. Nie chodzi też o to, że spora część kodu F/OSS nie jest dostępna, to w końcu nie koniec świata. Chodzi o to, że ludzie nie biorą odpowiedzialności za to, co oferują innym za pieniądze. W razie problemów kryją się za gówniarskim "to nie my, to oni!" i nie są w stanie powiedzieć otwarcie, że nie umieją się uczyć nawet na swoich własnych błędach (o cudzych nie wspominając).

Każda awaria jest kosztowna. Mam nadzieję, że właściciele BB poczują to wreszcie na własnej skórze.

Nowe w Megiteam

Poładniało (choć to pewnie kwestia gustu) — to pierwsze, co się rzuca w oczy. Oprócz tego:

  • stałe plany zamiast luźnej konfiguracji, nadal z możliwością dokupienia dodatkowych zasobów
  • VPS-y i dedyki
  • faktury i wreszcie możliwość odliczenia VAT
  • wyższe ceny, niewiele, ale zawsze

Jestem więcej niż zadowolony z usług Megiteam.pl, więc przedłużę u nich abonament na kolejny rok, może w wersji wyższej niż obecna — djangohosting.ch ma fantastyczny support, ale ich serwery sprawiają wrażenie przeciążonych. Chyba skończy się na tym, że przeniosę serwisy do Megiteam, a tam zostawię jedynie jakieś playgroundy i sandboxy, bez publicznego ruchu.

Jeżeli ktoś z moich szanownych czytelników zechce wykupić sobie w Megiteam abonament na usługę hostingową, to uprzejmie proszę wpisać zgoda jako nazwę polecającego. Wpadnie mi parę punktów w programie partnerskim... ;)

Bo polecam z czystym sumieniem.

Wynoszę się z astera

Moi drodzy znajomi, zamieszanie, które wprowadził Aster ze swoim serwerem Jabbera skłoniło mnie do wyrejestrowania tam konta (rozleniwiłem się na starość). Kto chce nadal utrzymywać ze mną kontakt przez Jabbera, proszę używać mojego konta na gmailu — jarek kropka zgoda.

Apel o opamietanie

W związku z rozglądaniem się za drugim autem (żona też człowiek i ma prawo jeździć gdzie chce i ile chce), staram się zdobyć jak najwięcej informacji o potencjalnych kandydatach. Najlepszym miejscem do poszukiwań są prawdopodobnie internetowe fora klubów użytkowników interesujących nas marek i modeli, jest jednak pewne ale... Przytłaczająca większość tych forów nie pozwala na czytanie ich zawartości bez uprzedniej rejestracji! Tak, żeby poczytać o czymś trzeba się zarejestrować i to mnie powoli zaczyna doprowadzać do szału — rozważaliśmy zakup Hondy Civic VI generacji, ale żeby coś o tym aucie poczytać musiałem założyć sobie konto na forum Honda Civic FanKlub (nie linkuję, żeby im nie przysparzać sławy), potem był Opel Corsa i to samo, z Peugeotem 206 tak samo. Mam już konto na forum Ford Club Polska i na forum Peugeota 406 (ech, jednorożec...), ale przecież nie będę sobie zakładał kont na forach wszystkich marek i modeli, które biorę pod uwagę przed zakupem...

Wątpię, żeby ktokolwiek z administratorów to przeczytał, ale napiszę wyraźnie: ludzie, opamiętajcie się, to nie ma sensu!. Jeżeli komuś zależy na popularyzowaniu czegoś, to nie zamyka osobom postronnym dostępu do informacji o popularyzowanym przedmiocie! Oczywiście, jest jeszcze możliwość syndromu psa ogrodnika, ale nie wierzę, że chodzi o to, by specjalnie zamknąć ludziom dostęp do informacji...

Nie ma już Uncov.com

Serwis Uncov.com, do którego link swego czasu świecił w bocznym pasku tej strony, zakończył działalność. I to z hukiem — domena kieruje teraz do strony wyszukiwania pewnej osoby na Twitterze. Jak wyjaśniła mi osoba, którą powszechnie kojarzy się z Uncov.com, czyli Ted Dziuba, domena ta należała do jego wspólnika, z którym rozstał się w nieprzyjaznej atmosferze. Okres rejestracji domeny wygasł i ktoś ją kupił, ot, i cała historia...

Na szczęście, to nie jedyne miejsce, gdzie można doświadczyć ostrego języka Teda Dziuby: miłośnikom jego felietonów pozostaje jego blog i co 2 tygodnie artykuły w The Register, cokolwiek ugrzecznione, ale wciąż bezlitosne.

Koniec Last.fm?

Last.fm zapowiedziało wprowadzenie opłat za streaming audio we wszystkich krajach poza Niemcami, Wielką Brytanią i USA. Podobny ruch Pandory (a następnie zamknięcie jej dla użytkowników spoza USA) doprowadził do niemal całkowitego jej zniknięcia ze sceny.

Jak każdy odmawiam płacenia za coś, co do tej pory było free. Trudno, najwyżej nie będę słuchał ich radia — ściągnę sobie co trzeba skąd się da...

Magia zrozumiana

Jestem po kilku tygodniach dłubania aplikacji webowej przy użyciu zestawu narzędzi (Werkzeug, SQLAlchemy lub datastore, Jinja2, WTForms) zamiast Django. Zawsze uważałem Django za kawał świetnego softu, ale dopiero teraz doceniam to, na ile ramówka aplikacyjna ułatwia życie programisty, załatwiając masę rzeczy z kategorii boilerplate przy użyciu kawałka swojej magii.

Narzędziówka jest pozbawiona zupełnie magii. To surowy zestaw narzędzi (niektóre z nich, jak SQLAlchemy mają własną magię wewnętrzną do załatwiania swoich spraw) i żeby zagrały ze sobą w zgodnej orkiestrze i razem umożliwiły napisanie dobrego kodu aplikacji, trzeba napisać sporo rzeczy: procesory żądań (w Django nazywa się to middleware), procesory kontekstu, podsystem konfiguracyjny, skróty ułatwiające życie (jak render_to_response() czy funkcja do odwracania URL-i), podsystem autoryzacji. W Django to wszystko już jest, gotowe i zainstalowane, a użycie jest tylko kwestią podłączenia w konfiguracji lub nawet zaimportowania odpowiedniego modułu — i za sprawą magicznej różdżki masz sitemapę, masz feed RSS/Atom, masz bufor stron i masę innych drobiazgów, na napisanie których poświęciłbyś trochę czasu, bo trzeba to mieć, pomimo tego, że te wszystkie rzeczy nie są corem aplikacji. Łatwo jest to wszystko docenić: działające zręby bloga w Django (tego bloga) miałem po około 2 godzinach roboty (wpisy, etykiety, archiwum, feed z wpisów i sitemapa), a powtórzenie tego samego wyczynu z użyciem zestawu narzędzi zajęło mi ponad 6 godzin pracy, z czego co najmniej 3 spędziłem na użeraniu się z duperelami. Warto było, bo moja wiedza na temat działania aplikacji w środowisku WSGI jest teraz o wiele większa. I lepiej rozumiem bebechy Django.

Z drugiej strony nie można powiedzieć, żeby ta wyprawa miała jedynie edukacyjną wartość — dorobiłem się sporej ilości kodu narzędziowego, który może mi się kiedyś przydać. Zobaczyłem też, jak wydajna i oszczędna w wykorzystaniu zasobów może być mała aplikacja, jeżeli się ją rozsądnie napisze, dla porównania aplikacja tego bloga żre na megiteam.pl ~20MB pamięci rezydentnej, a moja reimplementacja przy użyciu zestawu narzędzi jedynie ~12MB — różnica jest kolosalna (nie wspominam już o tym, że jest o wiele szybsza, prawdopodobnie dzięki Jinja2). Przyszłością tego bloga jest właśnie reimplementacja przy użyciu zestawu narzędzi, głównie w celach oszczędnościowych.

Napisawszy tyle wypadałoby przejść do jakiejś konkluzji... Jak dla mnie to każdy kto robi w webie przy użyciu pythonowych ramówek (nie tylko Django, to się tyczy również Pylons i TurboGears w takim samym stopniu), powinien zrobić sobie taką krótką wycieczkę do źródeł. Będzie mógł wtedy dostrzec zarówno mocne jak i słabe strony używanej przez siebie ramówki, a przede wszystkim zrozumie, jak jej wszystkie komponenty współgrają ze sobą, tworząc całość, która tak bardzo ułatwia pracę.

Zrobiło się cicho

A to dlatego, że moje przemyślenia na temat technologii przeniosłem do technologicznej tuby tego serwisu, którą w ramach edukacji implementuję na Google AppEngine. Aplikacja, choć wciąż w trakcie rozwoju, powoli zyskuje kolejne funkcje (a ja przy okazji uczę się nowych rzeczy).

Vendor lock-in (na melodię "do no evil")

Dzisiejsze ogłoszenie zasad płatności za Google AppEngine wywołało burzę w małej szklaneczce, jaką jest środowisko ludzi robiących aplikacje na AppEngine:

  • część (wygląda mi to na większość) cieszy się z tego, że może płacić, w tym także z tego, że za 3 miesiące będzie płacić za to, co do tej pory miała za darmo;
  • część (mniejszość) nazywa to po imieniu: vendor lock-in (najpierw skuś, potem zmień zasady i zmuś do płacenia za to, co do tej pory było za darmo).

Wyliczenia przeprowadzane tu i ówdzie (głównie na liście AppEngine) wskazują, że nowe limity będą odczuwalne przez wszystkie co najmniej przeciętnie popularne serwisy, a koszt może być znaczący.

Wysiłek włożony w zrobienie aplikacji, którą można wyjąć z GAE i włożyć na normalny serwer może się opłacić. A już na pewno można przestać myśleć o przenoszeniu aplikacji z normalnej platformy na GAE — to się po prostu nie opłaci.

Na kolana, mięczaki

What happened to the next iteration of hackers? I blame generational pussification - things like the everybody-is-a-winner attitude and Coldplay are making our children soft. As the Twitter invader proves, it doesn't take much to be a "hacker" these days. Great fuckin' job, Mitnick. Give a kid a good asskicking and make him listen to Frank Zappa. He'll be able to dissect a stack frame. (Ted Dziuba)

Nie krępujcie się, formujcie swoje dzieci w duchu miękkiej super-akceptacji dla całego świata, a moja ZIZ nakopie wam i waszym dzieciom do tyłka. Już niedługo. :)

wMiastoWzięci.pl na (niejakim) zakręcie

W związku z nadciągającą zimą finansową w IT (wszyscy przepowiadają, że rok 2009 będzie ciężki, tak jak był 2000 — a ja nie mam powodu, żeby nie wierzyć), wMiastoWzięci.pl w najbliższym czasie pozostaną moim prywatnym projektem, częściowo (prawdopodobnie w całkiem sporym zakresie) edukacyjno-eksperymentalnym. Hostowany będzie tak, jak dotychczas, tzn. na najtańszej opcji na djangohosting.ch, więc w wypadku znaczącego pogorszenia wydajności (np. z powodu nagłego zainteresowania serwisem) niczego nie będę dokładał za pieniądze (procesy, pamięć, storage). Lepiej, żeby było to jasne już teraz.

Przez ten rok (co najmniej, bo może być i dłużej) zamierzam zrobić tam kilka rzeczy, ale bez ustalania jakiegoś sztywnego grafiku, bez liczenia wersji i określania terminów:

  • oceny zawartości;
  • personalizowane powiadomienia o zmianach w zawartości;
  • uproszczenie procesu dodawania wydarzeń;
  • ponowne przemyślenie architektury informacji, bo trochę się pogubiłem...;
  • przejście od wydarzeniocentryczności do miejscocentryczności;
  • reorganizacja zawartości wyświetlanej na stronie początkowej serwisu;
  • nowy wygląd, lepiej dopasowany do charakteru serwisu;
  • może jeszcze kilka drobiazgów...

Jak widać, nie ma tego wiele, ale też nie zamierzam spędzać nad tym serwisem wiele czasu — moja córka dorasta w szybkim tempie i wymaga coraz większej uwagi. Na tyle, na ile będę mógł poświęcić na niego czas, będę coś tam dłubał, ale na pewno nie będę urządzał wyścigu do funkcjonalności, ani nie będę śledził działań konkurencji tylko po to, żeby być na czasie, ani tym bardziej o krok dalej. Nowe funkcje się pojawią, błędy będą poprawiane, serwis będzie rósł — w oczekiwaniu na lepsze czasy.

Polecam: XP-Dev.com

Niedawno po prawej stronie pojawiło się kilka obrazków-linków. O ile dwóch z nich nie ma co opisywać, bo same się doskonale opisują, to link do XP-Dev.com wymaga kilku słów opisu (albo tylko tak mi się wydaje).

Jakiś czas temu chciałem się uniezależnić od mojego dostawcy hostingu w dziedzinie utrzymywania repozytorium z kodem tego serwisu (i paru innych przy okazji też). Przeszkadzało mi to, że współdzielenie dostępu do repozytorium polega na forwardowaniu portu przez SSH, jak dla mnie (i dla znajomych, którym chciałem dać dostęp do repozytorium) to mało wygodne. Zacząłem szukać miejsca, gdzie mógłbym sobie potrzymać mój nie-opensource kod, za darmo lub za niewielką opłatą (ale jak piszę niewielką, to naprawdę niewielką — €10 rocznie to była absolutnie nieprzekraczalna granica). Z serwisów za niewielką opłatą właściwie nie dało się niczego wybrać, zwłaszcza, że oferowały mniej, niż każdy z dwóch darmowych serwisów: Assembla i wspomniany wcześniej XP-Dev. Obejrzałem sobie plany w tych dwóch serwisach i o ile Assembla nie ograniczała ilości repozytoriów, to każde repozytorium miało mniejszy limit wielkości, na XP-Dev.com można było mieć 5 repozytoriów po 300MB każde (na Assembli dowolną ilość 200MB). Założyłem sobie konto na XP-Dev.com, poprosiłem o wgranie dumpów moich repozytoriów i gotowe.

Jak się parę tygodni później okazało, wybór był szczęśliwy — Assembla wprowadziła ograniczenie dla darmowych kont polegające na wymaganiu publicznego dostępu do repozytorium. Parę dni później właściciel XP-Dev.com zapowiedział, że nie zamierza wprowadzać takiego ograniczenia i wręcz zaprasza wygnańców z Assembli. Uch, upiekło mi się...

Od tamtej pory pojawiło się kilka udogodnień, z tych, które zanotowałem (bo mają dla mnie pewną wartość utylitarną):

  • unifikacja url-i serwisu i repozytorium;
  • możliwość samodzielnego wgrywania dumpów repozytorium i dumpowania istniejących repozytoriów;
  • zniesienie limitów rozmiaru poszczególnych repozytoriów i limitu ilości repozytoriów, teraz trzeba się tylko zmieścić w 1.5GB.

Jak dla mnie to co najmniej wystarczająco dużo. Jakby ktoś potrzebował, to są tam też jakieś dodatki typu wiki itp., ale nie ma obowiązku używania. I to mi się podoba.

Memcached to nie jest srebrna kula

Jak ze wszystkimi innymi rzeczami, tak i z memcached nie należy przesadzać. Bynajmniej nie chodzi mi o to, żeby ograniczyć jego używanie — nie ma najmniejszego powodu, żeby sobie odmawiać, to niezły kawałek softu, który dobrze wykonuje swoje zadanie (pewnie mógłby lepiej, ale daruję sobie dygresyjne wędrówki na dzisiaj). Według mnie problem jest natury psychologicznej, a u jego podłoża leżą pospołu lenistwo z ignorancją.

Dla zobrazowania sytuacji przytoczę pewną historię (tak, jak ja ją widziałem, bo nie dotyczyła ona mnie bezpośrednio). Pewien projekt już od swojego założenia miał być ściśle związany z memcache. Wiadomo było od początku, że celem przyspieszenia działania serwisu wiele danych będzie trzymanych na boku w cache, żeby zminimalizować ruch między aplikacją i bazą danych. Założenie rozsądne, ale szybko się okazało, że mocno idealistyczne. Memcache zaczął być traktowany jako panaceum na wszystkie problemy z wydajnością serwisu, obojętnie czy wynikały one ze skomplikowania struktury danych (które skutkuje wysokim obciążeniem bazy danych), czy z marnego algorytmu (nieważne, czy źle zaprojektowanego, czy źle zaimplementowanego). Jeżeli nie dało się czegoś zoptymalizować (czytaj: nikt nie umiał/nikomu się nie chciało/nikomu nie pozwolono marnować na to czasu), to komuś włączała się żaróweczka "o, wiem, wrzucę to do memkesza!", i wrzucał do memkesza. Potem trzeba było opracować metodę usuwania z cache zdezaktualizowanych wpisów. Potem okazywało się, że algorytm do kitu wrzuca do memcache dane do kitu, ale w związku z tym, że aplikacja musi mieć jakiekolwiek dane, obojętne czy prawidłowe czy nieprawidłowe, a w dodatku bez cache aplikacja działać w ogóle nie będzie, to po jakiejkolwiek zmianie algorytmu trzeba było ręcznie usuwać nieprawidłowe dane i trząść się, czy czasem nie usunie się za dużo albo za mało. A i tak do końca nie było pewności, czy po zrestartowaniu aplikacji nagle nie okaże się, że w najmniej oczekiwanym momencie aplikacja nie wysra pięćsetką, a wtedy pozostawał już tylko restart memcached, który, w dużym skrócie, skutkował ogólną apokalipsą (sesje użytkowników w piach, żadnych danych wspólnych przez jakiś czas i ogólnie przerwa w działaniu serwisu idzie w dzisiątki minut).

I tak w kółko, bo jak się okazuje, jest to praktyka powszechna. To znaczy, po tamtym razie widziałem to samo wiele, wiele razy. A jaka jest według mnie recepta? To proste:

  1. zoptymalizuj swój kod
  2. zoptymalizuj bazę danych (słyszałeś o indeksach, prawda?)
  3. to, czego się nie da załatwić optymalizacją, trzymaj w cache

Dokładnie w takiej kolejności.

No future

Często widzę pytania typu jakiego frameworka mam się nauczyć? (albo jaki język ma przyszłość?), kto chce się przekonać, niech spojrzy na Stack Overflow. Zadają je najczęściej newbies, albo jeszcze się uczący albo zaraz po szkole, chcąc się wygodnie ustawić na przewidywane 8-10 lat pracy jako software developer (potem i tak pójdą w managery i będzie im wszystko jedno). Najczęściej dostają kilka-kilkanaście odpowiedzi, sumarycznie dających obraz tego, co jest teraz hot i za czym doświadczeni developerzy sikają w majty: Rails, Merb, Django, Pylons, Werkzeug, erlang, haskell... Trudno nazwać te wszystkie odpowiedzi błędnymi, bo prawdopodobnie w krótkiej perspektywie (2 lata? 3 lata?) to wszystko będzie się sprawdzało. Ale co potem?

A potem wszystkie te odpowiedzi będzie można sobie potłuc o kant zbolałej dupy. Wszystkie te frameworki odejdą w zapomnienie, a języki staną się niszowe (albo nigdy z niszy nie wyjdą). Patrząc na aplikacje, których używają miliony aż dziw, że nikt nie podaje odpowiedzi, która powinna nasująć się sama: "synku, ucz się JavaScript-u". A co to są za aplikacje, te których używają miliony? Nie Word, nie Excel, nawet nie Firefox ani Internet Explorer (paradoks, ale przeglądarka jest taką quasi-aplikacją, jest raczej wirtualnym środowiskiem aplikacyjnym — niektórzy, jak Joel Spolsky, uważają przeglądarki za coś, co zabija tradycyjne desktopy). To GMail, Google Reader, Google Documents, Picasa i pozostałe z koszyczka Google™ (Yahoo!™ nie ma aż takich ambicji, po kupieniu Flickr-a nie rozpoczęło globalnej ekspansji w celu przejęcia władzy nad internetem). Każda z nich jest od dna aż do szczytu napakowana JavaScriptem, co czasem daje efekt taki, że użytkownicy... nie umieją już posługiwać się desktopowymi aplikacjami, które były pierwowzorami aplikacji webowych Google. Uczeń przerósł mistrza używając technologii, która miała stworzyć w internecie namiastkę interaktywności znanej z aplikacji desktopowych. Być może za kilka lat jedynymi płatnymi aplikacjami desktopowymi będą... edytory programistyczne. Bo innych aplikacji w ogóle nie będzie.

Idea webowego desktopu nie jest nowa. Sięgając pamięcią do zamierzchłych lat 90-tych XX wieku niektórzy mogą sobie przypomnieć idee komputerów sieciowych, pozbawionych twardych dysków, będących jedynie stacjami roboczymi z wypasionymi kartami graficznymi (do renderowania stron WWW w oknie przeglądarki). Jak przez mgłę majaczy mi, że nawet poważne firmy, jak np. Sun Microsystems, maczały palce w realizacji tych idei. Dzisiejsze netbooki (z małymi dyskami SSD, procesorem Intel® Atom™, napędzane specjalnie skrojonymi dystrybucjami linuksa) są pokłosiem i ewolucyjnym rozwinięciem tej idei — to nie maszynka desktopowa ma dysponować przerażającą mocą obliczeniową, tylko maszyna, na której jest uruchomiona aplikacja. Stacji roboczej wystarczy tyle mocy, żeby wyrenderowała stronę w przeglądarce.

Za 5 lat obecne ramówki aplikacyjne i języki będą zjawiskiem zanikającym, a tym, co będzie napędzało aplikacje będzie ogromne morze JavaScriptu. I o ile wiem, nie jestem odosobniony w tym poglądzie...

Pownce is shutting down

Nie używałem zanadto, ale miałem sentyment, bo serwis był zrobiony w Django. A teraz przejęło ich Six Apart i zabawa się skończyła. To chyba normalne w interwebie, ale żal jakiś jest...

Mam pomysł na spotkanie towarzyskie

Chętnie spotkałbym się z tymi programistami Delphi, którzy robią (zawodowo lub OMC zawodowo) w Pythonie. Właśnie nie dawno zobaczyłem posta Fiedzi na django-users, parę innych nazwisk też mi się wydaje znajomych...

Markdown dla grzecznych

Markdown to fajny wynalazek, ale zaskakująco niebezpieczny i to w miejscu, którego zwykle się nie spodziewamy... Wspomniał o tym jakiś czas temu Jeff Atwood przy okazji jakichś innych wynurzeń. Utkwiło mi to bardzo mocno w pamięci, pewnie dlatego, że kiedyś zdarzyło mi się popełnić aplikację podatną na XSS. Tak, nieumiejętnie (nazwałbym to bezmyślnie, ale nie jest moim zamiarem itd.) zastosowany markdown wystawi na niebezpieczeństwo także i Twój serwis. Zastanawiam się nad tym, jak zastosować do zmyślnie, bo chciałbym użytkownikom wMiastoWzięci.pl dać do ręki coś, co im się przyda, a jednocześnie nie pozwoli im na wyrządzenie żadnych szkód (obojętne, umyślnie czy nieumyślnie).

Pewnym rozwiązaniem mogłoby być oczyszczenie tekstu źródłowego przed zapuszczeniem na nim filtra markdown — ale to trochę przypomina wylewanie dziecka z kąpielą, bo wyłącza część użyteczności markdown. Z drugiej jednak strony, rozwiązanie Jeffa A. (czyszczenie tylko części HTML) nie wydaje mi się rozsądne, przede wszystkim z powodu ogromnego skomplikowania zagadnienia. Czyżby była to sytuacja bez wyjścia?

Lighty na ratunek ortografii

Zdarzyło się tak, że zrobiłem literówkę w urlconfie i stało się, Google zaindeksowało mi stronę pod błędnym url-em. O ja nieszczęsna, ale przecież zdarza się w najlepszej rodzinie. Trzeba było zmontować jakiegoś redirecta. Co prawda Django ma jakąś swoją aplikację do redirectów (django.contrib.redirects), ale przecież nie o to chodzi, żeby Django robiło wszystko, skoro to taka drobnostka — przecież każdy serwer http ma coś do robienia redirectów, Lighttpd nie jest żadnym wyjątkiem. Trochę nad tym posiedziałem (bo orłem z wyrażeń regularnych to ja nie jestem...) i działa jak złoto:

$HTTP["host"] =~ "(^|\.)wmiastowzieci\.pl$" {
    url.redirect = (
        "/miajsca/$" => "/miejsca/",
    )
}

Żeby było ciekawiej (choć to babol i w nowszym lighty będzie zmienione), lighty w tym momencie wysyła 301 (czyli permanent redirect) co akurat w moim przypadku robi dobrze, bo nie zamierzam więcej popełniać tej literówki. :)

Czas się ujawnić

To uczucie nieporównywalne z niczym: budujesz aplikację przez kilka tygodni lub miesięcu i przez cały czas zastanawiasz się czy ktoś będzie tego używał?. W takiej niepewności trwasz dopóki nie zauważysz, że jednak ktoś zdecydował się jej użyć, a wtedy... No i wtedy właśnie przychodzi ten strzał adrenaliny, który mogę porównać tylko z paroma rzeczami (niestety, nie mogę napisać, co to za rzeczy, bo każda z nich jest albo szkodliwa albo zakazana przez prawo — tę stronę przecież czytują dzieci...). Dziś rano spojrzałem w panel administracyjny jednego z moich prywatnych serwisów i poczułem właśnie TO.

Pomimo trzymania aplikacji w niemal całkowitej tajemnicy do czasu ukończenia prac (wiedziała o niej tylko moja żona i Google, o ile ktoś wiedział czego ma szukać), ktoś zajrzał na wMiastoWzięci.pl i dodał wydarzenie (choćby z tego powodu warte uwiecznienia). Nie będę tego ukrywał dłużej, to mój serwis. Wciąż jeszcze jest szlifowany, wciąż nie wszystko w nim działa, ale jak widać komuś to nie przeszkadzało. Co nie działa:

  • zgłaszanie obiektów (wydarzenia, zdjęcia, recenzje) do moderacji
  • komentarze do wydarzeń i miejsc
  • przeglądanie wielu etykiet na raz

Dla spragnionych informacji technicznych: serwis działa na Django-trunk, baza to MySQL 5.0 (z backendem MyISAM), deployment na FastCGI/lighttpd.

A skoro już poszło w świat, to skończył się luźny czas developmentu w modelu langsam, langsam i trzeba w szybkim tempie dorobić brakujące funkcje serwisu. ;)

Zagadka rozwiązana

Gra, która zostanie ożywiona (stąd "Revival", i trochę z mojego upodobania do pewnego utworu The Soulsavers), to Gwiezdny Kupiec, wydany dawno temu przez nieistniejącą już firmę Encore. Ktoś kiedyś zrobił wersję interwebową tej gry, ale serwis już dawno zniknął z sieci — gdyby nie ten fakt nawet nie próbowałbym myśleć o odtworzeniu tej gry. Gratuluję wszystkim, którzy odgadli, a tych, co nie odgadli pocieszam, że to dość niszowe zagadnienie. ;)

Co do współpracy... Kilka osób się odezwało, dziękuję za zainteresowanie. Wybrańcem losu został Franek Goliński, który użył jokera, bo pracuje ze mną i mamy bezpośredni kontakt przez 8 godzin dziennie (siedzimy może 3 metry od siebie...).

Szczerze mówiąc, nie spodziewałem się w ogóle odzewu, a tu proszę... Zaskoczenie.

Revival

Poszukuję współpracownika do odtworzenia pewnej kultowej gry planszowej w realiach interwebu (Django 1.x + jQuery), może być na AppEngine, ale nie musi. Projekt może być Open Source, ale nie musi (bo w sumie kogo to obchodzi...). Wskazany wiek > 30 lat (młodsi raczej nie będą mieli odpowiedniego szacunku dla tej gry ;)). Gra jest turową strategią, więc łatwo nie będzie.

Kontakt tam gdzie zawsze - Jarek kropka Zgoda na usłudze pocztowej Google®. Proszę, tylko poważne propozycje...

[edit]: kilka osób mnie już o to pytało, nie chodzi o grę Revival (nawet nie wiem, co to takiego).

Hacknot zniknął z sieci

Z ogromną przykrością i z prawdziwym żalem odkryłem, że Hacknot.info (nie linkuję, bo domenę przejęli już squatterzy) jeden z najciekawszych serwisów z esejami dotyczącymi produkcji oprogramowania zniknął z sieci. Zniknęła masa fantastycznych artukułów (często bardzo kontrowersyjnych, ale zawsze ciekawych i pozwalających przemyśleć poważnie różne sprawy). Pozostała książka (do ściągnięcia za darmo w postaci PDF lub do kupienia za parę €), ale zawiera ona tylko wybór esejów Eda Johnsona.

Szkoda, naprawdę wielka szkoda. Z drugiej strony, nie mogę uwierzyć w to, że cała zawartość tego serwisu zniknęła bez śladu (przecież była na CC!), więc przez cały czas można mieć jakąś nadzieję, że gdzieś uchowała się lokalna kopia...

Krewni i znajomi królika

Wszyscy zaangażowani w przedsięwzięcie już roztrąbili wieści o uruchomieniu Django.pl, więc przyszedł czas na niezaangażowanych. Zajrzałem i... nic. Pomijając tłumaczenie tego, co jest w oryginalnym serwisie, to tam po prostu nie ma niczego nowego. Nie wiem, czego się spodziewałem. Może czegoś bardziej lokalnego? Czegoś, czego w oryginalnym serwisie nie ma? Polskiej specyfiki?

E, jak zwykle się czepiam. Fajnie, że serwis wystartował, teraz trzeba go rozwinąć w coś unikalnego (i pilnować, żeby nie poszedł w maliny). Tłumaczenie przyda się początkującym, a fajnie jest też mieć coś lokalnego.

Pomoc z niespodziewajki

Jakkolwiek dziwne może się wydać to stwierdzenie, Google jest świetnym narzędziem do testowania aplikacji webowych. A właściwie to jego bot. Nic się przed nim nie ukryje, spróbuje pobrać dokument spod każdego URL-a, na jaki tylko trafi, posłusznie raportując każdą 500 i 404 w GWT. A przy okazji mając włączone raportowanie mailem można szybko zareagować na problem. Nie policzę, ile błędów wykrył Googlowy bot w ciągu kilku ostatnich dni, odkąd moja aplikacja jest na etapie testów wewnętrznych.

Dziękujemy ci, Google. :)

Support ratuje wszystko

Dzisiaj pojawił się problem z pocztą w jednym z moich serwisów na djangohosting.ch. Część serwerów pocztowych odrzucało przesyłki, do części transfer był w dziwny sposób opóźniony, a dla równowagi część serwerów nie zgłaszała najmniejszych problemów. W końcu udało mi się dowiedzieć, że to coś związane z SPF, jaki ma moja domena. I rzeczywiście, po usunięciu rekordu TXT z danymi SPF maile zaczęły docierać do wszystkich. Co prawda w kilku serwisach od razu lądowały w folderze spam, ale lepsze to, niż zwrotka. Zgłosiłem problem wczesnym popołudniem, ale nie biłem piany, bo serwis jest w trakcie wewnętrznych testów, więc jest to właśnie ten czas, kiedy takie rzeczy mają prawo się ujawnić. Właściwie do niczego nie doszliśmy, ale gdy wróciłem do domu i z ciekawości spojrzałem, jak wygląda automatycznie tworzony rekord SPF, to coś mi się nie zgadzało: podobno miał wyglądać inaczej... O 20:29 zgłosiłem nieprawidłowość (jako komentarz do zamkniętego już ticketu, z prośbą o wyjaśnienie, czy te wpisy są ekwiwalentne), a o 20:34 sprawa była załatwiona, instalator domen rzeczywiście dodawał nieprawidłowy wpis SPF.

Fantastyczny support to jest coś, co rekompensuje wszystkie błędy MySQLdb, z którymi muszę się tam zmagać. Gdyby ktoś się zastanawiał, gdzie tanio postawić aplikacyjkę w Django, to polecam djangohosting.ch.

I hate this feeling

Nienawidzę tego uczucia zazdrości, kiedy mając w 50% zaawansowaną aplikację widzę ogłoszenie, że ktoś zrobił dokładnie to, nad czym właśnie ślęczę. Jeszcze bardziej nienawidzę tego uczucia zazdrości, gdy widzę, że moja aplikacja nie jest równie dobra, jak tamta. Wszystko w niej wtedy wydaje się lepsze — przepływ sterowania, architektura informacji, wygląd, dosłownie wszystko.

10 minut i jednego papierosa później przeklinam bardzo brzydko, siadam z kartką papieru i zaczynam kreślić plan pokonania konkurencji. Wygram, k**wa, wygram!

Szatan atakuje ponownie

Od For fun and profit

Framework to nie hop-siup...

Przyglądając się WebOb i dołączonym do niego przykładom można wreszcie zobaczyć, jak dużą rzeczą są ramówki webowe. O ile WebOb dostarcza podstawy do zbudowania własnej ramówki, to porównanie tej podstawy z gotowym frameworkiem, np. Django, uświadamia, jak wiele rzeczy trzeba napisać, żeby wszystko razem zagrało. Oczywiście, zazwyczaj używa się tylko pewnej części ramówki i wydaje się, że napisanie własnej spowoduje, że będzie szybsza, lżejsza i w ogóle lepsza, bo przecież pozbawiona kodu (a więc i funkcji), którego się i tak nie używa. Ale to, co pozostaje, to i tak ogromna ilość kodu i ogromna ilość funkcji, które trzeba zaimplementować. I to zaimplementować poprawnie, przewidując sytuacje niezwykłe (dziwnego klienta, któremu się coś pieprzy z HTTP i czegoś-tam zapomina wysłać albo nie rozumie) i awaryjne.

Ja w każdym razie dziękuję, zostanę przy cudzej robocie. :)

Moja muzyka od paru miesięcy

Postanowiłem dać upust mojemu upodobaniu muzycznemu i w tym miejscu zarekomendować pewnego artystę (a właściwie pewną artystkę). Otóż, kilka miesięcy temu szukając ciekawego industrialu dzięki last.fm trafiłem na Android Lust. No i zawładnęło mną na dobre... Piękny głos Shikhee, kiedy trzeba melancholijny, a kiedy trzeba drapieżny i ostry, rytm pulsujący kiedy trzeba, a kiedy trzeba połamany, kompozycje po prostu ładne. Nie chcę więcej. :)

Wyjeżdżając na wakacje nie zapomnij komputera

Jak się okazuje, Polska pełna jest niezabezpieczonych sieci WiFi. Wystarczy włączyć komputer, a kilka natychmiast się znajdzie. A jak nie, to trzeba przesiąć się o jedną-dwie ławki dalej.

Znikam

Dziś znikam z horyzontu internetu na 10-11 dni — wyjeżdżamy nad morze i nie zamierzam tam niczego kombinować z dostępem do internetu, po prostu nie ma.

Wracamy 11 lub 12 sierpnia i liczę na to, że internet będzie tu jeszcze. ;)

Pointless

Co jakiś czas zdarza mi się dostać od kogoś znajomego zaproszenie do jakiegoś serwisu społecznościowego (Plaxo, GoldenLine, Facebook, MySpace itd.). Z ciekawości zwykle się rejestruję, przeglądam co tam można dobrego znaleźć i w przytłaczającej większości przypadków rezygnuję z dalszego aktywnego uczestnictwa, bo niczego interesującego tam nie znajduję. W każdym z nich jest to samo: jakieś szorty w stylu Twittera, jakieś forum, jakieś klany czy grupy, jakieś powiązania między online identities (bo przecież nie ludźmi) i właściwie żadnej wartości dodanej. Klon klona klonem pogania, w dodatku zwykle klon serwisu dla półanalfabetycznych nastolatek.

Na tym tle wyróżnia się chyba jedynie Last.fm, bo przynajmniej jest tam jakaś unikalna wartość dodana (rekomendacje). Do niedawna dość często zaglądałem również na LinkedIn żeby dowiedzieć się, co teraz porabiają moi znajomi z poprzedniej pracy, ale przestałem, gdy pożal-się-Boże rekruterzy zaczęli wykorzystywać go do masowego łowienia jeleni. Inaczej nie można nazwać procederu namiętnego proponowania mi pracy w Javie pomimo tego, że mam wyraźnie napisane w profilu, że nie interesuje mnie praca w tym środowisku i odrzucę każdą ofertę choćby wirtualnie związaną z taką pracą. Z tego wynika, że łowcy jeleni nie zaglądają do profili użytkowników przed wysłaniem im oferty pracy, co dyskwalifikuje zarówno łowców, jak i ich oferty, a użyteczność samego serwisu stawia pod wielkim znakiem zapytania.

Albo jestem za stary na taki interweb, albo ten interweb się zrobił mniej użyteczny (nawet pod kątem rozrywkowym).

We're at ALPHA, man!

Django doszło z numerkiem do 1.0-alpha, co oznacza, że wszystko jest na dobrej drodze do dotrzymania obiecanego terminu wydania 1.0! Internet ma wreszcie szansę stać się cokolwiek przyjemniejszym miejscem (od strony programistycznej).

A ja siadam ponownie do sprzątania po rewolucji, jaką było dołączenie NFA do trunka...

Skaluj się, małpo!

Hehe... Widziałem już takie teksty, że niby żeby myśleć o skalowaniu, trzeba mieć po co się skalować, względnie żeby skalowanie zostawić na później, gdy już będzie potrzebne. Niejaki Ted Dziuba dał to po raz kolejny, tym razem dosadnie i z werwą.

Słyszysz? Przestań pieprzyć o skalowalności, i tak nikt nie będzie używał twojej aplikacji. No.

Zmiana planów w ostatniej chwili

Dosłownie w ostatniej chwili zdecydowałem się na zmianę dostawcy hostingu na djangohosting.ch, pomimo że byłem zdecydowany na coś innego. Po sugestii Thomasa (dzięki!) przyjrzałem się usłudze dokładniej i postanowiłem dać szansę. Wykupiłem najtańszą opcję, wypróbowałem one-click-django-installer i oczywiście zameldowałem się po SSH. Już pierwsze pół godziny sesji przekonało mnie, że jest tam o wiele przyjemniej niż na Alwaysdata — nie ma żadnych myków z przestawianiem $HOME, no i zwiększanie opcji jest bardziej granularne (oddzielnie procesy, porty, pamięć i przestrzeń dyskowa), a cała infrastruktura w dużej mierze przypomina to, co jest na MegiTeam.pl, z paroma udogodnieniami:

  • można uruchomić serwer developerski django i w razie problemów mieć dostęp do pełnego tracebacka;
  • pełna kontrola nad uruchamianiem FastCGI;
  • łatwiejszy dostęp do logów Lighttpd (chociaż jest w nich równie mało, jak w logach nginxa na megiteam).

Ogólnie wygląda to bardzo dobrze, a przy tym jest trochę taniej.

Zdecydowałem się na dostawcę

To był tydzień pełen przemyśleń, ale w końcu doszedłem do jakichś wniosków. Mój najbliższy projekt będę hostował na Alwaysdata. Co prawda całość serwisu jest po francusku, ale jakoś daję sobie z tym radę.

Ujęło mnie to, że jest:

  • tanio (€ 6 za miesiąc w najtańszej opcji);
  • dobry support na forum (po angielsku!);
  • dość duża wolność, jak na shared plan;
  • krótki ping, serwery stoją w OVH w Roubaix (Francja).

W związku z małą ilością dostępnego miejsca na dysku, będę musiał media i uploady na S3, ale nie powinno być to jakoś szczególnie uciążliwe.

Konkurent (djangohosting.ch) przegrał głównie przez zerowy wybór w dziedzinie bazy danych (tylko MySQL, bez PostgreSQL), ale nie była to przegrana autorytatywna. Dam mu szansę następnym razem. ;)

Wybierz sobie dostawcę

A tymczasem wybór dostawcy hostingu pod Django jest zaskakująco mały, o ile ktoś celuje w użytkowników z Polski, a przy tym nie dysponuje kwotą wystarczającą do wykupienia sobie dedyka w Hetznerze.

Jest za Atlantykiem kilka firm, które chętnie przytulą większą lub mniejszą aplikację w Django za bardzo skromną kwotę, ale te miejsca mnie nie interesują. Ping po 200ms to nie jest coś, na co chciałbym narażać moich klientów. Na Ukrainie też jest pewna firma, która chętnie pohostuje aplikację za niewielkie pieniądze, ale na Ukrainę pingi z Polski lecą wolniej, niż do Francji, bo pakiety muszą zahaczyć o Frankfurt. Mili Szwajcarzy hostują się w Hetznerze, więc pingi do nich są co najmniej znośne, podobnie jak do Francuzów (ci z kolei się hostują w OVH). W Polsce mamy chyba tylko MegiTeam i ITL, ale ich ceny są zupełnie nie na miarę moich możliwości (przynajmniej o ile chodzi o cokolwiek więcej niż ten blog). W efekcie wybór jest między Francuzami a Szwajcarami, a każda z tych ofert ma znaczące niedobory (choćby w porównaniu do WebFaction).

Mam jeszcze 2 tygodnie na podjęcie decyzji.

Cierpię

Po raz kolejny cierpię, jak za każdym razem, gdy muszę zmontować jakiś layout dla serwisu. W tej dziedzinie mam dwie lewe ręce i zezowate oko, więc staram się (przynajmniej na początku) znaleźć coś gotowego. I ciągle mam ten sam problem — szablony które udaje mi się znaleźć mają w większości ustaloną szerokość circa about 800px, czasem pomijalnie większą. To jest rzecz, która dyga mnie za każdym razem, jak potrzebuję wygrzebać jakiś gotowy szablon: przytłaczająca większość szablonów jest robiona na fixed width, przez co masa przestrzeni się marnuje. Nie wspominając o tym, że wszystkie wyglądają jak odbite z jednej matrycy z niewielkimi zmianami.

Nie chce mi się już robić we webie.

jQuery mi się podoba

Po raz kolejny zastrzegam: to nie jest miłość (bo miłość może być tylko jedna). Ale jQuery mi się podoba.

Dzisiaj miałem zrobić taki pokręcony formularz z trzema select-ami, gdzie środkowy przyjmuje elementy z dwóch naokoło niego na kliknięcie. Biorąc pod uwagę moją niechęć (i co tu dużo ukrywać, nieznajomość też) do JavaScriptu, planowałem sobie to na co najmniej dzień roboty, a najprawdopodobniej półtora. Tymczasem usiadłem do roboty około 10, a o 12 miałem już to zrobione. 35 linijek kodu i żadnego znużenia. Więcej takich ułatwiaczy poproszę.

JavaScript może czuć się przeproszony

Nigdy nie lubiłem JavaScriptu. Syntaktycznie mi się ten język nie podobał, jego idea wydawała mi się poroniona (co najmniej), a różnice w implementacjach przez różne platformy zwyczajnie dyskredytujące. Tym niemniej zapoznałem się z nim przynajmniej na tyle, żeby znać go z widzenia. Ogólnie konieczność pisania kodu w JavaScripcie napawała mnie obrzydzeniem.

Do niedawna. Bo niedawno wypatrzyłem jQuery i całe moje podejście do JavaScriptu zmienniło się diametralnie. Miłością nie zapałałem (bo miłość może być tylko jedna), ale polubiłem JavaScript. Dziękujemy Ci, jQuery!

Tak łatwo to jeszcze nie było

Znalazłem kilka dni temu samouczek pisania własnych ramówek webowych w Pythonie w oparciu o WSGI i bibliotekę WebOb. Tak łatwo to chyba jeszcze nie było...

Na szczęście minęły czasy pączkujących ramówek (w tempie dwóch tygodniowo, strach było otworzyć lodówkę), ale może takie samouczki pokażą pretendentom, co ich czeka od strony kodu. Bo tego, co ich czeka od strony użytkowników to się nie da opisać żadnymi słowami. ;)

Gówniażeria

Co jakiś czas na pl.comp.lang.python pojawiają się ogłoszenia o pracy dla programistów w Pythonie. Abstrahując od dyskusyjnej właściwości tej grupy dla wysyłania ogłoszeń o pracy (niby jest pl.praca.oferowana, ale ogłoszeń o pracy dla Pythoniarzy nie jest aż tak wiele, więc ma to pewien walor...), to reakcje na takie ogłoszenia doprowadzają mnie do białej gorączki.

Przykład z ostatnich dni, pewna firma z Wrocławia zamieściła ogłoszenie o pracy. Napisali czym się zajmują, czego oczekują i tradycyjnie enigmatycznie co oferują. I od razu zaczęło się wydziwianie: a to że polszczyzna odbiega od wzorca metra prof. Miodka, a to że znowu nie podali proponowanych zarobków, a to że wymagają bardzo dobrej znajomości biblioteki standardowej. Takie pitu-pitu, żeby sobie tylko popyszczyć. Dużo osób narzeka, że gdzie indziej pracodawcy w ofercie podają kwoty, ale nikt jakoś nie zauważa, że dotyczy to ofert zamieszczanych w serwisach jobsowych, a nie w usenecie. I pewnie aby dopełnić obrazu nikt się nie pofatygował, żeby popatrzeć jak gdzie indziej wyglądają reakcje na takie ogłoszenia. Podpowiem — odpowiedzią jest milczenie.

Kalkulator w dłoń i liczymy

Osłabiający się wciąż dolar sprawił, że postanowiłem sprawdzić, czy MegiTeam nadal jest konkurencją dla WebFaction, przynajmniej jeżeli chodzi o cenę. Kalkulator w dłoń i liczymy.

Ponieważ MegiTeam nie ma opcji płatności miesięcznej, policzymy dla okresów 3, 6 i 12 miesięcy, stosując wszystkie podstawowe zniżki i porównując plany taryfowe, które sobie odpowiadają. W przypadku WebFaction będzie to "Shared 1" (80MB RAM, 600GB transferu miesięcznie, 10GB przestrzeni dyskowej), z uwzględnieniem zniżek za przedpłacenie. W przypadku MegiTeam, które nie oferuje aż takiego transferu, użyta będzie maksymalna wielkość 50GB transferu miesięcznie. Ceny w USD zostaną przeliczone według kursu średniego NBP z dzisiaj.

3 miesiące

WebFaction: 3 * $9.50 * 1.175 (17.5% VAT) = $33.49, czyli 73.83 zł

MegiTeam: 139.00 zł

6 miesięcy

WebFaction: 6 * $9.50 * 1.175 (17.5% VAT) = $66.98, czyli 147.65 zł

MegiTeam: 269.00 zł

12 miesięcy

WebFaction: 12 * $8.50 * 1.175 (17.5% VAT) = $119.85, czyli 264.20 zł

MegiTeam: 521.00 zł

Jak widać, przy rocznym okresie rozliczeniowym MegiTeam jest dwukrotnie droższe od WebFaction. Jeżeli do października nie nastąpi jakaś katastrofa na rynku walutowym, to się przeniosę z hostingiem za ocean. Może nie będzie aż tak strasznie wolniej...

Po raz kolejny porażka

Nie pamiętam już ile razy przysiadałem (w celach czysto edukacyjnych, aby zrozumieć jak to działa) do zrobienia sobie wielokolumnowego układu dokumentu HTML, z kilkoma wymaganiami, które zdają się obecnie wykluczać:

  • kolumna główna o szerokości względnej, dopasowującej się do wielkości okna przeglądarki;
  • kolumny boczne o stałej szerokości, wyrażonej w jednostkach em;
  • kolumna główna zdefiniowana w kodzie HTML jako pierwsza;
  • bez gremlinów w typie poziomego paska przewijania w IE6;
  • i jak najmniej boilerplate (niestrukturalnych div-ów).

Nie ma tego wiele. Co jakiś czas przeglądam to, co znajduje mi Google, ale wciąż powtarzają się te same triki: a to kolumny boczne trzeba definiować jako pierwsze, a to nie da się ustalić ich szerokości, a to znowu coś innego. A jeżeli znajduję gdzieś gotowy, działający szablon, to jego kod jest tak pogmatwany, że tylko łapię się za głowę.

Jak dla mnie, dowodzi to tylko jednego: CSS, choćby nie wiem jak był użyteczny w innych dziedzinach, w obecnej postaci do tworzenia układów stron się nie nadaje. Gdy tylko chce się wyjść poza ustawianie wielkości czcionki, obramowania elementu czy koloru tła, okazuje się, że używanie do tego celu CSS przypomina dokręcanie śrubek przy użyciu łyżki. Ktoś mógłby argumentować, że web to nie gazeta i kolumny są wbrew naturze WWW, ale w takim razie oznaczałoby to tylko jedno: że WWW nie nadaje się do użycia sterowanego zapotrzebowaniem. Bo ewidentnie potrzeba dzielenia treści na kolumny istnieje, a wręcz ze zwiększaniem się rozdzielczości monitorów ta potrzeba staje się coraz bardziej naoczna.

Więc co? Flash? Dopiero Flash to nie jest web (gdzie tu dokument, połączony z innymi dokumentami systemem dowiązań?). Czekam od kilku lat na rozwiązanie tego problemu w sposób kompleksowy, pewnie będę czekał jeszcze długo, i wszystko wskazuje na to, że się nie doczekam.

Nie mam wizji na AppEngine

Dostałem to konto i po całym weekendzie zastanawiania się nie umiem sobie wyobrazić aplikacji, którą mógłbym napisać i odpalić na AppEngine. Ograniczenia są cokolwiek duże, ale sama perspektywa jest przez cały czas kusząca. Dam sobie jeszcze tydzień na przemyślenie, czy w ogóle w to brnąć.

Przez cały czas mam przeczucie, że to jest coś, co daje duże możliwości.

Got it, gonna try it over the weekend

Thanks for signing up to try Google App Engine! Your account has been activated, so you can begin building applications!

No to zobaczymy, co się z tego da wyciągnąć... Mam pod ręką kilka eksperymentalnych projektów, któryś z nich zląduje na AppEngine.

Nic za darmo

W dzień-dwa po tym, jak Google ujawniło swoje AppEngine, firma Joyent, która sprzedaje (dość tanio) wirtualki na OpenSolarisie, postanowiła udostępnić swoją infrastrukturę bezpłatnie (co nie znaczy za darmo, ale po kolei) pod projekty w Pythonie, które mogą się pochwalić odpowiednio dużym ruchem. Z wielkimi fanfarami i używając biblijnego słownictwa ogłosili program, który nazwali (a jakże) Garden of Eden.

Haczyk jest taki, że chcą... nielimitowanego dostępu do danych klientów tak hostowanych serwisów. Imiona, nazwiska, adresy, telefony, numery faksów i cały ten szpej. Warto? Owszem warto... zastanowić się, co ważniejsze.

No i chyba mnie ominęło

Wszystko wskazuje na to, że moje zgłoszenie do testowania Google AppEngine nie zostało wylosowane, 10000 kont zostało rozdanych, a mnie zostało czekanie na następny batch i ćwiczenie na lokalnym dev serwerze. Znajomy zaproponował, że da mi jedną ze swoich trzech przydziałowych aplikacji, żebym mógł sobie potestować, więc pewnie nie będzie to trzening tak całkiem na sucho...

W każdym razie już widać, że o ile z Django na AppEngine zostaje bardzo dużo, to modeli używać trzeba tych dostarczanych przez Google. Nie minęło wiele czasu, a już pojawiły się plany rozszerzenia zaplecza bazodanowego Django o obsługę API przechowywania danych na AppEngine. Może to zaowocować szybszym merge odgałęzienia queryset-refactor do głównej gałęzi rozwojowej Django.

W obecnej formie na AppEngine nie wszystko jest zaimplementowane (nie ma np. M2M), z niektórych rzeczy trzeba zrezygnować, jak z interfejsu administracyjnego, czy z djangowego mechanizmu sesji, ale i tak jest to na tyle ciekawe, żeby chcieć dostać sztukę dla dokładniejszego przyjrzenia się. :)

Hot! (znowu się spóźniłem)

Google wystrzeliło z nowym pomysłem — AppEngine to nowy (i z opisu wynika, że rewolucyjny) hosting aplikacji webowych w ścisłej integracji z usługami Google, na razie przede wszystkim w Pythonie. W domyślnej instalacji jest Django 0.96.1, ale można też wziąć sobie wersję z SVN. Na razie trochę niejasne jest, w jaki sposób połączyć implementację modeli by Django z API, którego używania wymaga Google, ale sądzę, że wszystko się wyjaśni wkrótce.

I jak zwykle się spóźniłem z zapisaniem, trafiłem na waitlistę...

Nowości z frontu walki z Akismet

Coś wygląda na nieźle spieprzone w usłudze sprawdzania komentarzy przez Akismet — podanie w komentarzu linku do strony na Grupach Google (obojętne, dyskusje czy pliki), zamiast spodziewanego "true" lub "false" zwraca "" (pusty ciąg znaków). Na razie nikt nie zwrócił uwagi na takie zachowanie Akismet, ale ja się zacząłem rozglądać za czymś innym. Na razie plany rozszerzenia CommentModerator obejmują LinkSleeve i Defensio.

Jak na razie wygląda na to, że nie da się zamieścić komentarza, który zawiera link do Google Groups. Wolałbym nie rezygnować z automatycznego moderowania komentarzy, ale jeżeli nie da się tego uniknąć, to będę moderował komentarze ręcznie. Oh, my...

Jakiś problem z Akismet

Akismet robi jakieś hocki-klocki, gdy w komentarzu wpisuje się link do strony z plikami listy mailowej WARPY. Trzeba będzie to zbadać.

Aksimet poszedł w krzaki

Nie wiem, na którym końcu łańcucha pokarmowego został popełniony błąd, ale przez kilka godzin nie można było dodawać komentarzy dzisiaj z powodu brakującego pola user_agent, którego (zupełnie nie wiedzieć czemu) system antyspamowy nie dostawał podczas sprawdzania komentarza.

Przy okazji wyszło na jaw, że logi nginxa, jakie gromadzi megiteam.pl nie są szczególnie przydatne — nie wiadomo co jest logowane (stdout? stderr?), nie wiadomo kiedy wystąpił błąd, bo nie ma daty i czasu przy wpisach w logu fastcgi, są jedynie w access_logu, ale tam nie ma z kolei komunikatów o błędach. Zresztą, w logu fastcgi też ich nie ma, jedynie ślady w postaci komunikatów to broken pipe.

Poważny projekt, poważne koszta

A tak całkiem na poważnie, to nie wiem, czy te koszta są tak poważne.

Ten projekt to webshop (a jakże), z dość egzotycznym rodzajem muzyki. Nie obliczam go na jakiś ogromny ruch typu miliony wejść dziennie, ale z 10 000 przydałoby się obsłużyć. Oprogramowanie napiszę sobie sam (koszt: 0), pozostaje to, czego sam nie zrobię, czyli maszyna (najcieńszy Root Server na hetzner.de to około 2500 złotówek rocznie), storage (S3, z pewnym okładem to 250 złotówek miesięcznie) i opłaty dla firmy rozliczającej płatności. Razem daje to około 5500 złotówek samego kosztu utrzymania, kosztów administracyjnych jeszcze nie udało mi się policzyć.

Dużo? Czy nie dużo? Trudno mi powiedzieć, chociaż tak na oko nie wydaje się to jakimś ogromnym wydatkiem.

Wyczesane zarządzanie obiektowym keszem w Django

Bardzo, bardzo dokładnie przyglądam się wszystkiemu, co związane z cache na poziomie obiektów w Django (np. projektowi django-orm-cache). Znalazłem blogowy wpis (po rosyjsku, a jakże!), który opisuje rozwiązanie bardzo podobne do tego, którego i my używamy, ale o wiele bardziej kompletne. Wypadałoby to teraz gdzieś przetestować, ale w środowisku, w którym miałoby to jakikolwiek sens, nie za bardzo możemy — po prostu nie ma na to czasu...

Ku pamięci, jak to Aleksiej Koszeliew załatwił sprawę odświeżania obiektowego cache w Django. Polecam uwadze, jeżeli kogoś też interesuje to, jak inni dają sobie radę z wygaszaniem cache...

Ludzie mają problemy

A my nie! (My, czyli kilka naszych aplikacji)

Iwan Sagalajew, pracujący dla yandex.ru, podzielił się kilkoma spostrzeżeniami po nieudanym odpaleniu nowego serwisu społecznego. Czytałem to z niekłamanym zadowoleniem — większość problemów, które tam opisał, nie ma nawet szans, żeby nas dotyczyć. Po kolei:

  • zbyt długi czas zapisu danych sesji, nie dotyczy nas, bo sesje trzymamy w memcache;
  • efekt "dog-pile", nie dotyczy nas, bo rzeczy kosztowne robimy poza aplikacją (poniekąd asynchronicznie);
  • pomimo nacisków naszego DB-speca, nie normalizujemy naszego modelu nadmiernie.

Nie mam złudzeń, że w pewnym momencie będziemy musieli troszkę przyciąć nasz radosny bałaganik, ale aplikacja została zaplanowana z tak dużym zapasem, że to na pewno nie nastąpi w ciągu najbliższych kilku miesięcy...

Mała aktualizacja, pod wpływem komentarza Bluszcza — to on to wymyślił. A żeby nie rozpłynął się w samozachwycie, to wymyślił też parę marnych rzeczy, ale tego co marne pozbędziemy się prędzej czy później...

Bosskie :D

Rzadko coś linkuję, ale to jest słodkie...

Ballada o SQLittle

Mówisz - masz

Bluszcz zażyczył sobie RSS-ów dla konkretnych kategorii, żeby odfiltrować offtopiki na planecie. Tradycyjnie na wyrost kazałem mu się zgłosić w przyszłym tygodniu, ale to nie byłaby aplikacja w Django, gdyby rzeczywiście miało to tyle trwać. I trwało w sumie 20 minut. Proszę, masz RSS-y z kategorii (u mnie się one nazywają etykietami). Tę, która Cię interesuje, znajdziesz na stronie z wpisami pod etykietą python.

Internet jako źródło wiedzy

Wiele osób uważa internet jako zupełnie nie spełniający wymogów, jakie stawia się wiarygodnemu źródłu wiedzy. Ich liczba mniej-więcej odpowiada liczbie osób, które wiedzę z internetu traktują bezkrytycznie, jak jakieś objawienie. To nie o nich mam zamiar napisać dziś kilka zdań, to niereformowalna ekstrema. Zastanawiają mnie ludzie, którzy nie umieją (lub nie chcą) skorzystać z wiedzy w internecie pomimo tego, że jej tam szukają.

Nie policzę, ile razy zdarzyło mi się w usenecie czy na liście mailowej odpowiadać na pytanie podając bezpośredni link do oficjalnej dokumentacji (najczęściej pierwsze trafienie w Google). Nie policzę, ile razy byłem pytany bezpośrednio o coś, co jest opisane w wielu miejscach i stało się już wiedzą powszechną. Czemu ludzie uważają, że wiedza pochodząca z usenetu jest bardziej wiarygodna od tej, którą mogą znaleźć przy użyciu dowolnej wyszukiwarki?

Wydaje mi się, że odpowiedź na to pytanie tkwi nie w ludzkiej naturze, ale w charakterze zadawanych pytań (i w efekcie w typie uzyskiwanych odpowiedzi). Wiele osób poszukuje nie sposobów rozwiązania problemu (idei, pomysłu), ale gotowego rozwiązania, które można zastosować metodą Ctrl-C i Ctrl-V. Od takiej wiedzy wymaga się, by była generyczna i rozwiązywała całe spektrum problemów jednej kategorii, albo została dopasowana do konkretnego przypadku. Ponieważ taka generyczna wiedza jest wielką rzadkością, poszukiwacze wiedzy stawiają na to, że ktoś, postępując według ich wskazówek, wyprodukuje odpowiadający ich potrzebom kawałek wiedzy, gotowy do zastosowania w ich przypadku i rozwiązujący ich problem.

Jest nas dużo, ale wciąż za mało

Na Django People jesteśmy teraz na 4 miejscu, razem z Niemcami. Uważam to za całkiem niezły wynik. Przed nami są Brazylia, Wielka Brytania i US of A (w tym przypadku chyba bardziej sprawiedliwe byłoby liczenie według stanów, ale się nie upieram), więc raczej kraje albo dużo bardziej liczne ludnościowo od nas, albo bardziej ambitne, jeżeli chodzi o pokazanie się. Mogę się mylić (i pewnie się mylę), ale każde miejsce wśród pierwszych 7-8 powinno nas zadowalać, choćby z powodu tego, ile osób przychodzi na WARPY (w tym tygodniu zostało odwołane). Python zajął już poczesne miejsce w galerii języków programowania, a Django jest już powszechnie rozpoznawane.

To dobrze. Roboty jest dużo, a ten wózek musi się toczyć.

Wszystkie ręce na pokład!

Wczoraj pojawił się serwis Django People i w szybkim tempie wskoczyliśmy (my jako reprezentacja Polski) na 5 miejsce. To by mniej-więcej odpowiadało temu, co widać było m.in. na zeszłorocznym EuroPython, ale proszę nie ustawać w wysiłkach, klikać i się rejestrować. Naszym obecnym celem, po połknięciu Francji, Hiszpanii i Chin, są Niemcy!

Ubufox is a shit

Odkąd przesiadłem się na ubuntu 7.10 przez cały czas miałem problemy z wtyczką Flash do Firefoxa. A to twierdził, że jej nie ma, a to że jej nie chce, a to znowu coś innego. W pewnym momencie doprowadziłem swojego FF do tego, że musiałem usunąć cały profil i utworzyć go na nowo. Pakiet flashplugin-nonfree był oczywiście zainstalowany przez cały czas, ale ćwok uparcie twierdził, że nie jest. Mało tego, proponował ciągle zainstalowanie pakietu flashplugin-nonfree i po chwili rezygnował, stwierdzając, że przecież jest zainstalowany. Po wypieprzeniu ubufoksa zainstalowałem sobie wtyczkę prywatnie.

Panowie od ubuntu, wasz ubufox to kawał gówna.

Oh, no, neva!

Tutoriale mnie dygają

W szczególności tutoriale do ramówek webowych. Każda ramówka w pewnym momencie dorabia się "20 minutes wiki tutorial" (czasem nawet w formie screencastu), ale w większości przypadków są one całkowicie bez sensu — nie pokazują tego, jak ramówka działa, nie uczą, jak jej używać, nie opisują jej komponentów. Zaczęło się od niesławnego screencastu RoR, a potem było już z górki. Pamiętam kilka lat temu, gdy w krótkim czasie wystartowały TurboGears i zaraz potem Django, że początkowo TG wygrywało popularnością właśnie z powodu posiadania takiego screencastu (i uzyskiwało opinię łatwiejszego do nauczenia). Lista mailowa TG pękała w szwach, zapowiadano nowe, ekscytujące możliwości kolejnych wydań ramówki, ale minęło kilka-kilkanaście miesięcy i to Django przejęło inicjatywę. Po kolejnych kilku-kilkunastu miesiącach TG uchroniło się przed zniknięciem, ale jak na pioniera radzi sobie coraz gorzej, już nie jest nawet numerem 2, bo w staraniach o przejęcie władzy nad sercami i umysłami developerów wyprzedziło je Pylons. Na szczęście, Pylons również posiada 20 minutes wiki tutorial, więc pozycja Django (które posiada jedynie nieoficjalny screeencast wiki na ShowMeDo) wydaje się być niezagrożona. ;)

Tak sobie właśnie przypomniałem... Jakiś czas temu prorokowałem, że z pierdyliarda ramówek webowych w Pythonie (był taki okres, kiedy powstawała jedna ramówka dziennie...), pozostanie nam 2-3 liderów i plankton — i tak się właśnie stało. Kto wymyśli tę, która zdetronizuje obecny numer 3 i stanie do wyścigu o pierwsze miejsce?

64MB RAM na Megiteam.pl

To mało czy dużo? Zależy... Moja aplikacja daje radę. Działa na jednym procesie FastCGI, swoje przydziałowe (?) 64MB RAM wykorzystuje w 100%. Szukałem jakichś wskazówek, jak ograniczyć apetyt aplikacji Django (uruchamianej na FastCGI) na RAM, ale znalazłem niewiele, a już na pewno nic nowego, nic, czego bym już nie wiedział. Być może nie jestem jeszcze aż tak bardzo zdesperowany, bo nie odczuwam, żeby aplikacji brakowało pamięci. Może to jest całkiem wystarczająca ilość, skoro aplikacja się jeszcze nie krztusi?

E, tam, nie mam chyba większych problemów... Jeszcze kilka lat temu nie przeszłoby mi przez myśl, że będzie mnie stać na hostowanie gdziekolwiek aplikacji w czymkolwiek innym, niż PHP. Zanim dorobiłem się hostingu na megiteam.pl nawet zastanawiałem się, czy nie iść na taniochę i nie przeprosić się z PHP. A tu — prawie jak spełnienie marzenia.

Aktualizacja z 18 stycznia: pani Magda Zarych, właścicielka megiteam.pl, uściśliła moje domysły. Aplikacja nie spożywa 64M, lecz w granicach 18M. Patrzyłem nie na to, co trzeba. Swoją drogą, przyjemnie, że firma wsłuchuje się w bicie serca klientów. ;)

W poszukiwaniu nowych komiksów

Trochę z nudów, a trochę dla zrobienia sobie przerwy od kodowania tego serwisu (hahaha!), zapuściłem wyszukiwanie ciekawych komiksów w 'necie. Pół godziny poszukiwań (niezbyt intensywnych, muszę przyznać) doprowadziło mnie do dwóch miejsc: Dinosaur comic i Questionnable Content. Kojarzę, że kiedyś chyba jedno z nich nawet przeglądałem i całkiem mi się podobało. Chyba coraz bardziej lubię te lakoniczne historyjki. :)

Poniżej próbki, gdyby ktoś miał problemy z klikaniem myszą w linki...

people in the stories for men are always showing up to work late, saying "sorry i'm late, mr. bossman! an explosion happened to me." then mr. bossman explodes them out of the office!

They Ran In The Same Circles

Po raz kolejny uwidacznia się potrzeba użycia jeszcze szerszego szablonu. Mam nawet jeden na oku, ale jest marniutki...

Już zapomniałem jak to jest...

Family going to bed at 10 PM is so much worse than jet lag.

Kiedyś było to dla mnie dość normalne... Czyżby dopadała mnie nostalgia za kawalerskimi czasami? ;)

Wygląd tego wpisu przekonuje mnie, że czym prędzej muszę się rozejrzeć za jeszcze szerszym szablonem, bo mi sie stripy z XKCD nie mieszczą...

Książki, książki

Po Pro Django, Web Development Done Right szykuje się kolejna książka o tej ramówce — James Bennet zaanonsował, że pisze książkę, która omawia Django od strony praktycznej. Książka jest już listowana na Amazon.com, więc sprawa wygląda na poważną. Wypada się tylko cieszyć. Przyda się taka książka wszystkim początkującym.

Jednym z zagadnień przez tę książkę poruszanych ma być pierwsza aplikacja w Django, czyli właśnie silnik blogowy. Ja swój napisałem w ciągu kilku wieczornych sesji, właśnie jako projekt szkoleniowy z migracji na nową wersję Django (choć wcale nie był pierwszą aplikacją, moją pierwszą aplikację można już podziwiać od dłuższego czasu w Rumunii, na Węgrzech i w Wielkiej Brytanii). Trudno jednak wymagać, by ktokolwiek zaczynał zaznajamianie się z Django od dużego, komercyjnego projektu na zlecenie międzynarodowego klienta...

Dobre wieści, Django znowu działa

Mądrzejsi ode mnie znaleźli błąd, poprawili i Django znowu działa przez FastCGI. Chwała nam i naszym kolegom, wiadomo komu precz!

Rzeczy proste, rzeczy skomplikowane

Kiedyś o tym ktoś już napisał (może Joel Spolsky, a może ktoś inny, nie mogę sobie przypomnieć). A teraz dotknęło to mnie osobiście.

Są rzeczy proste i są rzeczy skomplikowane. Naturą rzeczy prostych jest to, że łatwo jest ich używać (my to nazywamy, że mają prosty interfejs). Są jednak także rzeczy, które są skomplikowane same z siebie. A jak jest z ich używaniem?

Podobnie jak z rzeczami prostymi, rzeczy skomplikowane są... skomplikowane w użyciu. Rzeczy skomplikowane mają skomplikowany interfejs właśnie dlatego, że ze swej natury są skomplikowane i ich funkcji nie da się wyrazić w sposób uproszczony. Można to porównać do dwóch narzędzi, które służą do wyciągania gwoździ: obcęgów i tzw. łapki. Obcęgi są dość skomplikowanym narzędziem, które spełnia kilka funkcji (na kilka sposobów), więc jego interfejs jest nieco bardziej skomplikowany, niż łapki. Oczekiwanie, że obcęgi będą miały prostszy interfejs, doprowadzi do degeneracji obcęgów do poziomu łapki. Podobnie, nikomu nie wpadnie do głowy, by żądać od 50-tonowej lokomotywy, by miała interfejs Hondy Civic.

A teraz zdążam na skróty ku poincie. Dużo ludzi uważa, że zadaniem nas, czyli developerów, jest zapewnianie prostego interfejsu. Abstrahując od tego, że jest to piramidalną bzdurą, jest to także niemożliwe. Rzeczy skomplikowane nie mogą mieć prostego interfejsu, dopóki są skomplikowane. I nie będą miały prostszego interfejsu, dopóki będą realizować skomplikowane funkcje w skomplikowany sposób. A takie działanie jest chyba immanentne dla aplikacji webowych...

Komiksy

Zasadniczo zlewam komiksy w internecie, ale XKCD jest po prostu... Po prostu świetne. Warto przejrzeć archiwa, by znaleźć swoje ulubione stripy (mój to ten o spowalnianiu ruchu obrotowego Ziemi).