SZARP, od samego początku (pomijając krótki okres niemowlęctwa, gdy działał pod kontrolą systemu operacyjnego DOS) posiada architekturę bardzo, w swoim duchu, UNIX-ową. SZARP to kolekcja niezależnych procesów, z których każdy posiada (z grubsza) tylko jedno zadanie i, z założenia, ma je wykonywać idealnie 🙂
SZARP w typowej instalacji składa się z jednego procesu akumulującego dane wszystkich parametrów, oddzielnego procesu zajmującego się zapisywaniem parametrów do bazy, procesu udostępniającego aktualne dane przez protokół HTTP, procesów (zwanych demonami) komunikujących się ze urządzeniami, gdzie często jest to jeden proces uruchomiony na jedno urządzenie.
Wszystkie te procesy wykorzystują „znane i lubiane” UNIX-we mechanizmy komunikacji międzyprocesowej, aktualne wartości parametrów przekazywane są przez segmenty pamięci dzielnej, do której dostęp odbywa się za pomocą klasycznego schematu czytelników i pisarzy, a dane do urządzeń przekazywane są przez kolejki komunikatów.
Poniżej w sposób artystyczny przedstawiono część systemu SZARP zajmującą się akwizycją parametrów oraz mechanizmów komunikacji między tej części składowymi:
Taki sposób zaprojektowania systemu oraz sposób jego implementacji posiada kilka bardzo przyjemnych cech, jak wyraźna separacja między poszczególnymi komponentami i ich zadaniami oraz odporność systemu jako całości na awarie jego pojedynczych komponentów.
Niestety, obecna implementacja posiada też kilka ograniczeń, których świadomość istnienia, z czasem stała się dla nas na tyle dolegliwa, że postanowiliśmy coś z tym zrobić.
Jednym z ograniczeń obecnej architektury systemy jest to, że wartości przemierzające trasę od urządzeń do bazy danych, nie mają związanych ze sobą znaczników czasowych. Założenie jest takie, że wszystko co znajduje się w obszarach pamięci dzielonych to wartości aktualna. Dostęp do tych danych poszczególne komponenty dokonują ze stałą częstotliwością, a dokładny moment kiedy to się odbywa ustalany jest przez tyknięcia zegara danego komponentu (+ ew. oczekiwanie na uzyskanie dostępu do danego obszaru). Ponieważ zegary poszczególnych komponentów nie są ze sobą zsynchronizowane, wrzucając daną wartość do bazy danych, nigdy nie możemy być pewni kiedy dokładnie ta wartość została pobrana – wiemy jedynie że stało się to od 1 do 4 tyknięć zegarów temu. Ponieważ zazwyczaj zegary pracują z wystarczająco szybko, ta różnica nie ma znaczenia. Jednak czasami warto by było być bardziej dokładnym, i szybszym.
Drugą kwestią jest zafiksowanie architektury na jednym typie wartości, 16-bitowych liczbach całkowitych. To co segmenty pamięci dzielonej przechowują, to właśnie tablice 16-bitowych int-ów. Co prawda rzeczywistość jest trochę bardziej skompilowana i SZARP nie ma problemów ze zbieraniem i przetwarzaniem wartości o większym rozmiarze, to faktem jest, że problem ten nie jest rozwiązany w sposób systematyczny.
Jak więc sugeruje tytuł tego tekstu, postanowiliśmy przebudować odrobinę istniejącą architekturę SZARPa.
Zatem, już bez dalszych wstępów, Panie i Panowie, oto przed Wami – projekt nowego SZARPa! (replika pracy anonimowego artysty z XXI wieku)
Jak można zauważyć, istnieje kilka zasadniczych różnic między istniejącą a planowaną architekturą. Przede wszystkim, głównym mechanizmem komunikacji miedzy procesami nie jest już pamięć dzielona, a sockety ZeroMQ pracujące w schemacie producent-konsument.
Pojawia się nowy, centralny komponent systemu parhub, którego zadaniem jest rozgłaszanie otrzymanych komunikatów (wysyłanych głównie przez demony), do wszystkich zarejestrowanych konsumentów. Parhub jest to jedyny proces, z którym muszą się komunikować pozostałe komponenty systemu.
Drugą istotną zmianą jest to, że wartości przesyłane w komunikatach zawierają znacznik czasowy. Niezależnie od tego jak długo dany kounikat podróżował do celu, zawsze jesteśmy w stanie precyzyjnie powiedzieć kiedy dokładnie dana wartośc została pobrana. Poza tym, komunikaty są przesyłane asynchronicznie, a zatem komponent otrzymujący komunikat może zacząc jego przetwarzanie natychmiast, nie będąc związany tyknięciami żadnego zegara.
Istotną zmianą jest również to, że wartości parametrów przesyłane w komunikatach mogą mieć różne typy i rozmiary.
Bardzo ważną cechą nowej architektury jest fakt, że parcook może zostać do niej wpięty jako jeszcze jeden demon, co pozwoli na jej stopniowe wdrażanie, bez konieczności przerabiania od razu wszystkich demonów na nowy sposób komunikacji.
Teraz wystarczy tylko zakasać rękawy i do roboty! 🙂