Без малого уже чуть более полутора лет прошло со времени появления идеи о создании модульной системы и написания первых пробных строк кода. По сути, это первый и самый большой мой проект такого рода. Многое было сделано поспешно, многое наугад, но так или иначе, это рабочая программа, спрос на которую внутри нашей группы постепенно растёт. Однако сейчас я буду писать не о радужных перспективах, а о проблемах, вся глубина которых осознаётся только сейчас.
И так, в основе проекта лежала концепция конвеерной обработки данных, где каждая цепочка конвеера предоставляет из себя независимый, динамически подгружаемый модуль, а связаны они между собой при помощи компактного (по определению, ограниченного и замкнутого) интерфейса. При реализации первой же конфигурации стало ясно, что одного конвеерного подхода крайне мало для реализации полноценной программы. И рушится всё на простой задаче реализации различных типов интерфейсов, т.е. на задаче ввода/вывода. Эта задача просто напросто подразумевает двухсторонний обмен сообщениями между модулями, который принципиально не уживается с конвеером, двигающимся в одну сторону. Тогда на этот факт небыло обращено должного внимания, и были введены кастыли в виде обратных запросов, что как-то спасло положение и ввело некую долю неразберихи. С ростом количества модулей эта неразбериха росла, как минимум, по квадратичному закону. В итоге, разобраться во всей этой паутени уже невозможно практически никому. Я сам, после перерыва в несколько месяцев, принял одну фичу за баг, и заслуженно, не имея при этом никакой возможности тот баг исправить, ибо рушилось многое. Ситуация усугубилась при попытке сконфигурировать систему для мониторинга и управления лазером, что находится сейчас в разработке. В этой задаче требовалось лишь отправлять и получать данные с прибора, обернув это в дружелюбный графический интерфейс. В интерфейс-то это обернулось, но внутренняя структура модуля ужасна, не очевидна и неэффективна. В результате имеем следующее. На данный момент в системе нет никаких инструментов для эффективной реализации интерфейсов ввода/вывода (com, ethernet and etc), а также протоколов. Модель конвеера для этого оказалась непригодной. Уже есть, однако, новые идеи, но о них в другой раз.
Передача сигналов между модулями. По поспешности и неопытности была выбрана обёртка QVariant. Однако лишь недавно я узнал, что QVariant не является по умолчанию зарегистрированным типом. Другими словами, Нельзя обернуть QVariant в QVariant. А я то думал, отчего это у меня не работают отложенные конекты. Видимо, их реализация принципиально отличается от прямых конектов, которые работали. Следующий на примете тип QVariantList или QByteArray, но для их введения необходимо исправить все модули.
Замкнутые циклы при передаче сообщений. Если мы используем прямые конекты, то сигнал передаётся в сокет немедленно, прерывая выполнения того кода, из которого он был вызван. При этом, часть модулей были написаны так, что результатом их успешной работы была посылка сообщения обратно. Посылка такого сообщения также прерывала работу того модуля, который уже прервал модуль, которому отправляет сообщение.. в результате возникает замкнутый цикл, а в Qt преусмотрен механиз разрыва таких циклов. В результате, возникает потеря сигнала, потеря данных на ровном месте, и давольно сложно было понять, что это потеря внутри программы, а не отсутствие ответа от прибора, тем более когда последнее также имело место.
Распараллеливание на потоки. Идея, которая присутствовала практически с самого начала, но опять же, только сейчас назрела. Во первых, разбиение на потоки практически исключает возникновение замкнутых циклов и непредвиденных разрывов в выполнении модулей. Сейчас удалось лишь на скорую руку таки реализовать отложенные конекты, что как-то сняло проблему образования замкнутых циклов. Также разбиение на потоки даст возможность писать "блокирующие" модули с гораздо более линейным и понятным кодом, и они никак не будут мешать другим частям программы. И в тоже время, введение потоков требует полного пересмотра структуры.
Вот же что представляет из себя сложившаяся ситуация. Развиваться в том же направлении проект не сможет, это тупик. А для изменения этого направления необходимы немалые усилия, и не понятно, хватит ли их... Одно уже произошло определённо, проект вышел из области простых упражнений в программировании и начинает представлять из себя нечто действительно "живое", существующее по правилам...
И так, в основе проекта лежала концепция конвеерной обработки данных, где каждая цепочка конвеера предоставляет из себя независимый, динамически подгружаемый модуль, а связаны они между собой при помощи компактного (по определению, ограниченного и замкнутого) интерфейса. При реализации первой же конфигурации стало ясно, что одного конвеерного подхода крайне мало для реализации полноценной программы. И рушится всё на простой задаче реализации различных типов интерфейсов, т.е. на задаче ввода/вывода. Эта задача просто напросто подразумевает двухсторонний обмен сообщениями между модулями, который принципиально не уживается с конвеером, двигающимся в одну сторону. Тогда на этот факт небыло обращено должного внимания, и были введены кастыли в виде обратных запросов, что как-то спасло положение и ввело некую долю неразберихи. С ростом количества модулей эта неразбериха росла, как минимум, по квадратичному закону. В итоге, разобраться во всей этой паутени уже невозможно практически никому. Я сам, после перерыва в несколько месяцев, принял одну фичу за баг, и заслуженно, не имея при этом никакой возможности тот баг исправить, ибо рушилось многое. Ситуация усугубилась при попытке сконфигурировать систему для мониторинга и управления лазером, что находится сейчас в разработке. В этой задаче требовалось лишь отправлять и получать данные с прибора, обернув это в дружелюбный графический интерфейс. В интерфейс-то это обернулось, но внутренняя структура модуля ужасна, не очевидна и неэффективна. В результате имеем следующее. На данный момент в системе нет никаких инструментов для эффективной реализации интерфейсов ввода/вывода (com, ethernet and etc), а также протоколов. Модель конвеера для этого оказалась непригодной. Уже есть, однако, новые идеи, но о них в другой раз.
Передача сигналов между модулями. По поспешности и неопытности была выбрана обёртка QVariant. Однако лишь недавно я узнал, что QVariant не является по умолчанию зарегистрированным типом. Другими словами, Нельзя обернуть QVariant в QVariant. А я то думал, отчего это у меня не работают отложенные конекты. Видимо, их реализация принципиально отличается от прямых конектов, которые работали. Следующий на примете тип QVariantList или QByteArray, но для их введения необходимо исправить все модули.
Замкнутые циклы при передаче сообщений. Если мы используем прямые конекты, то сигнал передаётся в сокет немедленно, прерывая выполнения того кода, из которого он был вызван. При этом, часть модулей были написаны так, что результатом их успешной работы была посылка сообщения обратно. Посылка такого сообщения также прерывала работу того модуля, который уже прервал модуль, которому отправляет сообщение.. в результате возникает замкнутый цикл, а в Qt преусмотрен механиз разрыва таких циклов. В результате, возникает потеря сигнала, потеря данных на ровном месте, и давольно сложно было понять, что это потеря внутри программы, а не отсутствие ответа от прибора, тем более когда последнее также имело место.
Распараллеливание на потоки. Идея, которая присутствовала практически с самого начала, но опять же, только сейчас назрела. Во первых, разбиение на потоки практически исключает возникновение замкнутых циклов и непредвиденных разрывов в выполнении модулей. Сейчас удалось лишь на скорую руку таки реализовать отложенные конекты, что как-то сняло проблему образования замкнутых циклов. Также разбиение на потоки даст возможность писать "блокирующие" модули с гораздо более линейным и понятным кодом, и они никак не будут мешать другим частям программы. И в тоже время, введение потоков требует полного пересмотра структуры.
Вот же что представляет из себя сложившаяся ситуация. Развиваться в том же направлении проект не сможет, это тупик. А для изменения этого направления необходимы немалые усилия, и не понятно, хватит ли их... Одно уже произошло определённо, проект вышел из области простых упражнений в программировании и начинает представлять из себя нечто действительно "живое", существующее по правилам...