Google chce przyśpieszyć internet

Posted by Piotr Sarnacki Fri, 26 Jun 2009 19:11:00 GMT

Nie od dziś wiadomo, że prędkość ładowania strony ma wpływ na akcje użytkowników. Badania prowadzone miedzy innymi przez Yahoo, Google i Amazon wskazały, że zmniejszenie czasu ładowania strony ma bezpośredni wpływ na ilość akcji wykonanych przez użytkowników (wyszukiwań lub w wypadku Amazona zakupionych przedmiotów).

Google odpalił niedawno stronę, na której zachęca i uczy jak przyśpieszyć działanie naszych stron i serwisów

Dodatkowo Google wypuścił narzędzie Page Speed, które jest rozszerzeniem do Firebuga i podobnie jak YSlow pomaga zbadać stronę pod kątem prędkości ładowania się poszczególnych komponentów. Oba te narzędzia dostarczają od razu praktycznych porad i opisów pomagających zrozumieć jak zoptymalizować stronę. Dla mnie są to niezbędne narzędzia przy pracy z serwisami internetowymi. Do tej pory używałem głównie YSlow, ale przy następnych optymalizacjach na pewno skorzystam z Page Speed.

Jeżeli jeszcze nie znacie tych narzędzi, gorąco polecam zapoznanie się z nimi.

Posted in ,  | Tags , , ,  | no comments | no trackbacks

Git - co zrobić gdy się scommituje za dużo zmian?

Posted by Piotr Sarnacki Tue, 07 Apr 2009 09:40:00 GMT

Jak zauważył słusznie Radarek w komentarzu taki sam efekt można uzyskać poleceniem git reset --mixed HEAD~1. W tym wypadku można by treść całego posta wyrzucić do kosza, ale zostawię dla potomnych, żeby można było zobaczyć jak trzeba się nagimnastykować jeżeli się nie zajrzy do dokumentacji ;-)

Czasami podczas pracy nad jakimiś większymi zmianami warto rozbić pracę na mniejsze commity. Zdarza mi się czasami dodać przełącznik -a z rozpędu, który commituje wszystkie zmiany. Najgorzej jest gdy wrzucam przy okazji nową wersję jakiegoś plugina do railsów. W takim wypadku zmiany w aplikacji są przeplatane zmianami w pluginie. Później gdy trzeba spojrzeć na coś w logach gita, może to dość znacznie utrudnić pracę.

Na szczęście git jest bardzo elastyczny i łatwo jest takie coś odwrócić.

Wyobraźmy sobie taką sytuację:


  # przechodzę do nowej gałęzi, żeby zaimplementować nowy feature
  git checkout -b feature_200

  #....
  # tutaj dużo zmian, między innymi dodanie 
  # nowego pluginu, uaktualnienie innego, 
  # zmiany w samym kodzie itp. itd.

  # a teraz chcemy scommitować tylko zmiany w 
  # danym pluginie:
  git add vendor/plugins/acts_as_foobar
  git commit -m "Nowa wersja acts_as_foobar kompatybilna z railsami 2.3" -a
  # oj... dodałem -a, scommitowały się też 
  # zmiany w kodzie

Co teraz? Nic trudnego :)


  # tworzymy patche względem mastera
  git format-patch master

W tym momencie powinno pojawić się sporo plików o nazwach na przykład:


0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch
#... ewentualnie więcej
Teraz trzeba wyrzucić “zepsuty” commit:

  git rebase -i HEAD~3

Teraz powinien otworzyć się edytor, w którym widnieją linijki zaczynające się od słowa pick. Kasujemy linijkę z niechcianym commitem (tutaj uwaga – jeżeli nie jesteście pewni, że wszystko gra, to najlepiej zrobić backup repo, po takim zabiegu commit po prostu zniknie). Po zapisaniu zmian commit powinien zostać wyrzucony z drzewka i można zaaplikować wcześniej stworzonego patcha:


git apply 0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch

W tym momencie wszystko powinno wyglądać tak jak przed commitem – można teraz poprawić swój błąd.

Wiem, że to może się wydawać skomplikowane (szczególnie rebase), ale w praktyce zajmuje krótką chwilę, a dzięki takiemu zabiegowi nie ma bałaganu w repozytorium.

A może Wy macie jakieś ciekawe metody na rozwiązywanie problemów z gitem? Może inny sposób na powyższy problem?

Posted in  | Tags , ,  | 2 comments | no trackbacks

