Я занимаюсь рефакторингом проекта, который я не проектировал.Он написан на C / C ++ для Linux.В проекте есть основной клиентский компонент, который выглядит следующим образом:
Клиент -> Библиотека очереди вывода (OQL) -> Контроллер
Клиент
- Грязный полусложный код, плохо спроектированный (мешанина ООП-приближений с использованием синглетонов / пространств имен, просто странно во многих местах - но это работает)
- Реализация пользовательского протокола (не мой протокол, не может изменить)
- Общая библиотека
- Многопоточный
- Несколько потоков вызывают API-интерфейсы OQL, то есть вывод нескольких потоков
- Принимает команды от контроллера через API
- Создает массивный неупорядоченный вывод, который не обязательно напрямую (и определенно не 1: 1) зависит от входа контроллера)
Библиотека очереди вывода (OQL)
- Простой чистый код, на самом деле не предназначенный для текущей рабочей нагрузки (никогда не предназначался для очереди, изначально он просто записывал в stdout, а затем помещалась в очередь сообщений)
- Общая библиотека
- Однопоточный
- Предоставляет API, который принимает многие типы данных от клиента и создает текстовые представления этих данных
- Вставляет данные в сообщение sys Vочередь
Контроллер
- Исполняемый файл
- Однопоточный
- Элегантный, отказоустойчивый C ++, который широко использует boost
- Написанный мной с нуля, единственная часть проекта, которую мне было позволено полностью «исправить», так сказать
- Взаимодействует с клиентской библиотекой через API для установления соединения с сервером
- Сохраняет данные, полученные клиентом, и считывает их из OQL в базу данных на другом уровне
Таким образом, проблема сводится к тому, что контроллер является однопоточным и вызывает много функций API вклиентская библиотека.Сценарии, возникающие из-за того, что контроллер вызывает клиентский API.
- Обычный (98% +)
- Контроллер вызывает функцию клиентского API
- Функция клиентского API выполняет магию внутренне
- API-функция возвращает true
- Клиент получает данные в результате магии на шаге 2, в другом потоке выполнения и вызывает функцию OQL put из вторичного потока
- OQL записывает данные в очередь сообщенийочередь либо блокирует, либо не блокирует, но это не имеет значения, поскольку основной поток выполнения контроллера работает и обрабатывает данные.
- Success!
- Сценарий проблемы
- Контроллер вызывает функцию API клиента
- Функция API клиента немедленно дает результат, и ДО возврата вызовов вызов функции OQL из основного потока выполнения в Контроллере
- OQL записывает данные в очередь сообщений и одинпроисходит следующее:
- Очередь сообщений не заполнена, не блокируется, все возвращается и продолжениеролик обрабатывает новые данные в очереди сообщений, и жизнь продолжается счастливо
- Сценарий проблемы Очередь сообщений заполнена и блок DOES
Теперь я уверен, что вы можете видеть в проблемном сценарии, который является редким, основной поток выполнения блокирует полную очередь сообщений, а также данные не обрабатываются с другого концаочередь, так как контроллер однопоточный ...
Так что да, это немного беспорядок, и нет, я не доволен дизайном, но я должен найти лучший способ решить это безпереписывая все эти взаимодействия.
Я пытаюсь выбрать между:
Копание в клиенте, синхронизация всех потоков в один поток ввода-вывода, которыйвзаимодействует с OQL
- У меня практически нет веры в то, что кто-то после меня не зайдет и не сломает это в будущем, не внесет значительных ошибок и не сможет понять, почему
Введение потока записи в OQL
- Принимает простой класс и значительно усложняет его
- Вводит смешные проблемы
- Не нужна очередьочередь в этот момент?Поскольку данные должны переноситься в поток писателя
На самом деле, просто набрать этот вопрос было, вероятно, лучшим, что я мог сделать, так как мои мыслигораздо более организованы сейчас ... но есть ли у кого-нибудь предложения, чтобы предложить здесь?Есть ли какой-то шаблон проектирования, который я не вижу, который бы не требовал масштабного рефакторинга, и мои проблемы слишком раздуты по любому из них?Я даже не уверен, что кто-то может дать здесь полезный совет, не зная всех аспектов проблемы, но я ценю любую информацию, которую вы, ребята, можете предложить.