Z każdym krokiem bliżej GIT a dalej SVN

Powoli przekonuję się go systemu zarządzania kodem źródłowym (scm) GIT. Pewnie zanim uda wprowadzić się go w firmie trochę minie czasu (przecież w zeszłym roku wdrożyliśmy SVN, które dał nam niezłego kopa przy pracy nad dużymi projektami).

Git jest mniej sławnym dzieckiem Linusa Torvaldsa (tak, tego samego od Linuksa), który zrozumiał, że SVN choć świetny – nie jest idealny.

Git-scm

Jeśli przeszukasz internet dowiesz się wiele o zaletach tego systemu wynikające z innej filozofii, która repozytorium nie traktuje jako zbioru kolejnych wersji, ale jako zbiór konkretnych zmian. Dzięki temu sytuacje, które w SVN wymagają rozwiązywania konfliktów w GIT najczęściej sprowadzają się do automatycznego scalania (merge) zmian. Podobno dzięki tej zmianie branchowanie z trudnego tricku zmienia się w wygodne i użyteczne narzędzie.

Sam postanowiłem delikatnie wejść w ten strumień. Są projekty, które robię samodzielnie. Nie wymagają one systemu zarządzania wersjami, skoro jestem jedyną osobą, która ma dostęp do kodu. Jednak jestem tak przyzwyczajony do udogodnień, które przynosi ze sobą scm, że i tak zakładam repozytorium.

W prywatnych projektach przesiadam się na GIT bo założenie repozytorium jest proste jak 1,2,3(4):

cd /sciezka/do/projektu
git init
git add .
git commit -m "zakładam repo ^_^"

Dobra książka o przyszłości i możliwych zmianach

Zastanawiałeś się kiedyś jaki język jest “przyszłościowy”? Nie Ty jeden, na forach i portalach co kilka dni pojawia się podobne pytanie. Czy nauczyć się php? Czy może ruby, albo python? W co zainwestować?

Często odpowiedzi są niezadowalające – możesz dowiedzieć się, że jeśli będziesz wybierał język wg spodziewanych przyszłych zarobków, to nie będziesz dobrym programistą. W tym stwierdzeniu jest tylko połowa prawdy. Jeśli zostajesz programistą ze względu na możliwe zarobki możesz nie być tak dobry jak ten, dla którego jest to pasja.
Jeśli jednak już wybrałeś tą ścieżkę i chcesz się nauczyć tej technologii, która jest najbardziej pożądana, a przez to najlepiej płatna – jest to jak najbardziej rozsądne działanie. Porównałbym go do inwestowania tam, gdzie spodziewamy się największych zysków.

Jeśli stoisz właśnie przed podobnym dylematem chętnie zasugeruję Ci książkę, która może nieco rozjaśnić Ci sytuację. “Więcej niż Java” nie odpowie Ci na pytanie “którą droga iść?”. Ale rzuci światło na każdą z interesujących ścieżek, dzięki czemu, być może, łatwiej będzie Ci zdecydować.

Jednocześnie warto mieć w głowie pewne stwierdzenie, które przeczytałem w informatorze uniwersytetu kiedy startowałem na studia.

Studia informatyczne nie mają za zadanie nauczyć studentów jakiegokolwiek języka programowania. Mają za zadanie nauczyć ich myślenia, zasad i mechanizmów zachodzących w świecie informatyki, żeby absolwent mógł nauczyć się samodzielnie dowolnej potrzebnej technologii

Dlatego nawet jeśli podejmiesz decyzję i okaże się strzałem w dziesiątkę (zastąpi Javę i da Ci wspaniałe zarobki) pamiętaj, że powstaną wspanialsze narzędzia, które prędzej czy później wrzucą z piedestału Twojego wybrańca i kurę znoszącą złote jajka w jednym.

Bądź na bieżąco, poznaj jeden, ciekawy język/framework przynajmniej raz na pół roku… choćby pobieżnie i przeczytaj książkę, którą Ci polecam, bo warto ;)

Własny pingback – kiedy wysłać?

Ktoś, kogo śmiem nazywać “stałym” czytelnikiem tego bloga, czyli Kminek zadał mi ciekawe pytanie :

mam pewna zagwozdke – stworzylem mala platforme blogowa w Cake – cos a`la WordPress.com. przymierzam sie do implementacji protokolu Pingback. jest kwestia wysylania pingow – chyba raczej z punktu widzenia wydajnosci nie mozna tego robic przy zapisywaniu posta tylko uzyc taska shellowego, ktory co pewien czas bedzie to robil? jak sadzisz ?

Myślę, że tak jak sugerujesz, wysłanie pinga nie jest dobrym pomysłem. Sam pisząc posty czasem zapisuję je kilka razy zanim staną się one publicznie dostępne. Gdyby już przy pierwszym zapisie wysłać ping to byłby on wadliwy – prowadziłby do nieistniejącej strony.

Z drugiej strony wspomniany przez Ciebie task shellowy (rozumiem, że chodzi na przykład o crona) jest zadaniem dość kłopotliwym. Moim zdaniem komplikuje on architekturę aplikacji. Oczywiście zależy jak dużo do tego taska chcesz upchnąć? Jeśli parsowanie wpisu w poszukiwaniu linków etc. to moim zdaniem jest to zbyt wiele.

Moim pierwszym pomysłem było wysłanie pinga przy publikacji wpisu. Jednak gdyby w tekście znalazło się 20 różnych linków i wysyłać pingi przy publikacji – mogłoby to zbyt długo trwać i być niewygodne dla autora bloga (wyobrażam sobie sytuację, że przy 18 pingu następuje timeout wykonania skryptu i nie wiadomo czy post się opublikował i czy pingi się udały?).

Dlatego wybrałbym rozwiązanie kombinowane. Tzn. podczas publikowania wpisu (i update’u już opublikowanego) parsowałbym sobie tekst i znalezione linki umieszczałbym w tabeli pingbacks, która mogłaby wyglądać mniej więcej tak:

|----------------------------------------
| pingbacks
|----------------------------------------
| id: INT
| post_id: INT (albo permalink jeśli wolisz)
| uri : varchar (pingowany link)
| sent: tinyint(1) DEFAULT 0
|----------------------------------------

oczywiście przed zapisem sprawdzamy, czy już go nie ma w bazie ;). Przy takim rozwiązaniu świetnie powinien sprawdzić się Post::afterSave(). Wystarczy sprawdzić, czy zapisany model został z opublikowany i odpalić metodę Post::findAndSavePingbacks($postId).

Mam problem z tym, gdzie umieścić logikę wysyłania pingów. Myślę, że to też należałoby do warstwy Modelu (Pingback::send($limit)). Metoda taka pobrałaby kilka elementów z tabeli `pingbacks`, które nie zostały jeszcze wysłane i po udanym wysłaniu aktualizował pole `sent` (ustawiając 1).

Na koniec w kontrolerze zdefiniowałbym akcję, która miałaby za zadanie jedynie odpalić metodę Pingbacks::send()

class PingbacksController extends AppController{
  function send($limit=10){
     $this->autoRender = false;
     $this->Pingback->send($limit);
  }
}

I teraz jeśli mamy dostęp do crona to możemy zdefiniować na przykład akcję wget http://example.com/pingbacks/send
Jeśli nie mamy dostępu do takich luksusów – możemy wzbudzać tą akcję np. w AppController::afterFilter().

Co myślicie o tym rozwiązaniu?