Refaktoryzacja Railsów

Posted by Piotr Sarnacki Sat, 03 Jan 2009 20:45:00 GMT

Niestety nie będzie to wpis o tym jak refaktoryzować swoją aplikację, ale raczej post o refaktoryzacji samego frameworka w ramach przygotowań do Rails 3.

Railsy pożarły mózg Merba i posiądą jego tajemne moce (zachęcam do wysłuchania tego podcastu, chłopaki od railsenvy genialnie mówią o tym co się dzieje w świecie railsów) – o tym już każdy na pewno wie. Czy to dobrze? Oczywiście, że tak :)

Jeżeli ktoś dalej ma problemy z tą decyzją (podejrzewam, że może tak być w wypadku fanów merba), polecam prezentacją Living with legacy software wygłoszoną przez Davida Heinemeiera Hanssona – nie jest w żaden sposób bezpośrednio związana z połączeniem, ale zmienia podejście do aplikacji i ich kodu.

Ale nie o to, nie o to, nie o to

Yehuda Katz ostro wziął się do pracy jeszcze podczas świąt i co jakiś czas wrzuca na bloga informacje o tym jak refaktoryzuje i jakie ma plany wobec Railsów. Informacje traktujące o projektowaniu, refaktoryzacji i architekturze ciężko jest znaleźć w sieci, więc gorąco polecam śledzenie tego co pisze Yehuda – do tej pory można przeczytać między innymi o enkapsulacji ActionView i ActionController czy o optymalizacji respond_to. Dodajcie sobie tego bloga do czytnika, naprawdę warto.

Co najlepsze, wiele z tych zmian dotyka tylko wewnętrznej implementacji railsów, więc można liczyć, że będą one dostępne dla ruby on rails 2.3.0.

Posted in ,  | Tags , , , , , ,  | no comments | no trackbacks

To self or not to self?

Posted by Piotr Sarnacki Sat, 15 Nov 2008 18:12:00 GMT

Czasami przeglądając kod różnych aplikacji można zauważyć kawałki wyglądające mniej więcej tak:


  attr_accessor :price

  def total_price
    p = items.inject(0) {|sum, item| sum + item.price }
    # więcej kodu
    p
  end

W prawdziwej aplikacji można to zobaczyć na przykład w Spree (użycie tot zamiast total)

p oznacza tutaj zapewne price, ale autor kodu intuicyjnie stwierdził, że pisząc “price =”, zamiast stworzenia nowej zmiennej przypisze wartość na atrybut price.

Rzeczywiście jest to intuicyjne i całkiem bezpieczne, ale zupełnie niepotrzebne. Spokojnie i bez żadnego problemu można użyć price. Dlaczego?

W rubim można opuścić słowo self jeżeli chodzi o odczytanie wartości metody. Jeżeli więc bez zadeklarowania zmiennej price ktoś napisałby puts(price), to ruby zinterpretowałby to jako chęć wyświetlenia self.price. Inaczej jest z zapisywaniem. Jeżeli wywołana jest metoda price=, to ruby stworzy nową zmienną.

Na przykład taki kod:

  class Product
    attr_accessor :price

    def initialize(price)
      self.price = price
    end

    def do_something_with_price
      price = 10
      puts price
      puts self.price
    end
  end

  p = Product.new(20)
  p.do_something_with_price
Wypisze:

10
20

Na koniec napiszę tylko, że mam mieszane uczucia co do korzystania z tych właściwości języka. Z jednej strony nie lubię jak w kodzie pałętają się skrótowe nazwy zmiennych, ale z drugiej strony taki zapis pokazuje, że chodzi nam o coś innego niż self.costam.

Ja z reguły staram się nie skracać nazw w takich wypadkach. Jakie jest wasze zdanie?

Posted in  | Tags ,  | no comments | no trackbacks

Named scope

Posted by Piotr Sarnacki Fri, 03 Oct 2008 10:37:00 GMT

W railsach od jakiegoś czasu można używać named_scope. Jest to bardzo fajny mechanizm umożliwiający łatwiejsze skonstruowanie zapytania używając wcześniej zdefiniowanych metod. Wcześniej był dostępny jako plugin has_finder.

Wygląda to mniej więcej tak:

  named_scope :active, :conditions => { :active => true }
  named_scope :paid, :conditions => { :paid => true }
  named_scope :recent, lambda { { :conditions => ['created_at >= ?', 1.week.ago] } }

