Architektura zpracování datových proudů v Elixiru: od Hello, World! k volnému propojení
Vývoj systému interagujících enginů v Elixiru vyžaduje jasné oddělení vrstev a integraci s externími závislostmi. V tomto článku se zaměřujeme na implementaci základních uzlů pro zpracování datových proudů, včetně zdrojů, spotřebičů a centrálního dispečera, s důrazem na architektonické principy a praktická řešení.
Systematizace hardwarových uzlů a klasifikace
Při zpracování datových proudů hrají klíčovou roli koncové uzly grafu, které komunikují s hardwarem. Na spodní vrstvě se nacházejí zdroje dat, které lze klasifikovat podle typu vstupu:
- Klávesnice (Setpoint): pro zadávání alfanumerických informací, například nastavených hodnot v řídicích systémech.
- Pravidelné brány (R_gateway): ovladače sběrnic s pravidelnými daty, jako je Modbus, používané v průmyslové automatizaci.
- Nepravidelné brány (Ir_gateway): adaptéry pro spontánně přicházející data, například Can-sběrnice v moderních automobilech připojená k centrální řídicí jednotce.
Na horní vrstvě jsou spotřebitelé dat, zařazení do třídy Stock:
- Displeje pro zobrazování informací.
- Souborové systémy pro zaznamenávání událostí a chyb.
- Databáze nebo úložiště jako mezilehlé akumulátory.
- Systémy vyšší úrovně, umožňující propojování enginů do řetězců přes bránové uzly.
Taková klasifikace umožňuje vytvořit graf toku dat, kde uzly spodní úrovně předávají informace uzlům horní úrovně, zatímco na počáteční fázi se vynechává mezilehlá vrstva enginů.
Implementace základních uzlů a simulace proudů
Pro demonstraci fungování systému byly implementovány tři uzly-zdroje a jeden uzel-spotřebič bez použití šablony GenServer OTP. Tyto procesy jsou založeny na cyklických funkcích loop, což zjednodušuje architekturu a snižuje složitost:
- Modul pro vstup dat z terminálu: umožňuje ruční zadávání alfanumerických informací, například fráze "Ahoj, světe!".
- Simulátor pravidelných dat: nekonečně odesílá do proudu repliku "Hello, " s periodicitou 1 sekunda.
- Simulátor spontánních dat: nekonečně odesílá do proudu repliku "World! " s periodicitou až 1 sekunda.
- Terminál výstupu: zobrazuje alfanumerické informace na obrazovce, přijímá data od všech zdrojů.
Mezilehlá vrstva enginů zůstává prázdná, což odpovídá záměru vyloučení enginů z počáteční implementace. Kód po přidání pracovních enginů bude zveřejněn na GitHubu, což zajišťuje transparentnost a možnost dalšího rozvoje.
Rozdělení terminálů a centrální dispečer
Jedním z klíčových úkolů byla organizace terminálového vstupu/výstupu, vázaného na lokální proces. Standardně Erlang shromažďuje vstup/výstup ze všech uzlů na jeden terminál pro centralizovanou správu, což ne vždy odpovídá požadavkům distribuovaných systémů. Řešení bylo nalezeno s použitím operátoru:
:global.register_name(:stock_ldr, :erlang.group_leader)
To umožnilo rozdělit systém na specializované terminály, ačkoli hledání řešení zabralo značný čas kvůli nedostatečné dokumentaci k tématu.
Pro načítání a spouštění systému byl vytvořen centrální dispečer. V kontextu integrace s externími knihovnami v Elixiru se doporučuje vytvořit jednotný interní modul pro interakci s externími závislostmi, což přispívá k volnému propojení. Hexagonální architektura navrhuje umisťovat externí závislosti na periferii aplikace, odděluje obchodní logiku od vedlejších efektů. V praxi však dosažení tohoto principu může být složité, zejména při přítomnosti mnoha externích modulů, jako jsou hardwarové brány a spotřebitelé dat.
Architektonické principy a rozšiřitelnost systému
Navrhovaný systém interagujících enginů je otevřený pro rozšíření, kde jakýkoli koncový uzel grafu slouží jako brána (gateway) pro integraci s externím světem. To umožňuje volně přidávat uživatelské softwarové komponenty a rozvíjet systém v aplikované oblasti. Důležité upozornění: systém enginů neroste "nahoru", ale prorůstá "dolů" do aplikovaných oblastí, což mění stereotypní pohled na architektonický vývoj.
Klíčové aspekty pro vývojáře:
- Použití jednoduchých procesů s loop namísto GenServer OTP pro základní uzly může zjednodušit implementaci, ale vyžaduje promyšlené zpracování chyb.
- Rozdělení terminálů přes :global.register_name řeší problém centralizovaného vstupu/výstupu v Erlangu.
- Volné propojení s externími závislostmi zůstává složitým úkolem, navzdory doporučením pro hexagonální architekturu.
Co je důležité:
- Klasifikace uzlů na R_gateway, Ir_gateway, Setpoint a Stock zajišťuje jasnou strukturu zpracování proudů.
- Implementace simulátorů dat demonstruje fungování systému bez mezilehlých enginů.
- Rozdělení terminálů vyžaduje netriviální řešení v Erlangu/Elixiru.
- Centrální dispečer a integrace s externími závislostmi dodržují principy volného propojení.
- Systém je otevřený pro rozšíření přes bránové uzly, rozvíjející se v aplikované oblasti.
— Editorial Team
Zatím žádné komentáře.