View
48
Download
0
Category
Preview:
Citation preview
1. Wstęp
2. Kod legacy
3. Przygotowanie
4. Pierwsze podejście
5. Napotkane problemy
6. Drugie podejście
7. Wady i zalety
8. Co dalej?
Plan prezentacji
Kod legacyProblemy
■ PHP 5.5
■ Yii 1.1
■ Kilka testów (żaden nie działa)
■ Zależności wkomitowane w repozytorium
■ Zmiany w frameworku
■ Niespójna baza ze 170 tabelami, bez kluczy
obcych
KROK 1:
Wdrożenie Dockera dla developmentu
Spójne środowisko i konfiguracja.Ułatwia wdrażanie do projektu i konfigurację środowiska dla nowych developerów.Przejście na PHP 5.6.
KROK 3:
Naprawienie testów i wdrożenie CI
● Tydzień konfigurowania, przepisywania, poprawiania i dopisywania nowych testów.
● Testy uruchamiane w izolacji (Docker) na środowisku CI.
● Wdrożenie mechanizmów statycznej analizy kodu.
Jak przekonać do przepisania?
■ Miej przy sobie eksperta
■ Znajdź luki w kodzie
■ Mniej bugów podczas releasów
■ Dostarcz metryki kodu
■ Napisz test pokazujący niepożądane zachowanie aplikacji
■ Powołaj się na autorytet
■ Zbuntuj się?!
Najpierw powstał planSymfony App
Yii
InternetRequest
Route found in Symfony?
Process Request as usual
yes
Process by LegacyCode\LegacyCodeBundle\Controller\FallbackController
need something from Yii?
no
no
yes
this will be done by “subrequest” with flag $forcePathOverride = true
Create Symfony\Component\HttpFoundation\Response and return it
Spa
Struktura katalogów
● Nowa aplikacja obok starej.● Konfigurowalna ścieżka do
starej aplikacji.● Symlinki do statycznych plików.● Stara aplikacja może działać
samodzielnie gdyby coś poszło nie tak.
Tagi ESI
● Umożliwiają wstrzykiwanie widoków, za które odpowiedzialna jest nowa część aplikacji.
$esi->render('AppBundle:AssignLog:logs',['modelId' => $model->id]
);
Konfiguracja starej aplikacji w Symfony
● Utworzenie node w konfiguracji odpowiedzialnego za starą aplikację.
● Możliwość dziedziczenia dzięki komponentowi Symfony/Configuration
Wstrzykiwanie nowych serwisów do starej aplikacji
● Serwisy z Symfony trzymane w specjalnym kontenerze.
● Wstrzykiwanie kontenera odbywa się w kontrolerze.
Mamy problem
■ Niektóre akcje kończą się exitem
Rozwiązanie?
■ Developer usunął wszystkie exit i zastąpił je returnem
■ Rzucanie ApplicationTerminatedException
ShutdownableKernel
● Obsługuje wywołanie exit() wewnątrz kodu.
● Deleguje utworzenie Response ze zbuforowanego wyjścia i przesyła go do klienta.
ShutdownListener
● Rejestruje metodę shutdown jako shutdown_function przed wywołaniem kodu kontrolera.
● Odwołuje rejestrację w wypadku braku wywołania exit w kontrolerze (poprawnie wygenerowany Response).
OutputBufferListener
● Włącza buforowanie wyjścia przed uruchomieniem kodu kontrolera.
● Ustawia zbuforowane wyjście jako treść odpowiedzi.
ResponseCallbackListener
● Wywołuje callback tuż przed zwróceniem odpowiedzi i umożliwia jej podmianę
OutputBufferListener:Enable buffering
Request
FallbackController:Process request by legacy app
OutputBufferListener:Generate Response from buffer
HeaderListener:Add headers to Response
exit() called?
LegacyHttpKernel:Ask for response and send it to client
ResponseCallbackListener:Use a closure to modify the
Response
Response
YesNo
Logi w Monolog
● Prosty MonologRoute konwertujący wpisy do logów Yii na wpisy Monologa.
● Dodanie Route do komponentu log podczas budowania starej aplikacji
DataCollectors
● Znacznie ułatwiają profilowanie● Pomagają odnaleźć się w
gąszczu szablonów● Wyświetlają logi i zapytania
starej aplikacji
Podsumowanie
■ Znormalizuj kod
■ Pisz testy!
■ Staraj się przepisywać funkcjonalności małymi krokami
■ Twórz metryki w oparciu o statyczną analizę kodu
■ Ułatwiaj sobie życie przy pomocy narzędzi, jakie oferuje
framework
Recommended