Po zdefiniowaniu takich sope’ów (macie pomysł jak to spolszczyć?) można ich używać w ten sposób (zakładam, że scope’y zostały zadeklarowane w modelu Product):

  Product.active.paid.recent

Jak można łatwo zauważyć, scope’y można łączyć w łańcuchy. Dzięki takiej konstrukcji otrzymujemy prosty i treściwy kod, który łatwo zrozumieć. Teraz coś lekko trudniejszego:


  named_scope :in_category, lambda { |category| { :conditions => { :category_id => category } } }

  # i użycie
  Product.active.recent.in_category(category)

O co chodzi? Jako 2 argument można przekazać lambdę, która zostanie wywołana przy użyciu scope’a i powinna zwrócić Hash.

Ale to nie są jedyne zastosowania scope’ów. Można do nich przekazać też inne parametry, które może przyjąć metoda find.

Na przykład order, offset i limit:

  named_scope :order, lambda { |*args| { :order => args.first || "created_at DESC" } } 
  named_scope :offset lambda { |offset| { :offset => offset } } 
  named_scope :limit, lambda { |*args| { :limit => args.first || 10 } } 

  # i użycie:
  Product.active.order("id DESC").offset(10).limit

W pierwszym i trzecim scope’ie zastosowałem trick, który pozwala na użycie zdefiniowanej wartości domyślnej w razie gdy żadna nie zostanie podana. `*args` pakuje argumenty do tablicy. Jeżeli args.first zwróci nil, to znaczy, że tablica jest pusta, czyli nie zostały podane żadne argumenty i trzeba zaaplikować wartość domyślną.

Coś jeszcze? Fajnie by było, żeby można było sortować nie tylko po wartościach z jednej tablicy… a do tego wypadałoby użyć joins/include. Nic prostszego.


  named_scope :joins, lambda { |joins| { :joins => joins } } 

  # a teraz można tak:
  Product.active.joins(:user).order('users.email')

How cool is that?

No i na koniec coś co ostatecznie przekonało mnie, że named_scope jest genialnym wynalazkiem. Jeżeli ktoś robił kiedyś formularze, w których można wybrać kilka opcji i na ich podstawie trzeba zbudować zapytanie, zapewne wie, że jest to nieco upierdliwe. Używając `named_scopes` można to zrobić bardzo łatwo.

Ryan Bates napisał plugin scope_builder, dzięki któremu można to zrobić jeszcze łatwiej. Przypuśćmy, że mamy formę, w której można zaznaczyć kilka pól i po ich wysłaniu należy na ich podstawie pobrać odpowiednie rekordy z bazy.


  # przygotowujemy listę parametrów, które użytkownik może ustawić
  parameters = [:active, :paid, :recent, :title]
  # Tworzymy scope
  @products = Product.scope_builder
  # teraz można sprawdzić, które pola zostały zazanczone
  parameters.each do |param|
    @products.send(param) if params[param]
  end
  # na koniec można na przykład dodać paginację
  @products = @products.paginate(:per_page => 10, :page => params[:id])

Dla mnie genialne. :) Można dzięki temu łatwiej tworzyć zaawansowane wyszukiwanie, sortowanie i inne tego typu rzeczy.

Oczywiście najlepiej jest zamknąć taki kawałek kodu jako metodę modelu, zgodnie ze skinny controller, fat model, ale to pozostawię jako ćwiczenie ;-)

Posted in ,  | Tags , ,  | no comments | no trackbacks

Po dłuższej przerwie

Posted by Piotr Sarnacki Tue, 30 Sep 2008 14:38:00 GMT

Przez jakiś czas nie pisałem nic na blogu. Długo zbierałem się do napisania czegokolwiek, od dawien dawna miałem przetłumaczyć wpisy na moim angielskojęzycznym blogusiu. Tak bardzo mi się nie chciało, że jak tylko siadałem do kompa z zamiarem przetłumaczenia czy napisania czegoś podobnego coś mnie odrzucało.

Dlatego, żeby więcej się nie męczyć podsumuję ten temat i podam linki – większość ludzi, którzy tutaj trafią i tak na pewno zna angielski.

