Node-architecture #1. High-Reliability система: теорія

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

                [приклади наведені на Python]

Критерій High-Reliability означає «високу надійність», «витривалість» софта в агресивних умовах. Навіть якщо загублений контакт з датчиками, впав доступ до сховищ, зникло підключення до мережі, відмовила частина модулів самого софту — решта компонентів програми продовжують виконувати свою роботу настільки, наскільки це можливо фізично.

Одне з рішень — проектування програми як сукупності «вузлів». Не плутати з ООП або мікросервісами. Node — це Callable adjective елемент, який має можливість бути запущеним безпосередньо, тобто містить в собі секцію if __name__ == "__main__": … Node не обтяжений залежностями та не заплутаний у зовнішніх зв’язках (coupling). Він автономний настільки ж, наскільки автономна будь-яка команда Python і може використовуватися в складі іншої якоїсь структури, аби співпав API.

  • Вузол має зону відповідальності, яка недосяжна зовні. Сутності, що знаходяться в цій області та підпорядковані безпосередньо вузлу, називаються сателітами. Важливо: це не тип, це роль. Сателітом може бути як найпростіша функція print("World of Hell"), так і повноцінний Node, що містить складну багаторівневу структуру
  • Для взаємозв’язку вузлів у просторі додатка створюється environment, середовище, що містить спільні розділювані ресурси, як мінімум два компоненти: сховище з функціоналом нормалізації (яке незалежно від типу та виду вхідних даних повертає результат у єдиному обумовленому форматі) та транспорт, здатний прийняти й передати дані між будь-якими вузлами.
  • Кожний вузол має сценарій локальної деградації, «дефолтну інструкцію» поведінки у разі відриву від спільного середовища взаємодії, він продовжує виконувати роботу в межах своєї функціональності.
  • Important : ніяких горизонтальних зв’язків проміж вузлами. Жоден із вузлів не повинен «припускати чи мати на увазі» наявність іншого вузла та будувати свою роботу, спираючись на очікувану поведінку іншого компонента

Приклад реалізації нода:

import datetime
# --- BUSINESS LOGIC (Doers / Satellites) ---
# Satellites are not aware of buffers or time. Only pure mathematics.
def _sum_processor(data_list):
    """Satellite: Pure Addition Function."""
    return sum(data_list) if data_list else None

def _format_packet(result):
    """Satellite: packing in a standard package."""
    return {
    'timestamp': datetime.datetime.now().isoformat(),
    'payload': result
    }

# --- INTERFACE & CONFIGURATION (Setters / Node Logic) ---
def run_sum_node(buffer_source):
    """
    NODE: 'Adder' node.
    Implements a local degradation scenario.
    """
    # 1. Data retrieval (Environment/Buffer simulation)
    raw_data = buffer_source if isinstance(buffer_source, list) else []
    #2. Calling a satellite (logic)
    calculation = _sum_processor(raw_data)
    # 3. Output normalization (packing)
    # Even if calculation is None, return a structure, not an error.
    return _format_packet(calculation)

# --- BUILDING & RUNNING ---
if __name__ == '__main__':
    # Test 1: Normal
    test_buffer = [10, 20, 30]
    print(f"Normal work: {run_sum_node(test_buffer)}")
    # Test 2: Aggressive environment (no data) — Local degradation
    empty_buffer = None
    print(f"Degraded work: {run_sum_node(empty_buffer)}")

Інша ілюстрація реалізації вузла, більш «описова». Умовний бойовий дрон, споряджений на даний момент штурмовою гвинтівкою NATO.

