Skip to main content
Ze zákulisí
Ze zákulisíEngineeringDecisions

Co nás naučil bot na více než 2 000 Discord serverech

Čtyři věci, které ve velkém fungují jinak, než předpokládáš, když píšeš kód.

Zveřejněno od AlphaCloud3 min čtení

Discord bot na třech serverech a stejný bot na více než dvou tisících nejsou tentýž program, jen ve větší velikosti. Hrstka předpokladů, které jsou v malém úplně neškodné, se od určité velikosti stane právě těmi chybami, které se hledají nejhůř.

Tady jsou čtyři, které nás stály skutečné výpadky.

1. Výpadky se nešíří rovnoměrně, schovávají se

AlphaCloud běží rozdělený do několika procesů, kterým se říká shardy. Discord rozhoduje, který server přistane na kterém shardu, a každý shard zná jen své vlastní servery.

Z toho vzniká třída výpadků, která zvenku vypadá jako náhoda: uvítací zprávy na některých serverech fungují a na jiných ne. Žádná chyba v logu, žádné upozornění, nic. Příčinou bylo jediné síťové volání bez časového limitu. Pokud druhá strana spojení přijme a pak zmlkne, kód čeká po zbytek života procesu. Všechno po něm se nikdy nestane, a protože se nevyhodí žádná chyba, nic žádnou chybu nehlásí.

Ponaučení je nenápadné a univerzální: každé odchozí volání potřebuje horní hranici. Volání, které čeká navždy, je horší než takové, které selže, protože selhání je aspoň vidět.

2. Restart není oprava, je to lhůta

Dokud jsme neznali příčinu, restart postiženého shardu spolehlivě pomáhal. Přesně v tom je problém restartů: fungují, a tím mizí tlak najít příčinu.

Otázku „pomůže restart?“ teď bereme jako diagnózu, ne jako lék. Pokud pomůže, rozbitý stav žije v paměti a v kódu je místo, které ho vytváří a nikdy neuklidí.

Platí to i obráceně: cokoli, co musí přežít restart, patří do databáze. Pokud běží vícekroková operace, třeba změna rolí napříč tisíci členy, a proces uprostřed spadne, operace nesmí prostě zmizet. Musí se při dalším startu rozpoznat a pokračovat.

3. Limity Discordu platí pro bota, ne pro proces

Discord omezuje, kolik požadavků smí bot za sekundu udělat. Zjevný předpoklad: víc procesů, větší propustnost. Špatně. Limit je na botovi, ne na procesu. Tři shardy, každý s plným rozpočtem, dohromady dají trojnásobek povoleného a Discord pak přiškrtí všechny tři.

Každý z našich procesů si proto spočítá, kolik jich celkem existuje, a vezme si jen svůj podíl. Zní to samozřejmě, ale nebylo to tak, a ta chyba zůstala dlouho neviditelná, protože každý jednotlivý proces vypadal sám o sobě naprosto slušně.

Příbuzná past: opakované úlohy běží v pevných intervalech, třeba každých pět minut. Pokud všechny shardy startují ve stejnou chvíli, spouštějí své úlohy navždy ve stejném okamžiku. Od té doby dostane každý proces při startu náhodný posun.

4. Co lidé skutečně nastavují, není to, co čekáš

Technická část je jedna polovina. Ta druhá: pro většinu serverů je výchozí hodnota tím nastavením. Modul se špatnými výchozími hodnotami je na naprosté většině serverů špatně nastavený, ať je stránka s nastavením sebelepší.

Plynou z toho pro nás dvě věci. Zaprvé každá výchozí hodnota stojí víc přemýšlení než samotné nastavení. Zadruhé lepší otázka u nového modulu nezní „co se tu dá nastavit“, ale „co tenhle modul dělá, když nikdo nic nenastaví, a je to správně pro normální server“.

To je také důvod rozhodnutí, které na první pohled zní jako opak: od v1.8.0 se dá skoro každá zpráva, kterou bot posílá, volně navrhnout. Povinné bloky jako důvod v DM s varováním nebo menu kategorií v panelu tiketů ale jde přesunout, ne smazat. Volnost v designu ano, ale ne do té míry, aby si server omylem postavil něco, co vypadá, že funguje, a nefunguje.

Společná nit

Tři ze čtyř jsou stejná myšlenka v různých převlecích: v téhle velikosti je tiché selhání dražší než hlasité. Pád se nahlásí a opraví. Funkce, která prostě přestane cokoli dělat, tak může zůstat měsíce a dozvíš se to z hlášení chyby od někoho, kdo si dal tu práci a napsal ho.

Proto se teď u nového kódu jako první neptáme „funguje to“, ale „jak to vypadá, když to nefunguje, a všimli bychom si toho“.

Další články