Napisałem apache upload progress module do apacha. Moduł, dzięki któremu można pobrać dane o wysyłanych plikach. Format odpowiedzi oparłem o moduły tego typu dla nginxa i lighttpd dlatego jeżeli wcześniej ktoś używał któregoś z nich, przesiadka będzie całkowicie bezbolesna. Sam używałem wcześniej nginx upload progress (głównie dlatego napisałem moduł do apacha) i po przerzuceniu aplikacji na apacha z nowym modułem nie trzea było zmieniać ani jednej linijki. Na angielskim blogu zamieściłem opis instalacji i konfiguracji modułu.

Żeby można było w miarę łatwo używać modułu napisałem także pluginy do “prototype’a”http://github.com/drogus/prototype-upload-progress/tree/master i jquery, które obsługują pasek postępu. Przykłady są w repozytoriach, umieściłem je także na serwerze dla obczajenia w akcji. Popełniłem także tekst o tym jak hackowałem plugin, żeby działał w safari – safari w tym momencie nie było wcale lepsze od IE… nawet powiedziałbym, że gorsze. Swoją drogą plugin nie działa w najnowszej operze (działał w 9.5 zdaje się), więc jeżeli ktoś ma chwile czasu i mógłby sprawdzić dlaczego i co można zrobić, żeby działał, to może wnieść swój wkład w rozwój (dodam, że nie jest to ta sama kwestia co dla safari, bo to już sprawdziłem) – nie sądzę żebym miał teraz czas sam na tym siedzieć.

Dodatkowo napisałem jeszcze tekst o tym jak można fajnie uatrakcyjnić aplikację używając jQuery. Część pierwsza. Część druga będzie jak będę miał więcej czasu, czyli pewnie niezbyt szybko.

Pozdrowienia ze słonecznego Wrocławia, gdzie mam zamiar mieszkać przez najbliższy rok (miła odmiana od Pruszkowa :).

Posted in , ,  | Tags , , , ,  | no comments | no trackbacks

2 przydatne rzeczy w gicie

Posted by Piotr Sarnacki Tue, 03 Jun 2008 09:04:00 GMT

Usuwanie gałęzi ze zdalnego repozytorium:


git push {repository} :heads/{your_branch_here}

Usuwanie pliku z indexu bez usuwania go z systemu plików (przydatne gdy dodamy do .gitignore plik, który już istnieje):


git-update-index --force-remove sciezka/do/pliku

Taki szybki pościk ;-)

Posted in  | Tags , , , ,  | no comments | no trackbacks

Git

Posted by Piotr Sarnacki Tue, 08 Apr 2008 12:50:00 GMT

Jeżeli ktoś jeszcze nie zauważył społeczność frameworków Ruby on Rails i Merb przesiada się powoli na rozproszony system kontroli wersji Git. Na gita przechodzą Railsy, przeszedł już Merb, Rspec, sporo koderów wypuszczających popularne pluginy. Jednym słowem coś w tym musi być.

I rzeczywiście coś w tym jest.

O co chodzi? Jarosław Zabiełło na swoim blogu przedstawił kilka rozproszonych systemów kontroli wersji.

Jakie są zalety gita?

  • każdy posiadający kopię aplikacji posiada też całe repozytorium. Coś się rozwaliło? Trzeba zmienić serwer? Serwis,a na którym hostowałeś SVN’a padł? Smuteczek. Ale nie z gitem – repozytorium, które masz na dysku wystarczy.
  • Git jest dużo szybszy od SVNa
  • “Mobilność” – bardzo ważna dla mnie kwestia. Często wyjeżdżam i zdarza mi się pracować bez dostępu do netu. W przypadku SVNa musiałem wrzucić jeden mega commit z pierdylionem zmian. W przypadku gita commity lecą do repozytorium na dysku i później można je ewentualnie pchnąć (push) do publicznego repo.
  • Bardzo łatwa obsługa gałęzi. Pracując z gitem najlepiej wyrobić sobie nawyk tworzenia gałęzi przy każdej zmianie, lub grupie połączonych ze sobą zmian. Dzięki temu można pracować równolegle nad wieloma rzeczami nie zaśmiecając aplikacji. Później tylko łączymy gałęzie, które rzeczywiście są potrzebne, jeżeli coś nie wyjdzie można po prostu daną gałąź wyrzucić i po krzyku
  • dużo łatwiejsze wrzucanie zmian do projektów open source’owych, szczególnie z pomocą githuba (ale o tym za chwilę).