{
  "node_name": "Right_Arm_Subsystem",
  "role": "SYSTEM_INTEGRATOR",
  "comment": "Top-level control of the right limb",
  "satellites": [
    {
      "name": "Weapon_Unit",
      "role": "COMPLEX_SATELLITE (NODE)",
      "status": "Active",
      "internal_structure": {
        "node_name": "Rifle_Module_MK1",
        "description": "Automatic weapon module",
        "satellites": [
          {
            "name": "Magazine_Slot",
            "role": "COMPLEX_SATELLITE (NODE)",
            "state": {
              "magazine_type": "NATO_Standard_20",
              "inventory": {
                "Armor_Piercing": 200,
                "Incendiary": 52,
                "Standard": 800
              }
            },
            "degradation_protocol": {
              "on_empty": "Signal_Reload_Request",
              "on_jam": "Switch_to_Manual_Eject"
            }
          },
          {
            "name": "Optics_Sentry",
            "role": "SIMPLE_SATELLITE",
            "task": "Barrel angle adjustment based on wind sensors"
          }
        ],
        "degradation_protocol": {
          "on_overheat": "Reduce_Rate_of_Fire",
          "on_magazine_lost": "Lock_Trigger_Safe"
        }
      }
    },
    {
      "name": "Shoulder_Servo",
      "role": "SIMPLE_SATELLITE",
      "task": "Recoil vector compensation"
    }
  ],
  "global_degradation_protocol": {
    "on_limb_loss": "Isolate_Neural_Link",
    "on_power_critical": "Lock_In_Current_Position"
  }
}
  • Вкладена автономія: Якщо рівень Weapon_Unit «вистрілено», рівень Right_Arm_Subsystem не падає. Вона переходить у on_limb_loss (ізоляція зв’язків). Він щойно перестав отримувати дані від сателіта, але сам живий.
  • Сценарій на будь-який випадок: У кожного рівня свій Default.
  • Порожній магазин? Вузол «Зброя» просто не одержить набій, але продовжує відстежувати ціль.
  • Зброя перегрілася? Вузол «Рука» продовжує тримати напрямок, але не тисне на спуск.
  • Ізоляція складності: Програмісту, який прише логіку Right_Arm_Subsystem, не потрібно знати, скільки бронебійних набоїв в магазині і чи є такі взагалі. Він спілкується лише з Weapon_Unit. Інформація про набої схована за трьома периметрами захисту. Це і є дисциплина кордонів.

Продовжуючи ідею «робота»: якщо він скачає ПДР Японії з усіма їх особливостями, це ніяк не торкнеться функціоналу «правої руки з автоматом». І якщо не скачає, а зависне чи буде змушений ходити пішки — теж. Навіть якщо тіло робота рознесе прямим влученням ракети, у ноді «Права Нога» залишаться сателіти «GPS» та «боді-камера», які продовжать працювати.

ХарактеристикаООП (Успадкування)Node-architecture (Роль)
Пов’язаністьЖорстка (Tight coupling). Нащадок фізично залежить від наявності батьківського класу в пам’яті.Нульова. Вузол самодостатній і не потребує зовнішніх декларацій для ініціалізації.
Точка відмовиБазовий клас. Зміна або баг у Base каскадно руйнує всіх нащадків.Локалізація. Помилка в «Батьку» (Директорі) не впливає на працездатність автономного «Васала».
ІмпортВимагає import усієї гілки предків. Порушення шляху імпорту робить код непрацездатним.Вузол — точка входу (main). Увесь необхідний код для виживання знаходиться всередині або в сателітах.

Protocol / Interface vs. Рантайм-контракт

Стандартні typing.Protocol або ABC фіксують наявність методів, але не гарантують поведінку системи в агресивному середовищі.

  • Protocol (Static/Structural Typing): Декларує, що об’єкт має метод .fire(). Якщо метод не знайдено на етапі виклику або імпорту — додаток генерує AttributeError або не проходить перевірку типів.
  • Node Contract: Вузол не просто «обіцяє» наявність методу. Він гарантує результат. Якщо внутрішня логіка (сателіт) не може виконати завдання, Вузол зобов’язаний повернути нормалізовану відповідь згідно зі сценарієм локальної деградації.

Принцип ізоляції: Якщо Protocol — це форма ключа, то Вузол — це шлюз. Шлюз не просто перевіряє форму ключа, він забезпечує автономну роботу відсіку, навіть якщо ключ зламаний або відсутній.

Тип (Type) vs. Роль (Role)

Ключова відмінність в управлінні життєвим циклом та областю видимості.

  • Тип — це глобальна ідентичність. Клас Ammunition залишається ним у всіх частинах додатка. Його методи доступні кожному, хто має посилання на об’єкт.
  • Роль — це контекстна ідентичність. Один і той же фрагмент коду може виступати в різних ролях залежно від місця в каскаді: — Вузол-Директор: При запуску як оркестратора зовнішньої логіки (наприклад, імпорт сторонніх важких бібліотек).
    • Сателіт: При виклику як внутрішнього ресурсу іншого Вузла.
    • Точка входу: При автономному запуску для самотестування або локальної роботи.

Інкапсуляція vs. Дисципліна кордонів

В ООП інкапсуляція має рекомендаційний або синтаксичний характер (_private, __mangled). У вузловій архітектурі це механічна заборона.

  1. Заборона горизонталі: Жоден вузол не може «припускати» наявність сусіда. Обмін інформацією — суворо через Environment (Транспорт/Сховище). Це виключає створення «павутини залежностей», характерної для ООП-проєктів.
  2. Герметичність сателітів: Сателіт не має власного API для зовнішнього світу. Спроба викликати сателіт в обхід його Вузла — це порушення протоколу. Вузол є єдиним легальним фільтром, який приймає зовнішнє живлення та розподіляє його між своїми васалами.

