Autor wpisu: Diabl0, dodany: 29.05.2009 22:25, tagi: zend_framework
Jakiś czas temu stworzyłem prostą klasę do pobierania kursów walut z NBP. Dla przyśpieszenia działania i odciążenia serwerów NBP wykorzystuje ona Zend_Cache do przechowywania danych po pobraniu. Niestety, ostatnio kilka razy zdarzyła się sytuacja że cache się już przeterminował, trzeba pobrać nowe dane a… serwer NBP odpowiada błędem. I wszyscy są wściekli. Pracownicy, bo nie mogą pracować, szefostwo, bo pracownicy nie pracują, oraz ja bo muszę tłumaczyć że nie mam na to wpływu… Jak się jednak okazało - mam
Jak zwykle, wystarczyła dokładniejsza lektura API i odkrycie że metoda Zend_Cache_Core::load ma kilka parametrów, w tym jeden bardzo nas interesujący:
@param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
Wystarczyło teraz troszkę ruszyć palcami i:
/* @var $cache Zend_Cache_Core */ $cache = Zend_Registry::get ( 'cache' ); // UWAGA - porównie z przypisaniem = TUTAJ MA BYĆ POJEDYŃCZY ZNAK RÓWNOŚCI if ($data = $cache->load ( 'Mao_Service_ExchangeRates_NBP' )) { // Pobrano dane z cache i dane są jeszcze aktualne $data = unserialize ( $data ); $this->_dataDate = $data ['_dataDate']; $this->_data = $data ['_data']; } else { // Dane pobrane z cache są przeterminowane, próbujemy pobrać nowe try { $this->_fetchData (); $data = array ( '_dataDate' => $this->_dataDate, '_data' => $this->_data ); $cache->save ( serialize ( $data ), 'Mao_Service_ExchangeRates_NBP', array (), 3600 ); } catch ( Exception $e ) { // Nie udało się pobrać danych z źrudła (przyczyna nas na razie nie interesuje) // Pobieramy dane z cache nawet jeśli są przeterminowane. $old_data = $cache->load ( 'Mao_Service_ExchangeRates_NBP', true ); if ($old_data) { // Na szczęście mamy "stare" dane które możemy wykorzystać $data = unserialize ( $old_data ); $this->_dataDate = $data ['_dataDate']; $this->_data = $data ['_data']; try { // Próbujemy raportować możliwy problem do "systemowego" loggera // Teoretycznie logger powinien być, ale kto wie czy kiedyś ktoś // tego nie wykorzysta gdzieś indzie i będzie się zastanawiał czemu wyskakuje exception $logger = Zend_Registry::get ( 'logger' ); $logger->warn ( 'Mao_Service_ExchangeRates_NBP old data used. Reason:' . $e->getMessage () ); } catch (Exception $e) { // Uuuu... Problem z loggerem? co to za konfiguracja? // Na szczęście to nie jest krytyczny problem więc ignorujemy } } else { // No to mamy spory problem, nie ma ani danych z źrudła, ani danych // Nic więcej nie jesteśmy w stanie zrobić tutaj z tym problemem, // więc wyrzucamy go wyżej throw $e; } } }
Próbujemy wczytać dane z cache. Jeśli nie ma danych lub są przeterminowane ($cache->load zwraca false) to próbujemy pobrać nowe dane z NBP. Jeśli z jakiegoś powodu nie uda się to nam, to ponownie próbujemy pobrać dane z cache tym razem nie zwracając uwagi na ich “przydatność do spożycia”. No i w ostateczności jeśli i to zawiedzie, to i tak jesteśmy na tyle głęboko w czarnej d… że możemy wyrzucić wyjątek wyżej i dać innym zająć się tym problemem. My zrobiliśmy wszystko co w naszej mocy.
Aby dopełnić arta zamieszczam również pełną klasę Mao_Service_ExchangeRates_NBP. Może się komuś przyda.