Ale kod leżący cały czas na dysku będzie mało przydatny. Dlatego można założyć sobie publiczne repozytorium. Stwierdziłem jakiś czas temu, że w trosce o swój czas, którego zawsze za mało, będę musiał ograniczyć wszelkie prace, których mogę stosunkowo łatwo uniknąć. Dlatego nie bawiłem się nawet w tworzenie swojego własnego publicznego repozytorium. Wygodniej skorzystać pracy innych ludzi ;-)

Obecnie najbardziej popularne (jedyne?) serwisy oferujące hosting repozytoriów gita to: GitHub i Gitorius. Gitorius jest w pełni darmowy, ale nie można na nim trzymać prywatnych repozytoriów. Na githubie za darmo można trzymać publiczne repozytoria (ogranicza nas 100mb – jeżeli chodzi o gita to bardzo dużo), za prywatne trzeba będzie zapłacić. Na razie można jeszcze korzystać za darmo, bo serwis jest w fazie beta.

Zarejestrowałem się na Githubie kilka dni temu i przeniosłem tam 2 ze swoich projektów. Github to bardzo fajny pomysł na stworzenie społeczności koderów (napisany oczywiście w railsach). Co daje taki serwis?

  • dostęp do rss’ów poszczególnych użytkowników, projektów, feed z wiadomościami z obserwowanych projektów
  • można jednym kliknięciem zrobić kopię aplikacji (fork) – jakie są tego korzyści opisał na blogu jeden z developerów merba Michael Ivey :Contributing to merb
  • można wysłać znajomym “pull request” – czyli prośbę o uaktualnienie, na przykład po ważnej aktualizacji

Dodatkowo dostajemy wszystkie zalety gita.

No to co? Przesiadka na jasną stronę mocy, z tego fuj fuj obleśnego i niefajnego SVNa, który tak chwaliłem kiedy się z nim zapoznałem ;-)

Posted in  | Tags , , , ,  | no comments | no trackbacks

Książki

Posted by Piotr Sarnacki Sat, 01 Sep 2007 12:40:00 GMT

Zdarza mi się ostatnimi czasy przeczytać komentarz, że książki programistyczne są już niepotrzebne, bo i tak wszystko jest w necie. A nawet, cytuję: “w książkach to jest naćkane, jak chcesz konkretów to nie kupuj książek”.

Całkiem głupie to ;-)

Dla mnie książki programistyczne są niezastąpione. I najchętniej kupiłbym sobie połowę pozycji dostępnych na rynku. Po czym prawdopodobnie 1/3 bym nie przeczytał, ale to już inna kwestia. Ogólnie rzecz biorąc większości rzeczy zawartych w książkach można pewnie nauczyć się samemu, z lekką pomocą wujka Googla. Ale o ile przyjemniej przeczytać jak to robią profesjonaliści (o ile nikt nie da się nabrać niektórym profesjonalistom inaczej)

Po takim wstępie nie mogę się nie pochwalić, że jakiś czas temu kupiłem wspólnie z ludźmi od nowego projektu (na razie nie zapeszam. za jakiś czas pewnie coś napiszę) parę bardzo fajnych książek.

  • Don’t make me think – genialna książka o usability. Bardzo krótka i treściwa. Autor starał się napisać książkę, którą będzie się dało przeczytać w parę godzin. I muszę przyznać, że bardzo dobrze mu to wyszło. Idealna dla ludzi, którzy nie są specami w tej kwestii, a chcą poprawić użyteczność swoich stron.
  • Agile development with Rails – Pozycja obowiązkowa dla uczących się RoR. Co prawda teraz niewiele mi się przyda, ale czułbym się źle jakby jej nie kupił. Korzystałem dość sporo z ebooka z amule’a. No i przyda się bliźniemu, który właśnie zaczyna się uczyć RoR.
  • Ruby for Rails – jeszcze nie przeczytałem, ale po przekartkowaniu zapowiada się bardzo ciekawie. Napiszę coś więcej jak wreszcie się za nią wezmę ;-)
  • The Ruby Way – bardzo dobra książka. Jestem właśnie w trakcie czytania. Podaje bardzo dużo rozwiązań często spotykanych problemów zgddnie z “ruby way”. Ponad 600 stron esencji programowania ;-)
  • JavaScript: The Definitive Guide – niektórzy narzekają, że książka bardziej zbliżona jest do dokumentacji niż do książki “do nauki”. Dla mnie to plus. Javascripta znam całkiem dobrze. Pewnie dzięki temu, że w poprzednim stuleciu, kiedy o bibliotekach takich jak jQuery nikt nie słyszał, bawiłem się w pisanie różnego rodzaju latających warstw, wysuwanych menu i innych arkanoidów (nawet fajnie się grało ;-). W tym momencie potrzebuję właśnie takiej dokumentacji, do której mogę spojrzeć podczas pisania i zobaczyć jakie metody udostępnia dana klasa, albo jak powinien się zachowywać jakiś kod. Jeżeli ktoś chce pisać coś więcej niż efekty z użyciem jQuery (czy innego script.aculo.us), to naprawdę zachęcam do kupna.