Підсумковий тезис

Якщо ООП прагне до повторного використання коду через абстракцію, то Node-architecture прагне до незалежності виконання через ізоляцію.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному4
LinkedIn
Ctrl + Enter
Ctrl + Enter

вот бы это все на машине Кузьмина запустить

На моей архитектуре это все есть. И без лишних сущностей. Все до банальности просто Событие-подписка.

Без конкретных примеров, конечно, сложно понять, чем это особенно полезно по сравнению со множеством уже существующих вариантов.

Активное (акторное) ООП, обычно связанное с именем Алана Кея и реализациями Simula и Smalltalk, уже вспомнили. По крайней мере там похожее то, что акторы (могут быть названы «процессами») работают как независимые активные сущности и обмениваются сообщениями для взаимодействия.

Ещё очень близкая схема сделана в Erlang/OTP. «Процесс» принимает и посылает сообщения; почти всё внешнее взаимодействие сделано через аналогичные точки обмена сообщения. OTP добавляет иерархию контроля, которая обеспечивает рестарт в случае вылета, а в тяжёлых случаях — передача ответственности на другой узел (там узел это общий системный процесс, который запускает акторы). Есть средства для облегчения этим рестартам и передачам в простых случаях.

Чем ваше предложение хорошо и/или ново на их фоне, пока непонятно. Меня начинает смущать вот это:

Жоден вузол не може «припускати» наявність сусіда.

Чем этот сосед так важен или неважен, какую роль он играет — непонятно. В общем случае подобный компонент имеет таки право предполагать наличие каких-то общих сервисов, и тех, с кем ему надо взаимодействовать; если без них работать не кем, то в чём собственно хитрость?

Жду второй части, но на сейчас мне кажется, что разрезание на части сделано как-то странно.

Давайте устроим пятиминутку занимательной психологии на основе Вашего поста. Чисто в познавательных целях, голый анализ, никакого негатива.

чем это особенно полезно по сравнению со множеством уже существующих вариантов
там похожее
сделано через аналогичные

На сегодняшний день существует около 10 «фундаментальных» операционных систем и порядка 250 «исторически значимых», включая проприетарные «микро-ОС» для микроконтроллеров, не являющиеся дистрибутивами, а написанные с нуля под конкретное железо и под крайне узкий круг задач.
Языков программирования, на которых пишут реальный код прям сегодня — около 300.
И весь этот зоопарк крутится на одной и той же двоичной системе, где просто нули и просто единицы, ничего нового. Как думаете, им всем просто заняться нечем или ждут, когда же наконец найдётся решительный человек, который припечатает: «ну всё, ТЕПЕРЬ достаточно и БОЛЬШЕ не нужно»? Ведь всё это одни и те же нули и единицы, унылое бинарное однообразие.
Не бывает «лучше» в вакууме, бывает среда и задачи.

Второй момент. Я поискал в Google, но не смог найти ту линейку, согласно показаниям которой определяется, что отличие объекта измерения от прочих приобрело статус «особенного». То ли у меня Google просроченный, то ли искать не умею...

Третье. Профессиональный вопрос як уповноваженому по милицях. Если кто-нибудь изобретёт что-нибудь ОСОБЕННОЕ, то есть фундаментально-революционное, которое перевернёт весь мир, позволит смести всех конкурентов, получать сказочные прибыли, обзавестись огромным влиянием, при этом простое в реализации и не стоящее почти ничего, а потом бесплатно выложит свою идею со всеми подробностями на открытом общем ресурсе — как считаете, это будет эпический лошара или уже неэпический, то бишь легендарный?

В общем случае подобный компонент имеет таки право предполагать наличие каких-то общих сервисов

Вот просто прибили на месте, как муху газетой, ни отнять ни прибавить. Действительно, о какой автономности может идти речь, если любой код зависит от каких-нибудь общих сущностей... ой, стоп, а что это:

Для взаємозв’язку вузлів у просторі додатка створюється environment, середовище, що містить спільні розділювані ресурси, як мінімум два компоненти: сховище з функціоналом нормалізації (яке незалежно від типу та виду вхідних даних повертає результат у єдиному обумовленому форматі) та транспорт, здатний прийняти й передати дані між будь-якими вузлами.

— а хотя какая разница, написано и написано, на заборе ещё и не такое напишут. Так вот, а вся программа целиком зависит от своей языковой среды, которая в свою очередь ни на что не годна без окружающей её операционной системы, которая... Растянуть эту сову до масштабов вселенной и на этом можно остановиться на первый раз. Но как жить теперь, и, главное — зачем?

