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?

Share Button

3 thoughts on “Własny pingback – kiedy wysłać?

  1. koncepcja mi sie podoba i tak to wlasnie zrobie, na pewno odswieze temat w bardziej szczegolowej formie u siebie na blogu jak juz bede mial dzialajaca implementacje. dzieki

  2. Dobry pomysł. Często podczas implementacji pojawiają się rzeczy, których nie przewidzieliśmy i weryfikują takie teoretyczne rozważania. Czekam na wpis co Ci wyszło w praniu :)

  3. A nie lepiej zainicjować pingowanie “w tle” nie czekając na wynik? albo na zasadzie blox’a czyli po publikacji jquerowy loader w oczekiwaniu na spingowanie – zapytanie zostanie wowczas zainicjowane, a to czy user zaczeka na completed to już tylko jego sprawa :)

Leave a Reply

Your email address will not be published. Required fields are marked *