Podejrzewam, że gdyby początkujący programiści więcej inwestowali w wiedzę książkową to byłoby dużo mniej partactwa. Szczególnie, że książki związane z Rubim i RoR oprócz nauki programowania próbują od początku wpajać dobre praktyki programistyczne. I koniecznie trzeba przeczytać Pragmatycznego programistę :)

Posted in  | Tags , , , , ,  | no comments

Historia pewnej aplikacji

Posted by Piotr Sarnacki Thu, 14 Dec 2006 23:30:00 GMT

Jakiś czas temu miałem wątpliwą przyjemnmość modyfikowania pewnego systemu CMS napsanego w PHP, w celu dopasowania go do klienta. CMS słaby jeżeli chodzi o kod (dość wolny, w niektórych miejsach mała dbałość o bezpieczeństwo, kiepskie zaprojektowanie). Po przejrzeniu specyfikacji stwierdziliśmy (z kolegą, który miał pisać to ze mną), że poprawki nie będą duże i można je będzie wprowadzić bez wielu zmian w kodzie. Nic bardziej mylnego.

Chciałbym podzielić się wrażeniami z rozwijania dużej (jak się później okazało) aplikacji. Na razie wolałbym nie mówić o tym dla kogo ją pisaliśmy, gdyż jeszcze do końca się nie uwolniliśmy od tego projektu. Człowiek uczy się na błędach, więc o błędach chciałem napisać.

Odejście od specyfikacji

Niedługo po rozpoczęciu prac można było zobaczyć wyniki. Wstawiliśmy pierwszą wersję szablonów HTML, jeszcze bez ostatecznego formatowania, ale z grubsza przypominającą otrzymane grafiki. Od razu zaczęły się uwagi i spekulacje jakie moduły przydałoby dopisać i co zmienić aby ułatwić pracę przy wstawianiu treści. Stwierdziliśmy, że robiąc drobne poprawki nie przysparzamy sobie zbyt dużo pracy, a klient będzie zadowolony, więc jest nam to nawet na rękę. Bardzo duży błąd. Dopisując jeszcze funkcjonalność zawartą w specyfikacji, zaczęliśmy ową specyfikację zmieniać. Większość propozycji wychodzących od klienta nie było przemyślanych, czasami po dopisaniu kodu trzeba było go usunąć, bo “to jednak nie było to”. Kod zaczął się powoli zaśmiecać, a my niejako staliśmy w miejscu - robiliśmy poprawki, a aplikacja była cały czas daleko od ukończenia.

Wybór technologii

W tamtym okresie nie myśleliśmy poważnie o czymkolwiek innym niż PHP. Baliśmy się deploymentu, klopotów z serwerem. Poza tym prawie gotowy system mieliśmy już napisany (należy w tym miejscu przypomnieć, że prawie robi wielką różnicę). Napisany, ale tak jak już wspomniałem napisany kiepsko. Trzymaliśmy się konwencji, w której napisany był CMS, a liczba linii kodu i funkcji drastycznie rosła. System był coraz bardziej zaśmiecony, o czymś takim jak moduły do testowania nawet nikt nie myślał, a często podczas poprawiania jednych błędów wynikały inne (zarówne w kodzie jak i te na poziomie projektowania). Nie wyglądało to dobrze.

Niewiedza klienta!

Niestety nie wzięliśmy poprawki na to z kim będziemy mieli dane pracować. Informatycy z owej instytucji nie są osobami kompetentnymi - cały czas wnosili o zmiany w serwisie, a bardzo łatwo było stwierdzić, że nie znają się nic a nic na specyfice aplikacji internetowych, ani na programowaniu czegokolwiek (ewentualnie jakiejś prostej w obsłudze pralki). Najlepiej chyba to opisze tekst szefa informatyków: Linki, na które kliknę zmieniają kolor (wcześniej proszono nas o zmianę visited na odmienny kolor) i zostają takie nawet przez kilka dni. Trzeba było mu wytłumaczyć na czym to polega… Albo wysyłanie maili: “Prosimy o zrobienie archiwum dla całego serwisu”, żeby zaraz potem wysłać maila “Oczyistym jest, że archiwum powinno być oddzielne dla każdego działu w serwisie”.

