Я работаю над программированием некоторого кода, который подключен к консоли, но читает из файла журнала. Это уникально тем, что данные постоянно записываются в журнал, и я и я могу проверить их только по мере их поступления. Данные поступают в пакетах, которые собираются в «строки», а затем я проверяю каждую строку, чтобы посмотреть, ищем ли это данные.
Например:
(output) -- ignore
(output) -- ignore
(output) -- ignore
(input ) -- > ask for A - enable regex for A
(output) -- ignore
(output) -- ignore
(output) -- regex match - A_START - enable regex for B and C
(output) -- regex match - B
(output) -- regex match - B
(output) -- regex match - B
(output) -- regex match - C
(output) -- regex match - A_END - process completed data set
Вывод записывается в журнал асинхронно из моего приложения, поэтому я не могу отправить команду и затем ожидать, что следующий вывод будет результатом; это будет выход в какой-то момент в будущем. Поэтому мой буфер чтения обычно состоит из одной строки.
Обратите внимание, что соответствующая строка для A
может появиться в любое время, поэтому я явно включаю и отключаю эти шаблоны регулярных выражений по мере необходимости и в последовательности.
Это может показаться невозможным для разбора, но в этом безумии есть порядок. В то время как полученные данные являются асинхронными, они отправляются в «блоках», где каждый блок представляет собой полный набор данных. Например, если набор данных X, Y, Z представляет собой одну строку, он может появиться в журнале в любом порядке. Но если X - это три строки, то ВСЕГДА будет отображаться как три соседние строки, независимо от их относительного положения по отношению к Y и Z.
Это позволяет мне проводить регулярные выражения в очень явном НАЧАЛЕ блока, чтобы знать, когда включить жадное регулярное выражение, а затем в явном конце END для известного мне блока отключить жадное регулярное выражение.
В конце блока у меня теперь есть полный набор данных.
Хотя это довольно легко сделать после того, как написана хорошая основа кода, у меня возникает проблема, заключающаяся в том, что код для того, что на самом деле является очень линейным чтением некоторых данных, по своей природе является нелинейным, как он выглядит в исходный файл из-за необходимости переходить между разнородными триггерами регулярного выражения и дополнительными обратными вызовами.
Что я хочу сделать, так это детально прорисовать это как UML, чтобы я мог обратиться к нему позже, потому что я ЗНАЮ, что через три месяца у меня будет чертовское время, чтобы разобраться в этом.
Реальная процедура, которую я сейчас пишу, более сложна, чем короткий пример, который я описал выше. Это похоже, но для каждой записи B
в A
мне нужно отправить другую команду, чтобы получить дополнительный набор данных, связанный с A
. Полный набор данных для A
не закончен, пока у меня нет всего.
Вот краткое описание последовательности:
> invoke catalog show
(output) -- Catalog Begin
(output) Collection 1
(output) Collection 2
(output) Collection 3
(output) -- Catalog End
// foreach next entry in Catalog...
> invoke Collection 1 show
(output) -- Collection Begin
(output) ...
(output) ...
(output) ...
(output) -- Collection End
// Perform action on Collection 1
// foreach next entry in Catalog...
А вот более подробное изложение того же:
-- enable 'catalog begin' regex pattern
> invoke catalog show
(output) -- Catalog Begin
-- REGEX MATCH
-- disable 'catalog begin' regex pattern
-- enable 'catalog entry' regex pattern
(output) Collection 1
-- REGEX MATCH
-- add to catalog list
(output) Collection 2
-- REGEX MATCH
-- add to catalog list
(output) Collection 3
-- REGEX MATCH
-- add to catalog list
(output) -- Catalog End
-- REGEX MATCH
-- disable 'catalog end' regex pattern
-- enable 'collection begin' regex pattern
-- collections max = 3
-- next collection = 1
-- send command: invoke Collection 1 (next collection) show
> invoke Collection 1 show
(output) -- Collection Begin
-- REGEX MATCH
-- disable 'collection begin' regex pattern
-- enable 'collection entry' regex pattern
(output) ...
-- REGEX MATCH
-- add to collection entry list
(output) ...
-- REGEX MATCH
-- add to collection entry list
(output) ...
-- REGEX MATCH
-- add to collection entry list
(output) -- Collection End
-- REGEX MATCH
-- disable 'collection begin' regex pattern
-- enable 'collection entry' regex pattern
-- next collection + 1 (2)
-- send command: invoke Collection 2 (next collection) show
-- if next collection > 3 (collections max)... (false)
-- repeats for all 3 entries
> invoke Collection 2 show
...
-- collections invoked + 1 (3)
-- if next collection > 3 (collections max)... (false)
> invoke Collection 3 show
...
-- collections invoked + 1 (3)
-- if next collection > 3 (collections max)... (true)
-- perform processing on data (catalog list and collection lists)
Пожалуйста, помогите мне понять, как я могу четко изобразить это, чтобы я мог понять, как собрать все различные детали, которые составляют в противном случае очень линейную операцию.
UPDATE:
Я думаю, что это правильный подход?
У меня есть «Действие», в котором я хочу выполнить команду для запроса некоторой информации. Существует файл журнала «Вывод» из системы и «Дисплей», представляющий собой цикл, в котором я читаю каждую строку по мере ее получения с выхода.
Вывод является асинхронным (в своем собственном столбце), и отображение является асинхронным по отношению к этому, поскольку оно отображает каждую строку только в том случае, если она читается. И действие также выполняется асинхронно (его можно вызвать в любое время).
Я думаю, что это правильный подход. Теперь, как мне объединить этих троих вместе, чтобы проиллюстрировать их отношения?