Ну и единственный конструктивный вопрос, насчёт такой жёсткой автономности — да, на этом действительно всё и построено. Щас, ещё немного, потому что иначе сами ругаться будете, что «не статья, а каша» :)

Давайте устроим пятиминутку занимательной психологии на основе Вашего поста.

Вы уже устроили, спросив разрешения, я так понимаю, только для вежливости.
Но я, прочитав ваш комментарий, не смог из него вычислить для себя ничего конструктивного для данного разговора. Вероятно, я чего-то не понимаю:)

а хотя какая разница, написано и написано, на заборе ещё и не такое напишут.

Грокнуть сие, мягко говоря, сложно. И какое отличие этого самого «сховища з функціоналом нормалізації» от другого прикладного компонента, и что кроме хранилища с транспортом должно быть. Мне таки кажется, что должно быть что-то ещё.

да, на этом действительно всё и построено.

Ну вот потому я и говорю, что без следующих частей, мягко говоря, непонятно, кто тут на ком вообще стоял и чем запивал.

В принципе согласен. За исключением мелочей.

программа целиком зависит от своей языковой среды, которая в свою очередь ни на что не годна без окружающей её операционной системы, которая...

зависит от архитектуры..
и

И весь этот зоопарк крутится на одной и той же двоичной системе, где просто нули и просто единицы, ничего нового.

новое у меня есть. В памяти не двоичный массив, а концепты (структуры построенные по единым правилам).

Контент якого ми заслуговуємо

Он самый. Ссылочку на linkedin исправьте, а то только через поиск доступно.

А який контент ви бажаєте тут бачити?

Господин, с регалиями больше, чем ветеран трёх войн рассчитывал найти здесь халяву:

Если кто-нибудь изобретёт что-нибудь ОСОБЕННОЕ, то есть фундаментально-революционное, которое перевернёт весь мир, позволит смести всех конкурентов, получать сказочные прибыли, обзавестись огромным влиянием, при этом простое в реализации и не стоящее почти ничего, а потом бесплатно выложит свою идею со всеми подробностями на открытом общем ресурсе — как считаете, это будет эпический лошара или уже неэпический, то бишь легендарный?

Но ушёл разочарованным, не его день.

Ну то есть Вы понимаете, что чел с таким багажом мог бы буквально в одной строке сказать, «что здесь получилось» и «что здесь не получлось». Но...)))

Складно написано

Node-architecture

Дайте посилання на першоджерело. Чи це є ваша оригінальна ідея?

Якщо ООП прагне до повторного використання коду через абстракцію, то Node-architecture прагне до незалежності виконання через ізоляцію.

Якщо коротко, то це твердження не правда, принаймні те що стосується ООП.
Те що описано в статті, дуже схоже якраз на ООП в своїй оригінальній формі (дещо схоже на актори) wiki.c2.com/?AlanKayOnMessaging

Те що в порівняльній таблиці — м’яко кажучи спірні твердження. Хоча б

Точка відмови Базовий клас. Зміна або баг у Base каскадно руйнує всіх нащадків. Локалізація. Помилка в «Батьку» (Директорі) не впливає на працездатність автономного «Васала».

Вим ніхто не заважає в ооп писати так, що помилка не каскадується. Інша історія, що відгорожуючи одну функцію від зовнішнього світу, ви додаєте інфраструктурну (не дотичну до бізнес логіки) складність.

UPD.
Також складається враження, що змішані логічний і фізичний рівні проектування

wiki.c2.com/?AlanKayOnMessaging

Есть такое понятие, «конвергентная эволюция». В биологии это когда существа из разных сред приходят к одинаковым формам, потому что они оптимальны (как обтекаемая форма у дельфина и акулы). Если Вы увидели нечто общее и считаете, что это хорошо — это констатация факта, что это действительно хорошо. Спасибо.

Я впервые слышу об этом авторе и впервые вижу, что он писал двадцать с лишним лет назад, уже тогда сожалея, что всё пошло не так, как он представлял. И здесь великолепным примером является какой-нибудь прекраснодушный светлый мыслитель, который сидит тихонько и внутри своей головы представляет некий «правильный ислам», каким он, по его мнению, мог бы стать, если бы всё подразумевали как надо, а на некоторых моментах не заостряли внимание... А в это время миллиарды индивидуумов на протяжении 1200+ лет непрерывно и повсеместно демонстрируют в реальности, что такое есть ислам на самом деле. Поэтому и говорю, к РЕАЛЬНОМУ ООП изложенное не относится. Да и вообще это разные плоскости восприятия, «тип» не означает «роль», а на одном обмене сообщениями далеко не уехать, лягушки тоже обмениваются, но они тоже не ООП.