Najbardziej rozbrajały mnie te oczywstości, których było niesamowicie dużo. Wszystko co zrobiliśmy, a co nie było zgodne z ich błyskotliwymi przemyśleniami komentowane było: “Oczywistą rzeczą jest… “. Tłumaczenia, że nic nie jest takie oczywiste na niewiele się zdały.

Przedwczesny start

Z racji tego, że czas naglił zmuszeni byliśmy uruchomić serwis i przeprowadzić szkolenia przy niedokończonej wersji - od strony użytkownika wchodzącego na stronę wszystko wyglądało dobrze, ale w panelu administracyjnym sporo było rzeczy, które mieliśmy zmienić.

Kozi róg?

W tamtym momencie byliśmy w sytuacji podbramkowej. System był nieskończony, a było parę błedów i rzeczy do dopisania. Wtedy oczywiście klient przeszedł do ofensywy i nie patrząc na to ile zrobiliśmy rzeczy poza specyfikacją zaczął wytykanie nam “ewidentnych błędów, które uniemożliwiają pracę nas serwisem”.

Współpraca

A raczej jej brak. Niestety to był jeden z tych projektów, w których nie mamy przyjaźnie nastawionych użytkowników. Cały system od początku był postrzegany jako zło konieczne - pracownicy mieli wprowadzać na stronę wyniki swojej pracy. Czyżby nagle trzeba było zacząć pracować? Najgorszym elementem okazał się edytor WYSIWIG. Pomimo długich tłumaczeń, że tekst z word’a nie zawsze się w nim dobrze sformatuje notorycznie mieliśmy telefony, że tekstu nie da się sformatować. Niezliczoną ilość razy musiałem powiedzieć o tym jak wtedy należy postąpić: zapisać dokument jako plik .txt, wkleić do edytora i dopiero wtedy sformatować. Według użytkowników to jest za dużo pracy. Cóż z tego, że w większości wypadków formatowanie tektu zajmowało mi ok. 10 min? Najlepszy byłby oczywiście system, który sam napisałby i sformatował artykuł, a później zaparzył kawę i poszedł do kiosku po gazetę.

Rewolucja?

Po jakimś czasie poprawiliśmy większość błędów, ale pewne rzeczy ciężko było zmienić bez przebudowy wielu linijek kodu. Zdecydowaliśmy się na przepisanie systemu używając ruby on rails. Jak pomyśleliśmy tak też zrobiliśmy i mamy teraz tak samo wyglądający system, ale z railsami pod maską. Aplikacja chodzi o jakieś 30% szybciej - łatwo można zauważyć, że poprzedni cms był naprawdę kiepsko napisany. Do tego nie dopisaliśmy jeszcze cache’owania, a na pewno to zrobimy - zmiany na stronie są wprowadzane dość rzadko.

Nie muszę chyba wspominać, że napisanie tego systemu od początku zajęło nam dużo mniej czasu niż modyfikacja poprzedniego. Trochę boli fakt, że wyszedł z tego taki sam system. Nie wykorzystaliśmy więc mocy jaka drzemie w railsach. Jeżeli chodzi funkcjonalność i ciekawe rozwiązania wyszedł z tego marny przeciętniak.

Podsumowując!

Podczas pracy nad tym projektem popełniliśmy chyba wszystkie błędy, które dało się popełnić (zgodnie z prawem Murphy’iego ;-) ). Czasu na tym straciliśmy tyle, że pracowaliśmy za przysłowiową miskę ryżu, a momenty zwątpienia lub chęci odwiedzenia pracowników owej instytucji z kałasznikowem w ręku były bardzo częste. Można spytać, czy…

…warto było?

Myślę, że pomimo wszystko warto było się pomęczyć. Wiele się nauczyłem i czuję, że takie doświadczenia mi się przydadzą. Swoją drogą jest to doskonały przykład uczenia się na błędach ;-) I wiem nad czym muszę jeszcze dużo popracować: komunikacja z klientem.

I to by było na tyle jeżeli o historię pewnej aplikacji chodzi.

Posted in ,  | Tags , , ,  | no comments