Vývoj: postupné změny v backendu

Může se zdát, že vývoj aplikace stagnuje a "nic se neděje". Aktuálně probíhají menší změny na pozadí. Zkusím teď popsat, co a proč se vývoji odehrává. Následující článek je čistě pro vývojáře.

Aplikaci jsem začal vyvíjet v únoru 2014 jako diplomku. Od té doby jsem přešel z akademického prostředí do práce jako programátor a z Windows na Linux/MacOS. Změny nejsou nijak revoluční, ale spíše evoluční, kdy aplikuji zkušeností a praktiky z práce.

1. Verzování: hg → git

Dříve jsem preferoval Mercurial kvůli:

  • jednoduchosti, resp. git mi připadal více kryptický
  • TortoiseHg klientovi, resp. Sourcetree byl na starém Windows notebooku extrémně pomalý

V každém mém zaměstnání byl a je git standardem. Zvyknul jsem si na něj, hlavně na staging změn. Paradoxně pro hg fandy může být chybějící staging výhoda. Ale pro mě bylo přepnutí do hg bolestivé, když jsem udělal refresh a neviděl jsem provedené změny a nemohl je rychle vrátit zpět.

Co se týče klientů, tak na Macu je Sourcetree jednička. Na Linuxu byla situace o dost horší, ale s příchodem gitkraken už není gitový klient bottleneck ani na Linuxu (možná to platí i pro Windows).

Commity jsem zmigroval pomocí fast-exportu. Jedním dodatečným commitem jsem zavedl .gitignore místo .hgignore.

screenshot from 2016-12-18 17 20 02

2. CI: ruční skripty → automatizace

Dokud člověk pracuje sám, má jeden notebook, tak CI není nutnost, nebo ano?

Integrační server je nahrazen skriptem, který spouští nástroje z PHP Quality Assurance Toolchain. Dosud jsem neměl potřebu zavěšovat hooky ve verzovacím systému pro automatické spouštění testů a integračního skriptu. Všechny testy spouštím v Netbeans před commitem a integrační skript většinou na konci iterace.

- akademické já v roce 2014

Stačí změna notebooku i operačního systému a najednou padají testy, kód obsahuje záhadné závislosti apod. Místo opakování procesu, tj. zprovoznění projektu na lokále, doporučuji zprovoznit projekt na jakémkoliv integračním serveru. Ideálně bez přímého přístupu na server jen pomocí konfiguračního souboru jako travis.yml, circle.yml, …

Přechod nemusí být rychlý ani jednoduchý, pokud doteď aplikace prostě funguje "u mě a na serveru" a konfigurace není kompletně verzovaná (např. prázdné ručně vytvořené složky). Sám jsem tím strávil cca 4 hodiny a desítky nepovedených buildů.

Pár zelených buildů bylo i dříve, ale to jsem např. vypnul testy.

3. HTTP framework: phalcon → silex

Nepamatuji si přesně důvod, proč jsem zvolil Phalcon. Nejspíš kvůli rychlosti. Byla to hodně předčasná optimalizace. Ušetřil jsem možná pár milisekund uživatelům, ale sobě jsem přidal čas zprovozněním phalconu na circle.ci a hledáním hostingu.

Pokud bych musel dělat zásadní rewrite aplikace, tak bych se do změny frameworku nikdy nepouštěl. Ale používal jsem jen micro aplikaci pro routování, takže se změnila jen oddělená API vrstva + místo extension se závislosti přesunuly do composer.lock.

git diff

4. Logování chyb: soubory → cloud

Testy nikdy nepokrývají všechno, takže je nutností rychlá informace o případné chybě. Obzvlášť když změníte framework. Aplikace je spíše statická, takže jsem si vystačil s logováním do souboru, který jsem čas od času zkontroloval.

V Atoto se mi zalíbilo logování do Sentry. Po experimentech jsem tady použil loggly. Integrace po přechodu na PSR-3 logger proběhla hladce. Logovací služby jsou různě omezené, takže jako záloha stále poslouží soubor.

$monolog = new \Monolog\Logger(
    'REST API',
    [
        new \Monolog\Handler\StreamHandler('var/log/exception.log'),
        new \Monolog\Handler\LogglyHandler(LOGGLY_TOKEN . '/tag/monolog'),
    ]
);
$monolog->addCritical($exception->getMessage(), $context)

Proč jsem vlastně vůbec něco měnil?

Prvotním impulsem byla analýza kódu. Předtím jsem používal lokální historii buildů a chtěl jsem přejít na circle.ci s automatickým ukládáním historických artefaktů:

  1. circle.ci podporuje jen git repa → přechod z hg na git
  2. zprovoznění buildu → explicitní definice všech závislostí a automatizace
  3. zdlouhavé zprovoznění Phalconu → Silex dostatečně stačí pro moje potřeby
  4. chci rychle vědět hned o chybách po změně frameworku → přechod na Monolog a loggly

Může se zdát, že jde o náročné změny, které se nikdy nevyplatí, ne? Ušetřený čas se těžko sleduje a ještě hůře obhajuje! Oproti příliš snadnému poukázání na "ztracený" čas (refactoring, testy, zprovoznění integračního serveru, …)