Renault Espace 6 — pierwsze wrażenia

Od blisko trzech lat jeżdżę Renault Espace 5 generacji, więc z zaciekawieniem przeczytałem informacje o premierze 6 generacji tego modelu.

Renault Espace 6 generacji z zewnątrz

Z zewnątrz samochód wygląda poprawnie, miejscami nawet ładnie. Z drugiej strony jest trochę nijaki, ot kolejny crossover. Wszystkie wcześniejsze generacje były bardziej charakterne, jednym się podobały, innym wręcz przeciwnie, ale nikt nie mógł zaprzeczyć, że się wyróżniają. W środku Espace 6 również wygląda dobrze, choć niczym szczególnym się nie wyróżnia. Wśród danych technicznych moją uwagę zwróciło, że nowy Espace jest mniejszy w każdym wymiarze od poprzednika — jeśli oceniamy go jako samochód rodzinny to może być wadą.

Renault Espace 6 generacji wewnątrz

Gdybym jednak w tej chwili rozglądał się za nowym samochodem to nie brałbym Espace 6 pod uwagę. Bynajmniej nie dlatego, że jest SUV-em (wcześniej rozważałem m.in. Skodę Kodiak), ani dlatego, że jest mniejszy (Citroen C4 Grand Picasso i Peugeot 5008 również są mniejsze od Espace 5). Dla mnie mankamentem nie do zaakceptowania jest kanapa w drugim rzędzie zamiast trzech osobnych foteli.

Trzy osobne fotele z mocowaniami ISOFIX to ogromna zaleta już przy dwójce dzieci w fotelikach, bo foteliki można zamontować na skrajnym i środkowym fotelu zostawiając drugi skrajny fotel łatwo dostępny dla dorosłego pasażera, dajmy na to babci. W wypadku kanapy foteliki trzeba zamontować na zewnętrznych siedziskach, a dorosły pasażer musi się między nimi przeciskać, żeby dostać się do środkowego, najwęższego siedziska. To urąga godności babci!

Jeśli ma się trójkę dzieci jeżdżących w fotelikach to trzy osobne fotele w drugim rzędzie to zbawienie.

Oczywiście mam świadomość, że foteliki można również mocować na pasy i tym sposobem mieć fotelik zamocowany na środkowym siedzisku kanapy. Przerabiałem to, nie podobało mi się, wolę foteliki mocowane na ISOFIXy.

W mojej ocenie Espace 6 generacji to już nie jest samochód dla rodziny 2 + 2 lub większej. Dlatego gdybym w najbliższym czasie szukał samochodu to pewnie Renault Espace 6 nie brałbym pod uwagę. Z drugiej strony samochody rodzinne to ginący gatunek, Citroen C4 Grand Picasso/Spacetourer już nie jest produkowany, podobnie jak Ford Galaxy. Jest jeszcze Ford S-Max i Peugeot 5008, ale ten pierwszy jest już wiekową konstrukcją, zaś drugi nie zachęca ani gamą silnikowa ani cenami. Do dostawczaków zwanych eufemistycznie kombivanami (Citroen Berlingo, Peugeot Rifter) jeszcze się nie przekonałem. Dlatego pewnie będę chciał jeździć Renault Espace 5 do aż do czasu gdy będę potrzebował tylko jednego fotelika.

Inicjalizacja nowego projektu Symfony

W dokumentacji Symfony napisane jest, żeby do inicjalizacji nowego projektu użyć polecenia symfony new albo composer create-project. Jeśli podobnie jak ja nie lubicie instalować PHP z przyległościami lokalnie to można to zrobić z użyciem Dockera.

docker run --rm --interactive --tty --volume $PWD:/app --user $(id -u):$(id -g) composer create-project symfony/skeleton my_project_directory

Elvis w statku kosmicznym

Czy widzicie Elvisa w statku kosmicznym?

usort(
  $data,
  fn(array $a, array $b) => $a['label'] <=> $b['label'] ?: $a['id'] <=> $b['id']
)

Gdzie jest Elvis? Elvis tudzież „Elvis operator” to potoczna nazwa operatora warunkowego ?: który zwraca pierwsze wyrażenie, którego wartość jest prawdziwa. Z kolei statek kosmiczny (ang. „spaceship operator”) to potoczna nazwa operatora <=> który dokonuje trójstronnego porównania wartości.

Powyższy kawałek kodu sortuję tablicę $data po kluczu label, a w wypadku gdy wartości label są identyczne dodatkowo po kluczu id. Dzięki Elvisowi i statkom kosmicznym kod jest bardzo zwięzły.

Czempion zaangażowania

Divante — firma dla której obecnie pracuję — ma zwyczaju przyznawać nagrody dla wyróżniających się pracowników. O takie:

The Engagement Champion Award 2021
The Engagement Champion Award 2021

Trochę mnie to zaskoczyło, bo w mojej ocenie nie angażuję się jakoś wyjątkowo, po prostu staram się dobrze wykonywać swoje obowiązki. Z drugiej strony miło być docenionym.

Czy amplituner to przeżytek?

Wśród moich znajomych nie brakuje elektronicznych gadżeciaży, zazwyczaj mają duże, płaskie telewizory, często najnowsze konsole, itp. Teraz naszła mnie refleksja, że nie znam nikogo, kto oprócz sprzętu wideo miałby sprzęt audio lepszy niż soundbar. Zastanawiam się dlaczego? Czy dźwięk nie jest ważny? Czy może chodzi o to, że rozmieszczenie pięciu, sześciu czy ośmiu głośników, pociągnięcie do nich kabli jest problematyczne? A może po prostu jestem starej daty i teraz amplitunery, kolumny głośnikowe i cała sfera audio to fetysz audiofilów?