Вим ніхто не заважає в ооп писати так, що помилка не каскадується.

Никто не мешает, но никто так не делает, добро пожаловать в мир реального ислама ООП. В Node же нельзя писать по-другому, и это не по синтаксической или технической причине (улавливаете, как «классы» исчезли где-то за кадром?), а потому что таков устав функционирования.

ви додаєте інфраструктурну (не дотичну до бізнес логіки) складність

Именно поэтому это и обозначено словом «enviroment», такова цена надёжности. И это я ещё близкий к реальности код не показал, там обвес ещё более плотный. При этом, как и всякое окружение, это создаётся один раз, а дальше содержимое модифицируется и масштабируется по потребностям. Вот, кстати, могли бы «плагины» вспомнить, это намного ближе по сути, чем ООП, хотя тоже не оно, «У них там всё почти так же, как здесь, но всё же немного по-другому... Всё дело в маленьких различиях». А если следовать Вашей логике, то самое время схватить огнемёт и сжечь Django, FastAPI, Spring и все до единого прочие фреймворки, потому что они на 99% состоят не из бизнес-логики, а из какой-то там инфраструктуры и метапрограммирования.

Також складається враження, що змішані логічний і фізичний рівні проектування

РОЛЬ :)

Я впервые слышу об этом авторе и впервые вижу,

На цьому можемо завершувати розмову. Особливо враховуючи відсутність посилання на першоджерело і стилю відповіді, дуже схоже, що маємо ще одну «машину Кузьміна»

Это да, первоисточника у меня нет. А вот язык и транслятор есть. И даже программы. Здесь. www.youtube.com/watch?v=KMzyb7FmQDM Только трудно доходит.
Если кого терия заинтересует, то здесь. www.youtube.com/watch?v=qKUoCeGvXnA

Так вы пишете в одинаковом стиле.

Возможно. Со стороны виднее. Только я пишу про то, что в реальности существует и работает, просто возникла идея это как-то систематизировать и обозвать. И на донаты не развожу. А так да, «никакой разницы, ПРАКТИЧЕСКИ никакой разницы!»

У Кузьмина оно тоже в реальности работало еще до войны. Но никто не масштабировал.

И на донаты не развожу.

І це добре, бо dou.ua/...​875/?from=fortech#3071520

Поэтому и говорю, к РЕАЛЬНОМУ ООП изложенное не относится.

Есть реальные системы, сделанные на активном (акторном) ООП, пусть даже не в виде конкретно Simula или Smalltalk. Erlang/OTP я рядом вспоминал, мы на нём делали много серьёзного и хорошего. Да, его относительная доля по сравнению с пассивным ООП (как в C++/Java/C#/etc.) невелика. Возможно, это будет меняться.

Вторая часть (практическая реализация) будет примерно через неделю. Очень много кода, это непростая тема, пытаюсь обрезать максимально примитивно, лишь бы сохранить контекст.

Большая часть иерархических систем похожи — потому что топология одна.
Вот сбросили в чатике про иерархию в роботах web.stanford.edu/...​fs/lecture/lecture_14.pdf
И про ноды там же docs.ros.org/...​ts/Basic/About-Nodes.html
Так же иерархически устроена автоматизация фабрик и пожарная сигнализация зданий.
Вот моя глава об иерархиях metapatterns.io/...​d-metapatterns/hierarchy

И по результату вопросы:
— Зачем новая архитектура, и что она решает по сравнению с известными (микросервисы, меш, акторы, другие виды иерархий).
— Как, где, и вместо чего это надо использовать на практике.

«Как» — лучше один раз увидеть, чем тысячу раз «понять по-своему», я как раз рукожоплю вторую часть. «Где» — Вы меня прямо в тупик загнали. Возможно, там, где потребуется повышенная надёжность?.. «Вместо чего» — это скорее смогут сказать те, кому есть с чем сравнивать при закрытии своих потребностей. Потратить десяток-полтора лет на глубокое изучение всех существующих разновидностей решений, в том числе некро-примеров сорокалетней давности и чисто теоретических выкладок — достойный поступок, не спорю. Но обойдусь)))

Вот моя глава об иерархиях

Не просто «не совсем то», а как раз пример того, чего я сознательно избегаю. Подождите несколько дней, потом уже закидаете подручными предметами. А пока что это крик шкуры неубитого медведя.

Підписатись на коментарі