Ja audiofilem się nie czuję, oglądając film lub grając w grę lubię usłyszeć dźwiękowe efekty przestrzenne i poczuć jak dudni bas. Muzyki czy nawet radia też przyjemniej słucha się z głośników większych niż pudełko od zapałek.

pg_restore w Dockerze

Taka sytuacja: mamy bazę danych PostgreSQL działającą w Dockerze. Chcemy wgrać dane z kopii zapasowej, ale nie chcemy wrzucać pliku z bazą do kontenera postgresa. Jak to zrobić?

Możemy obok wystartować drugi kontener, w którym plik z bazą udostępnimy przez bind mount i w tym kontenerze uruchomimy pg_restore, który będzie wyrzucać dane na standardowe wyjście, które rurą przekierujemy do właściwego kontenera z bazą. Uff, brzmi skomplikowanie, ale samo polecenie mieści się w jednej linijce:

docker run -v "$(PWD)":/backup postgres:9.4 pg_restore --clean --no-owner --no-privileges /backup/dump.sql | docker-compose exec -T db psql -U dbuser -d dbname

Powyższy przykład zakłada, że kontener Postgresa został uruchomiony przez docker-compose, co najczęściej będzie miało miejsce na lokalnym środowisku developerskim. Jeśli projekt działa w roju (swarm) to polecenie można zmodifikować następująco:

docker run -v "$PWD":/backup postgres:9.4 pg_restore --clean --no-owner --no-privileges /backup/dump.sql | docker exec -i project_db.1.st5j3pz7rre153z7ficb59c9n psql -U dbuser -d dbname

AB testów wydajnościowych

Żeby przetestować wydajność aplikację webowej od A do Z trzeba się nieźle nagimnastykować. Jeśli jednak wystarczą powierzchowne testy, dajmy na to od A do B, to jest na to prosty sposób: ab czyli Apache Benchmark.

Apache Benchmark dobrze się sprawdzi np. w takich scenariuszach:

  • sprawdzenie czy refaktoring konkretnej końcówki API przyniósł wzrost wydajności,
  • testowanie różnych ustawień serwera,
  • obciążenie aplikacji celem sprawdzenia czy autoskalowanie działa.

W poniższych przykładach podaję tylko te argumenty ab, które są istotne dla danego przykładu. W prawdziwych zastosowaniach trzeba do nich dodać np. liczbę zapytań i liczbę równoczesnych zapytań.

Pomijanie loadbalancera

Obecnie serwery aplikacji są częstokroć schowane za loadbalancerem. Testując aplikację najczęściej chcemy uderzać bezpośrednio w nią. W tym celu należy wysłać nagłówek Host zawierający domenę aplikacji, a w URL-u podać serwer z aplikacją (domena lub IP):

ab -H "Host: api.example.org" http://10.1.1.10/endpoint

Autoryzacja

Tu również najczęściej wystarczy podać jeden nagłówek, a konkretnie Authorization:

ab -H "Authorization: Bearer wygenerowany-token" https://api.example.org/endpoint

Formularz

Żeby wysłać formularz metodą POST należy przygotować plik z zawartością formularza. Klucze i wartości powinny być rozdzielone znakiem równości, a kolejne krotki oddzielone znakiem &. Należy pamiętać o kodowaniu znaków niealfanumerycznych. Przykład:

parametr1=wartosc&parametr2=wartosc%20ze%20spacjami&parametr=dodatkowy

Uwaga: wiele edytorów automatycznie wstawia znak nowej linii na końcu każdego wiersza, co ab zinterpretuje jako część ostatniej wartości, co może prowadzić do trudnych do wykrycia błędów. Można to obejść na końcu umieszczając dodatkowy parametr.

Tak przygotowany plik należy podać jako argument dla ab wraz z kodowaniem:

ab -p form-data.txt -T 'application/x-www-form-urlencoded’ https://api.example.org/endpoint

PUT

Poniżej przykład testowania końcówki metodą PUT:

ab -m PUT -H 'Content-Length: 0' https://api.example.org/endpoint/id

Testowana końcówka nie wymaga przesłania danych innych niż te z URL-a, więc niezbędny jest nagłówek Content-Length z wartością 0, bez niego aplikacja rzucała błąd mówiący o niemożliwości sparsowania żądania.

Docker

A co jeśli na maszynce nie ma ab? Jeśli jest Docker to można zrobić:

docker run cmd.cat/ab ab -n 10000 -c 10 https://api.example.org/endpoint

Duplicity i B2 Cloud Storage

Ostatnie wydarzenia w OVH zainspirowały mnie do audytu mechanizmów kopii bezpieczeństwa. Dla moich projektów webowych audyt wypadł pomyślnie, jednak dane z domowych komputerów są backupowane tylko na inny komputer, który także znajduje się w mieszkaniu. W razie pożaru lub kradzieży mógłbym stracić dane oryginalne i ich kopie bezpieczeństwa.

Postanowiłem robić kopie do innej lokalizacji. Na domowych komputerach mam sporo zdjęć i filmów, a to setki gigabajtów, więc koszt przechowywania kopii ma znaczenie. Pod tym względem ciekawie wypada oferta B2 Cloud Storage.

Instalacja Duplicity z wymaganymi zależnościami w Debianie 11 jest banalna:

apt install duplicity python3-b2sdk

Niestety w Debianie 10 to nie działa, brakuje bibliotek dla B2, co objawia się błędem jak poniżej:

BackendException: B2 backend requires B2 Python APIs (pip install b2)

Doinstalowanie ich pip-em nie pomaga. Metodą prób, błędów i szukania znalazłem działające rozwiązanie na forum – należy zarówno Duplicity jak i SDK dla B2 zainstalować przez pip-a:

apt install build-essential python3-dev gettext librsync-dev
pip3 install duplicity
pip3 install b2sdk