Pull to refresh

Comments 93

PinnedPinned comments

Более того, добавлю вот ещё что.

Я являюсь сертифицированым специалистом по установке и настройке телефонных станций NEC SV 9500.

Если вы попробуете попросить любую ЛЛМку выдать вам список комманд по настройке телефона на SV9500, то даже самая современная ЛЛМка бодрячком выдаст полную ересь. Эти команды учаться кланом самураев, который существует только в виде самоподдерживающего сообщества инженеров, изучающих этот артефакт. (Даже прямо инетересно, если кто-то на Хабре работал с SV9500, или любой другой Univerge, напишите).

Эта система уходит корнями в древность. Она несёт в себе артеяакты древнее, чем любая программа, написанная в США. Её все ещё программируют путём использования ультрафиолетовых ламп и замены микросхем.

Но переписывать или переделывать SV9500 не в коем случае нельзя.

Знаете, почему?

Потому что она действительно обратно-совместима и поддерживается не с целью бюрократии, а с целью выжить в этом ужасном мире телефонии. Univerge умеет соединять телефонный звонок между IP терминалом, запущеным на новой аудио-колонке с андроидом и проводной телефон, советской сборки 1960х годов. У неё с этим - нет проблем. Платформа без остановки поддерживается какой-то сектой извращенцев из Японии. Каждый раз, когда происходит выпуск новых фитч, инженеры по настройке NEC не вздрагивают со словами "Твою мать, надо что-то новое учить". Они будут прекрасно знать, что первое что им нужно будет сделать - это найти слот исполнения на процессоре, в ОС реального времени, которая будет обслуживать телефон, линию или карту.

Они прекрасно понимают, что Univerge запросто подключатся к линиям T1, Ethernet и просто стандартным телефонным кабелям, и при этом у неё нет ну вообще никаких проблема ни с одной из этих карт. Они прекрасно понимают, что что бы не произошло в мире, когда пользователь SV9500 поднимет трубку телефона, то он услышит гудок.

9500 никогда не зависает. Она никогда не останавливается, и обслуживание SV9500 заключается в том, что вам придётся менять выпрямители тока, от которых она питается. Процессорные модули, как и карты управления телефонам можно менять на ходу. Её не надо выключать. В SV9500 нет понятия перезагрузки. Мы её перезапустили только один раз, когда электричество выключилось во всём районе на несколько дней подряд.

Не трогайте SV9500. Она - идеальна. Невероятно сложна, но идеальна. Она даёт такое качество разговора, до которого ни один из современных настольных телефонов не доберётся.

Но 9500 - это интегрированная система, которая обслуживается, и обслуживается сейчас, в настоящем времени. Она поддерживате старые карты, как родные, потому что была сделана с этой целью. Вы можете воткнуть новую карту для Ethernet в порт, который был создан до появления Ethernet, и всё будет работать, потому что у вас есть переходник.

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

Автор статьи посмел посягнуть на священную корову.

За такую ересь его могут придать костру.

CDLM (COBOL Developer lives matter) прежде всего! Всем нужно зарабатывать! Оставьте COBOL разработчиков в покое! ))

Вообще это шутка ) Маск молодец, поддерживаю :+1:!

С технической точки зрения в целом верно. Но кроме технической есть еще и бюрократическая и социальная и финансовая да еще еще много других точек зрения. И вот с этих точек зрения проще писать эмулятор Кобола на современных языках, чем переносить ПО на другой язык и другую базу. Вы просто не сталкивались с консерватизмом финансовых и госструктур. А если это еще и финансовые госструктуры, тогда вообще - полный трэш. И логика со здравым смыслом тут вообще не ночевала.

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

Вот они-то и должны правильный промпт составить

Они составят экспертизу, чтобы их потом уволили, и наняли одного двадцатилетнего, для которого 2003 год уже дикая древность? Ага, сейчас, уже бегут. "Промпт" составлять.

Кстати о "промптах". Вы в курсе, что правильно писать - "запрос"? Чванитесь там?

У финансовых структур очень простой подход.

  • Сколько времени вы потратите на переписывание (и не просто переписывание, но и полный ретест) того, что и так работает? Сколько мы вам за это должны заплатить?

  • Как быстро отобьются наши затраты?

  • Сколько в конечном итоге мы на это заработаем?

И вот пока вы на эти вопросы не ответить так, чтобы бизнесу ваш ответ понравился (а им понравится если вы гарантируете, что ваше переписывание через три года увеличит прибыль на 300%), никто до работающего кода вас не пустит. Причем, ответить вы должны очень убедительно. С примерами из личной практики типа "вот мы той вот корпорации все переписали и уже через год у них чистая прибыль вверх поперла".

А вам припомнят опыт Банка Содружества Австралии и Океании где на такое переписывание потратили 5 лет (с 2012 по 2017гг) и $750млн. Отхватив по дороге кучу проблем (типа внезапного обнуления кредиторской задолженности всех клиентов банка). И лучше (быстрее, стабильнее и т.п.) оно работать не стало.

Или ситуацию со службами занятости в пандемию. Когда они не выдерживали резкого скачка нагрузки. Тогда все стали пенять на старый COBOL, работающий на мейнфреймах, однако расследование показало, что как раз там-то все в порядке, а проблемы были выше - на уровне внешних систем, написанных на "современных стеках".

Бизнесу глубоко плевать на то что и как там работает. Ему важно чтобы оно работало стабильно.

А прежде чем говорить о переписывании, нужно пару-тройку лет поработать с этими системами на уровне центральных серверов. Просто чтобы понять специфику, требования и оценить объемы.

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

Как обычно истинна где то посредине.

С одной стороны, даже крупные изменения/исправления больших систем, не говоря уже о переписывании, НИКОГДА не взлетают с первого раза без ошибок, потому, что в крупной системе нельзя учесть всех тонкостей и особенностей, несмотря на все тестирования. И обязательно что ни будь да вылезет, может даже и не сразу. А некоторые вещи вообще можно протестировать только на проде в реальных условиях. Здесь имеет значение только отсутствие критических ошибок. С мелкими, все равно приходится разбираться по-ходу.

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

Здесь много определяется не стеком, но общей архитектурой.

Например, если архитектура построена по принципу модели акторов (много отдельных бинарников каждый из которых выполняет свою логическую функцию), то обновить любой бинарник отдельно от всех остальных по необходимости (изменение бизнес-логики, оптимизация, исправление ошибки) на самом деле несложно. Это не тащит за собой пересборку и глобальный ретест всей системы.

Что касается взаимоотношений бизнес-ИТ, то тут все просто. ИТ живет на деньги, которые зарабатывает бизнес. Сам по себе код в отрыве от бизнеса ничего не стоит. Вы не пойдете на базар с флешкой где записан какой-то бизнес-функции и не поменяете ее на мешок картошки (ну разве что саму флешку на что-то можно поменять).

Т.е. ИТ решает задачи бизнеса. Не больше и не меньше. И тут не вопрос кто главнее - главных тут нет. Без ИТ бизнес вернется к гроссбухам и арифмометрам Феликс (в лучшем случае, в худшем - счеты). Без бизнеса ИТ будет нечего кушать - код на хлеб не намажешь.

Так что ту надо учится сосуществовать и слушать друг друга.

Ну как сказать. Работал я на биллинге сотового оператора. Да, Кобол там был тоже, ~миллион строк (и десять миллионов на Си). Вот две тысячи бинарников. Только собираются они из общих building blocks, и это как раз хорошая архитектура - например, при смене некоторого общего типа данных ("домена") их достаточно пересобрать, а не править код в каждом. И вот взбрело в голову менеджменту отвязать некоторую часть из них от базы и перевести на микросервисы. Бинарники вроде отдельные, а заглянешь - там двести тысяч строк кода в подводной части айсберга. И сходу совершенно неочевидно даже, куда из них смотреть, чтоб даже просто оценить, какие надо править в рамках упрощенной задачи (это была сравнительно изолированная подсистема).

Ну я работаю в банке из топ-10. 50+ млн клиентов (а каждый клиент это огромный паровоз данных). Что такое АБС (это то, чем я занимаюсь, то, что крутится на центральных серверах и собственно обеспечивает работу банка)

  • 27 тыс. программных объектов

  • 15 тыс. таблиц и индексов базы данных

  • Более 150 программных комплексов (а "комплекс" - это может быть несколько десятков бинарных модулей)

  • Занимает более 30 Терабайт дискового пространства

  • В день изменяется более 1,5 Терабайт информации в БД

  • За день выполняется более 100 млн. бизнес операций

  • Одновременно обслуживается более 10 тыс. процессов

Это не самые свежие данные.

Сколько там строк кода не знает никто. Но модули все достаточно компактны - пара тысяч строк кода на модуль это уже много.

И все выстроено так, что любой модуль, при условии сохранения контракта (интерфейса) может быть переписан незаметно для всех остальных. Фактически модуль - это функция. Особенность RPG (на котором мы пишем) в том, что программа-бинарник может иметь произвольный набор аргументов разных типов (а не argc-argv как в С). И любая программа может быть описана как процедура внутри другой программы. Скажем, есть у нас некая программа ECLRLB которая что-то там делает. И надо нам ее вызвать из другой программы. Просто описываем ее интерфейс

dcl-pr ECLRLB extpgm('ECLRLB');
  LST           char(5);
  Error         char(37);
end-pr ;

И все. Теперь в вызывающей программе у нас есть процедура ECLRLB которая на самом деле является внешней программой extpgm('ECLRLB'). Дальше мы ее уже вызываем как обычную процедуру. И если видимо что внутри нее что-то не так работает - ну просто поправим один бинарник и все.

Есть процедуры которые вызываются и 100500 мест. Но поскольку это внешняя процедура, то любое изменение логики - изменение одного бинарника.

Ну в общем-то привычно. Плюсы микросервисной архитектуры (без её минусов) задолго до того, как такое слово стало мейнстримом.
Но я, собсно, имел в виду чуть другое. Может быть описан, допустим, домен DATE, который представляет из себя char(6). Предположим (на деле такого не было), для исправления "ошибки 2000" надо поменять его на char(8). Правим в одном месте, пересобираем весь проект - вуаля. Рыться по контракту каждого бинарника не нужно.
Хотя можно сказать, что это ортогональные вещи, конечно.

Ну в общем-то привычно. Плюсы микросервисной архитектуры (без её минусов) задолго до того, как такое слово стало мейнстримом.

Ну так-то модель акторов еще в 73-м году придумали :-)

И это не микросервисы в модном понимании. Это ближе именно к акторам.

А "весь проект" - это вся АБС у нас. Там тысячи (если не десятки тысяч) репозиториев. Пересобрать его весь нереально в осмысленное время.

К тому же, это mission critical система. Любое (!!!) изменение в коде требует полный цикл ретеста - компонентный, бизнес, интеграционный, нагрузочный...

Это реалаьно для десятка модулей, но не для всей системы.

Поэтому мы всегда заботимся об обратной совместимости контрактов.

К счастью, язык позволяет расширять контракт путем добавления неиспользуемых параметров.

Как пример. Переписывали один ретривер. Раньше он работал по "исторической" таблице, возвращая данные самой последней по дате изменения записи. Потом оптимизировали - сделали витрину для исторической таблицы где хранятся только последние записи. Переписали ретривер. Был контракт

Dcl-PR getDatInfo  extpgm('GETDA1R');
  CUS           char(6)    const;
  CLC           char(3)    const;
  Typ           char(3)    const;
  dsHDA         likeds(t_dsHDA);
End-PR;

Потребовалось добавить два параметра, стал

Dcl-PR getDatInfo  extpgm('GETDA1R');
  CUS           char(6)    const;
  CLC           char(3)    const;
  Typ           char(3)    const;
  dsHDA         likeds(t_dsHDA);
  dateOnly      ind        options(*omit: *nopass);
  Error         char(37)   options(*nopass);
End-PR;

Параметры dateOnly и Error необязательные. Т.е. в старых точках вызова они не передаются. В новых - можно передавать если надо

Внутри ретривера просто делаем проверку - передали эти параметры или нет

if %passed(dateOnly) and not %omitted(dateOnly)

и

if %passed(Error)

Ретривер очень популярный - вызывается из 100500 мест в системе - переделать все точки вызова нереально.

Оно и с технической точки зрения неверно. Попросту, а какие технические преимущества принесёт переписывание на "современные" технологии? Кто сказал, что они технически лучше? Мода?

 Попросту, а какие технические преимущества принесёт переписывание на "современные" технологии?

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

Для этого проще нанимать людей и обучать их внутри компании. Плюс вести документацию по проекту.

А современность стека не гарантирует ничего. Язык - это всего лишь слова и буквы. Если нет документации, а логика достаточно сложна, то вновь пришедший человек, даже отлично знающий стек, все равно не поймет всех тонкостей - что как и зачем оно делает.

Для этого проще нанимать людей и обучать их внутри компании. Плюс вести документацию по проекту.

Не путаем эксплуатацию и разработку. У эксплуатации - все работает. Хорошо и беспроблемно работает. Долго хорошо и беспроблемно работает.

А разработки по этой же самой причине - уже нет. Потому что ничего разрабатывать не надо было. А когда понадобиться - будет 'ой, а что делать-то?'

Нанимаем человека, обучаем, разрабатваем.

Если что - у нас так и происходит. Стек экзотический (у нас), готовых разработчиков мало. Нанимаем, обучаем сами. Проблем с разработкой никаких нет.

Если что - у нас так и происходит.

Это вариант, когда есть приемственность традиции. Всем этим людям было чем заняться в промежутке. И поэтому они сохранили знания, которым можно обучить. Я про случай, когда оно работает настолько хорошо, что в промежутке(долгом) ничего(относящегося к этому артефакту или близкому) разрабатывать не надо было и поэтому все все забыли, а документацию - потеряли при разных переездах и переносах. Частный случай - когда фирма-производитель вообще не существует с <давно>.

Так не бывает. Бизнес растет - появляются новые процессы, которые нужно встраивать в систему. По мере роста растет объем данных и некоторые процессы требуют оптимизации. Меняются внешние условия, требуется изменение бизнес-логики процессов.

Постоянно что-то нужно делать. Любая система вынуждена развиваться. Или умереть.

Так не бывает.

Сомневаюсь. Сам лично видел куски логики, про которые никто не мог объяснить, почему оно так и что сломается, если будет эдак. По этой логике еще где-то раз в полтора года приходилось заказчику отвечать, когда он спрашивал "почему X не обрабатывается, нам кажется это неправильно?" в духе "10 лет назад просили сделать, с тех пор так и осталось". Причем X не было чем-то странным и хотеть, чтобы оно работало - это выглядело вполне нормальным.

Ну тоже с таким встречался. Но это неправильный подход. Так не должно быть.

Да, у нас тоже бывает что написали ТЗ, сделали, потом в процессе тестирования что-то поменяли, ТЗ не актуализировали и все это забыли на несколько лет. Потом возникает нужда что-то поменять - упс. Код расходится с ТЗ. И тогда начинается "реаналитика" - почему так, а как должно быть, а где правильно...

В общем, если что-то пришло на доработку, то всегда идет анализ ТЗ, анализ кода и их синхронизация.

По тому что делаем сейчас, конечно, сразу следим чтобы поставка в бой уходила после синхронизации с ТЗ. Потому что потом даже тот кто все это разрабатывал уже не разберется что там и как.

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

Согласитесь, что это не проблема стека?

По хорошему, заказчик выдает бизнес-требования (BRD) где четко сформулировано что это такое и зачем оно нужно. И как должно работать. А на основе BRD уже пишется ТЗ (FSD) - это уже технические аспекты как именно оно будет реализовано. Там по дороге еще и архитектурное решение должно быть сделано - как все это интегрируется в систему.

И вот когда есть вся документация, разобраться будет уже проще.

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

Но все это к стеку вообще никак не относится. Это даже не разработчика проблемы, но аналитика и (возможно) архитектора.

Согласитесь, что это не проблема стека?

Это не утверждалось. Утверждалось, что процесс переписывания заставляет вспомнить то, что забыли и выяснения того, что не нужно.

В принципе, переписать все на том же самом стеке, почистив мусор - тоже вариант.

Такое, конечно, бывает, и нередко, но это совсем не то же самое, что "все разработчики на этом стеке умерли, потому что всё уже было разработано".

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

Про не технические там было рядом - социальные, там. Но было утверждение, что и техническое. Вот и интересно, что ж тут именно технического.

Переписывать код бизнес-логики в 2025 году стоит смешных денег. Вы не кодеки для видео пишете и не ЛЛМки растите. У вас есть строго кодифицированные процедуры, которые на другой язык можно переложить с закрытыми глазами.

Автор этого длинного и многословного текста похоже никогда не сталкивался с задачами переписывания действительно старого объемного ПО, на которое толком спецификаций нет и пр.
И не простого и понятного кусочка/модуля, а чего то более менее сложного и комплексного.

Я сталкивался.
Сводить все к синктаксису языков программирования и использования LLM вызывает у меня нервное хихикание. И явно отражает только теоретический "опыт" автора в этом вопросе.
В общем: "Что нам строит дом посторить: нарисуем - будем жить".

Когда 90% времени (в лучшем случае) тратишь не на само переписывание как таковое, с одного языка на другой, а на разборки "а зачем это и что это делает в конечном итоге". Не с точки зрения байтиков битиков, а высокоуровнево.
Даже, когда в целом понимаешь зачем и для чего, разбор занимает массу времени.
Особенно на "боковые" ветки логики, на которые в жизни внятных логов нет и никто не может сказать используется это и при каких условиях возникает.

Особенно весело, когда наступает фаза тестирования (нет ни тест кейзов ни общего знания как все целиком работает что бы их составить).
И когда переписанное ПО приносит неожиданные сюрпризы в "боковых" ветках логики (про которые никто не помнит и которые возникают неожиданно на бою).
А еще веселее, когда это ПО связано с финансами и любая ошибка в продакшн - это ооочень больно.

А "не протестированное ПО - это 100% не рабочее ПО". И даже прототестированное ПО - это на 50% рабочее ПО (с вероятностю 1/2. Либо встретишь в нем ошибку или не встретишь на этапе эксплуатации).

Кстати, это беда очень многих статей на хабре. Все сводится к кодированию. Я уже оочень давно занимаюсь разработкой ПО. Так вот кодирование - это совсем небольшая часть работы в разработке ПО.
И по большому счету пофиг на чем (язык, фреймворк). Основное - это понять что нужно (и понять/договорится что это именно то хочется получить).
Я вообще часто удивляюсь как люди друг друга еще понимают. У свой образ "реального мира в голове", а слова языка дают иллюзию, что этот образ "как бы один".

Да, все так. Но вы думаете что США обречены на вечность с Cobol? Нет же, рано или поздно они все таки все это перепишут, если хватит политической воли, а мы понимаем что там крутятся большие деньги, это их вариант коррупции, когда не очень нужные финансовые движения прикрываются не очень нужными, но законными процедурами. На этой теме старого ПО кормятся многие.

Но если не сейчас, то когда? Если не Маск, то кто?

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

Проблема переписывания старого ПО в не в переписывании с одного языка на другой.
А так, конечно все решается. Деньги.. ресурсы.. готовность пережить боль переходного периода.

И это больно. Это 100% проблемы эксплуатации при переходе на новое ПО, со старого, которое вылизано за много лет до максимума. Даже если задача решается "в лоб" (типа код с одного языка на другой) просто с сохранением всей архитектуры, каналов, структур храннения данных и пр.
Плавали... знаем..

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

:-) Ну видимо автор статьи мягко говоря "не очень в курсе" про различия в архитектуре mainframe и современных платформ.... Про "легкую смену языка" прикладного ПО ему уже написали... Плюс к этому "добавляется" "легкая смена БД" для хранения данных... :-)

И это тоже. Там совершенно другая архитектура. И другие подходы.

Но и язык тоже. Как вы будете переписывать с COBOL, где есть нативная поддержка прямой работы с БД, нативные типы данных (со всей арифметикой) для работы с датой, временем и фиксированной точкой на язык, где всего этого нет (точнее, где оно реализовано не языком, но какими-то внешними фреймворками)?

Самое главное, что непонятно зачем вообще переписывать что-то с COBOL, последний стандарт на него вышел 2 года назад, язык очевидно обновляется. Если язык решают свою задачу, то зачем его менять?

Если проблема в отсутствии тестов, возможно стоит начать писать тесты.
Если проблема в железе на котором оно работает, то возможно можно просто обновить железо? Ну в смысле, написали компилятор/интерпретатор/виртуальную машину (что там у COBOL используется), протестировали на современном железе и благополучно переехали.

Я больше скажу. Аналогов COBOL в современных "модных" языках нет. В том смысле, что COBOL является специализированным языком для работы с БД (быстрой работы с большими объемами данных) и реализации специфической коммерческой логики (где много работы с датой, временем, а вся арифметика на 90% идет с фиксированной точкой).

И чтобы сделать то, что в COBOL делается средствами языка, в современном языке вам придется подтянуть кучу зависимостей (не запутавшись в версиях) и в результате будете иметь несколько совершенно не нужных уровней абстракций (как правило, тянущих за собой неизбежные накладные расходы в рантайме).

У нас переписали последний софт совсем недавно с кобола. Проблема в отсутствии нормальных средств разработки. И разработать клиентское приложение чисто на коболе уже затруднительно и в конечном итоге выливается в доп. человеко-часы на поддержку приложения.

В GNU Cobol это работает так - он переводит в код на Си, и там в линкуемой либе используется вполне известная либа GMP для длинной целочисленной арифметики.

Ну это паллиативное решение. Это просто возможность писать на COBOL, не более того.

Да почему же? Думаете, "нативная" реализация COBOL имела бы под капотом что-то принципиально иное? Сомневаюсь, ибо требовало бы процессоров с BCD произвольного размера, что мог себе позволить только IBM, наверное.

За COBOL не скажу. Скажу за RPG. Те же типы данных ind, packed (decimal), zoned (numeric) поддерживаются на уровне системы. Равно как и типы date и time. Аналогично - прямая работа с БД, которая интегрирована в ОС.

Перетаскивать все это на какой-нибудь linux? Без потери эффективности?

https://www.opennet.ru/opennews/art.shtml?num=22604

2009 год. В случае таких систем часто дешевле и проще переделать... окружение. Потому что на окружение есть спецификации. В итоге перевести систему с древнего железа на современное железо с linux и окружением для cobol дешевле чем переписывать всю систему.

Но вы думаете что США обречены на вечность с Cobol?

А в чем, собственно, проблема с COBOL ? Вопрос звучит примерно в духе "IT обречено на вечность с SQL?" (да, на нём писать - это примерно как на SQL и есть, по стилю)

Легаси на то и легаси что трудно понять и ещё трудней изменить.

Контекст утерян, точнее есть распределено в тысяче голов, разработчик ушёл, документации нет или есть, но не соответствует

Но почему бы не написать новую систему с нуля, включая сбор новых требований. И потихоньку, лет 10 переходить, вначале не используя для крупных транзакций / задач

И потихоньку, лет 10 переходить, вначале не используя для крупных транзакций / задач

Есть риски с новой используемой технологией промахнуться - когда через десять лет она может успеть уже сама легаси стать.

А она и так станет легаси. Причем, до того, как вы закончите все это переписывать. Любая технология, который вы сегодня выберете.

по современной технологии хотя бы есть специалисты на рынке

Из этого всего следует один интересный вывод, но неприятный для "любителей нового". Практически всё есть легаси, поэтому совершенно нет смысла оперировать таким понятием (новизны) вообще.

Да. В жизни достаточно много "долгоиграющих" проектов. Которые живут и развиваются десятки лет. И для таких проектов, особенно, если они очень объемные, нет смысла все переписывать как только появился новый стек. Они будут жить и развиваться на том стеке, на котором их начали делать.

Вообще, в моем понимании, легаси - это не про возраст кода и не про распространенность стека. Это про степень документированности и качество кода. Т.е. легаси - это недокументированный код, в который в разное время разными людьми понатыкана куча заплаток. Когда вообще непонятно что, как и зачем оно делает.

Совершенно согласен. Но в массовом сознании разработчиков почему-то под "легаси" понимают не вот так, а как "не новый", типа там "на JS-фреймворке, который вышел из моды год назад"...

Контекст утерян, точнее есть распределено в тысяче голов, разработчик ушёл, документации нет или есть, но не соответствует

Это очень оптимистично. На самом деле его в головах нет. Оно просто автомагически работает и уже никто не помнит что именно, почему и для чего этот черный ящик делает.

Если автоматически работает и проблем нет, то пожалуй и ментальной модели уже нет. За ненадобностью.

Ну это проблема не языка и стека, а, так сказать, культуры производства.

 а, так сказать, культуры производства.

Нет. Это общая проблема сохранения знаний и умений.

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

Неправда. По личному опыту. Есть артефакты, которые работают по 5 и более лет. Мне на доработку приходили модули 15-16-го года. Никто не трогал. Но. Они документированы. Т.е. есть на них ТЗ - что он делает, как и зачем.

И никаких проблем с тем, чтобы внести изменения в логику или оптимизировать не возникает.

5 и боле..
ээх. А мне приходится разбираться иногда в коде, написанном 15 лет назад.
5 лет - это ни о чем. Это свежий софт.

Ну попадается и 20-летний, но редко крайне.

Реальность она тем интереснее, чем более вы готовы на неё смотреть.

Я работаю в финтехе и обслуживаю эти системы. Я не спроста пишу про LPT принтеры и телексы. Для меня всё это - дом родной. Я уже 15 лет живу и работаю в США. В 2015 году я отключил последний serial terminal, и перевёл всё оборудование на Ethernet в одном из банков.

в 2015, Карл. Мне приходилось ходить по зданию с паяльником и мультиметром, потому что люди выбивали 21 штырьковые вилки из розеток.

Не газ мне приходилось откачивать компьютеры с Досом и Виндой 95 в 2019 году.

Я в общем с вами согласен, но я не думаю, что вы действительно понимаете, в насколько плачевном состоянии находится эта архитектура. Просто физически.

Более того, добавлю вот ещё что.

Я являюсь сертифицированым специалистом по установке и настройке телефонных станций NEC SV 9500.

Если вы попробуете попросить любую ЛЛМку выдать вам список комманд по настройке телефона на SV9500, то даже самая современная ЛЛМка бодрячком выдаст полную ересь. Эти команды учаться кланом самураев, который существует только в виде самоподдерживающего сообщества инженеров, изучающих этот артефакт. (Даже прямо инетересно, если кто-то на Хабре работал с SV9500, или любой другой Univerge, напишите).

Эта система уходит корнями в древность. Она несёт в себе артеяакты древнее, чем любая программа, написанная в США. Её все ещё программируют путём использования ультрафиолетовых ламп и замены микросхем.

Но переписывать или переделывать SV9500 не в коем случае нельзя.

Знаете, почему?

Потому что она действительно обратно-совместима и поддерживается не с целью бюрократии, а с целью выжить в этом ужасном мире телефонии. Univerge умеет соединять телефонный звонок между IP терминалом, запущеным на новой аудио-колонке с андроидом и проводной телефон, советской сборки 1960х годов. У неё с этим - нет проблем. Платформа без остановки поддерживается какой-то сектой извращенцев из Японии. Каждый раз, когда происходит выпуск новых фитч, инженеры по настройке NEC не вздрагивают со словами "Твою мать, надо что-то новое учить". Они будут прекрасно знать, что первое что им нужно будет сделать - это найти слот исполнения на процессоре, в ОС реального времени, которая будет обслуживать телефон, линию или карту.

Они прекрасно понимают, что Univerge запросто подключатся к линиям T1, Ethernet и просто стандартным телефонным кабелям, и при этом у неё нет ну вообще никаких проблема ни с одной из этих карт. Они прекрасно понимают, что что бы не произошло в мире, когда пользователь SV9500 поднимет трубку телефона, то он услышит гудок.

9500 никогда не зависает. Она никогда не останавливается, и обслуживание SV9500 заключается в том, что вам придётся менять выпрямители тока, от которых она питается. Процессорные модули, как и карты управления телефонам можно менять на ходу. Её не надо выключать. В SV9500 нет понятия перезагрузки. Мы её перезапустили только один раз, когда электричество выключилось во всём районе на несколько дней подряд.

Не трогайте SV9500. Она - идеальна. Невероятно сложна, но идеальна. Она даёт такое качество разговора, до которого ни один из современных настольных телефонов не доберётся.

Но 9500 - это интегрированная система, которая обслуживается, и обслуживается сейчас, в настоящем времени. Она поддерживате старые карты, как родные, потому что была сделана с этой целью. Вы можете воткнуть новую карту для Ethernet в порт, который был создан до появления Ethernet, и всё будет работать, потому что у вас есть переходник.

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

Не трогайте SV9500. Она - идеальна. Невероятно сложна, но идеальна. Она даёт такое качество разговора, до которого ни один из современных настольных телефонов не доберётся.

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

После чего тебе говорят либо "не будем чинить", либо начинается страшенное эзотерически-мозголомное впихивание нужной функциональности в щели существующих протоколов. Которых мало. Потому что x*30 лет назад даже номер года обрезали до 20 цифр ради экономии. В духе "Такое сочетание флагов вообще-то запрещено, но если пять минут назад в padding-е поля данных использовали еще одну запрещенную комбинацию флагов (да-да, на самом деле это уже давно не просто забивка, туда всякую экзотику сейчас пишут)- то это теперь значит что..."

Вы серьёзно переоцениваете 9500. Там уязвимости не чинят. Там всё телефонное открыто и незашифровано. снять разговор по телефонному кабелю можно с помощью проба за 20 баксов.

Ей не нужно шифровать, она коммутирует.

В 2003 году, когда каждый программист был на учёте, когда для того, чтобы начать работу, вам действительно был нужен диплом и вышка, когда вам платили много, и требовали немало, — заниматься переписыванием ПО от нефиг делать не хотел никто.

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

... а кое-где проглядывает FoxPro.

С подачи того самого 2003-его (ну может попозже) у нас он не только проглядывает, но весьма активно используется. В гос. секторе точно.

... Не знаете, что такое телекс?

Да скажите проще - это самые ранние терминалы. Я, правда, живьем (именно как пишущую машинку с телефоном) его видел еще дошкольником и младшим школьником. Не поверите - в Сбербанке. В поселке городского типа. Вместе с ламповыми калькуляторами. И да первая персоналка, в привычном смысле этого слова, виделась там же. Судя по обрывочным воспоминаниям она даже работала на UNIX, возможно даже была не персоналкой и терминалом - мне тогдашнему этого было не понять. Первая команда, которую показали была cal - выводила календарь на текущий месяц. Что тонко намекает.

Да, для сомневающихся - год что-то между 1985-1989. Лужский район Ленинградской области.

Эту систему пора шатать. Её пора шатать давным-давно. В ней нет сложности. В ней совершенно нет сложности.

Как правило, сложность тут одна. Или менять все и сразу, или не трогать. Все, что можно заменить частями, давно заменено. Остальное просто страшно. Долгий простой, большие деньги, необходимость синхронной работы множества специалистов.

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

Впрочем, чем дольше проблема существует, тем дороже она стоит. В принципе рано или поздно а переделать придется. Обычно, правда, строят альтернативу и дают ей работать в режиме кооперации, постепенно замещая. Почему в штатах так не получается... Не мне судить.

"Почему в штатах так не получается..."

Денежки:) любые произвольные суммы, закрывающиеся настоящими хрустящими актами выполненных работ без фиксированных расценок. Там же золотое дно. И это не только мое мнение, вот ещё пример с Реддита

The other reason it’s problematic is because since it is less and less widely used, the government will pay a premium to keep those systems running - it’s not like it’s off the shelf software and hardware. I’m sure IBM gets a pretty penny to keep those systems going.

https://www.reddit.com/r/cobol/comments/1iy6xg8/comment/mesn0yy/?utm_source=share&utm_medium=mweb3x&utm_name=mweb3xcss&utm_term=1&utm_content=share_button

Но это в глубине, на поверхности конечно официальная страшилка, что все сломается и как твоя бабушка получит свой чек? Хотя , на минуточку, Австралия и Канада кажется вполне успешно справились с переходом со своей устаревшей системы платежей ещё лет 10 назад

Впрочем, чем дольше проблема существует, тем дороже она стоит.

Или отвалится

Для тех кому нужен готовый продукт, стоимость кода в отрыве от продукта равна нулю. Ценность кода появляется тогда, когда продукт пишется, обновляется, оптимизируется, если есть в этом финансовая выгода.

Перехваливать ИИ я бы не стал тоже. Отличный инструмент, но только в руках мастера.

Системы такого масштаба лучше постепенно вытеснить новыми, а потом похоронить. Это будет проще и дешевле.

Смогут ли новые системы жить достаточно долго?

Эффект Линди говорит, что скорее всего нет.

Зайдите сюда — https://www.ssa.gov/OACT/ProgData/tsOps.html, запросите данные — вам покажут их на экране (кстати, сайт сделан в лучших традициях 2006 года)

А мне понравилось. Никакой рекламы, банеров, модных рюшечек, открывается моментально, информация только по делу. Эх... что же мы потеряли...

А в 2006 появился первый публичный репозиторий гита.

Ну да, ведь до 2006 разработка того же линукса велась втёмную.

Любопытное наблюдение: чем профессиональнее человек в разработке, тем скептичнее он относится к LLM и прочему говну. Менеджеры, которые одним когнитивным усилием способны удержать в голове только один тэг HTML — те все, как на подбор, воодушевлены и рисуют воздушные замки один другого краше.

При этом любая попытка попросить LLM хоть что-то более-менее сложное переписать с одного языка на другой — терпит позорнейшее фиаско на любых мощностях.

Да таких примеров миллион: каждый, кто пытался использовать LLM вне круда и супер-мейнстрима на самых популярных языках — в курсе, как оно «справляется» :)

Переписать любой код с одного языка на другой дело, конечно, пяти минут. Другой вопрос - как он потом будет работать, и будет ли вообще. Учитывая, что автор предполагает менять сразу и ПО, и оборудование (а иначе смысла затевать всё нет), то проще построить всё с нуля - дать ТЗ на оборудование и периферию, и уже затем строить под него код... Который в 2048 году кто-нибудь такой же юный, как автор поста, будет кипя гневом предлагать срочно переписать под VR окружение, а то используют всякую древность - мониторы, карточки, клавиатуры с мышками - ужас же просто. Да ещё и денег за это получают.

Уверены?

Вот вам код на RPG

  exec sql declare curRDMGET07RDK cursor for
             with
               CAF as (
                 select CAFCUS CUS,
                        CAFCLC CLC,
                        CAFTP  TP
                   from CAFPF
                  where CAFTP = 'P'
                    and (CAFATR1 = 'Y' or CAFATR2 = 'Y')
               )
                
             select RDKCUS,
                    RDKCLC,
                    RDKSER,
                    RDKNUM,
                    RDKOPN,
                    coalesce(CAF.TP, cast(' ' as char(1)))
               from RDKPF RDK
          left join CAF
                 on (CAF.CUS, CAF.CLC)
                  = (RDK.RDKCUS, RDK.RDKCLC)
              where RDKOSN = 'Y'
                and RDKSDL = 'Y'
                and RDKUCD = '001'
                and RDKEDT <= :limitDte
                and not exists (select RDKMCUS
                                  from RDKMPF RDKM
                                 where RDKM.RDKMCUS = RDK.RDKCUS
                                   and RDKM.RDKMCLC = RDK.RDKCLC
                                   and RDKM.RDKMUCD = RDK.RDKUCD
                                   and RDKM.RDKMSER = RDK.RDKSER
                                   and RDKM.RDKMNUM = RDK.RDKNUM
                                   and RDKM.RDKMOPN = RDK.RDKOPN
                                   and RDKM.RDKMTP  = '7');


  if curOpn;
    dou lastBlock or dsError <> *blanks;
      exec sql fetch curRDMGET07RDK for :maxSQLRows rows into :dsSQLData;

      if sqlcod < 0;
        SQLError('fetch': dsError);
      else;
        lastBlock = sqlGetRows(sqlRowsRead);

        for row = 1 to sqlRowsRead;
          if dsSQLData(row).TP = 'P';
            addRDKMRec(dsSQLData(row): *omit: dsError);
          else;
            if chkCltG(dsSQLData(row).CUS: dsSQLData(row).CLC);
              %len(TRN) = 0;
              makeTRN(dsSQLData(row).CUS: dsSQLData(row).CLC: TRN);

              if %len(TRN) > 0;
                addRDKMRec(dsSQLData(row): TRN: dsError);
              endif;
            endif;
          endif;
        endfor;
      endif;
    enddo;

    exsr srCloseCur;
  endif;

И еще кусочек оттуда же

dcl-proc chkCltG ;
  dcl-pi *n ind;
    CUS  char(6)  const;
    CLC  char(3)  const;
  end-pi;

  dcl-f GF48LF    disk(*ext)
                  usage(*input)
                  usropn
                  keyed
                  qualified
                  static;
  
  dcl-s result    ind inz(*off);
  dcl-s CTP       char(2);

  if not %open(GF48LF);
    open GF48LF;
  endif;

  for-each CTP in %subarr(arrCTP_G: 1: %elem(arrCTP_G));
    setll (CTP: CUS: CLC) GF48LF;

    if %equal(GF48LF);
      result = *on;
      leave;
    endif;
  endfor;

  return result;

  begsr *pssr;
    dump;
  endsr;
end-proc;

dcl-proc makeTRN ;
  dcl-pi *n;
    ACUS     char(6) const;
    ACLC     char(6) const;
    TRN      varchar(1500);
  end-pi;

  dcl-f YIXX103LF disk(*ext)
                  usage(*input)
                  block(*yes)
                  usropn
                  keyed
                  qualified
                  static;

  dcl-f CAF10LF   disk(*ext)
                  usage(*input)
                  usropn
                  keyed
                  qualified
                  static;
  
  
  dcl-ds dsYIXX1    likerec(YIXX103LF.YXX1PFR: *all);
  dcl-ds dsCAF      likerec(CAF10LF.CAFPFR:    *all);
  dcl-s  proxyP     ind;
  dcl-s  proxyU     ind;
  dcl-s  pinChecked ind;
  dcl-s  arrPIN     char(9) dim(*auto: 100000) static;

  if not %open(YIXX103LF);
    open YIXX103LF;
  endif;

  if not %open(CAF10LF);
    open CAF10LF;
  endif;

  %elem(arrPIN) = 0;

  setll (ACUS: ACLC) YIXX103LF;
  read YIXX103LF.YXX1PFR dsYIXX1;

  dow not %eof(YIXX103LF) and
      dsYIXX1.YXX1ACUS = ACUS and
      dsYIXX1.YXX1ACLC = ACLC;
    if dsYIXX1.YXX1ACT = 'Y' and
       dsYIXX1.YXX1BEG <= $PDATE and
       dsYIXX1.YXX1END >= $PDATE;
       
      proxyP     = dsYIXX1.YXX1TYP in %subarr(arrProxyP: 1: %elem(arrProxyP));
      proxyU     = dsYIXX1.YXX1TYP in %subarr(arrProxyU: 1: %elem(arrProxyU));
      pinChecked = (%elem(arrPIN) > 0 and
                    %lookup((dsYIXX1.YXX1CUS + dsYIXX1.YXX1CLC): arrPIN: 1: %elem(arrPIN)) > 0);

      if (proxyP or proxyU) and not pinChecked;
        arrPIN(*next) = (dsYIXX1.YXX1CUS + dsYIXX1.YXX1CLC);

        chain (dsYIXX1.YXX1CUS: dsYIXX1.YXX1CLC) CAF10LF.CAFPFR dsCAF;

        if %found(CAF10LF) and
           (dsCAF.CAFATR1 = 'Y' or dsCAF.CAFATR2 = 'Y') and
           ((dsCAF.CAFTP = 'P' and proxyP) or (dsCAF.CAFTP = 'U' and proxyU));
          if %len(TRN) = 0;
            TRN = dsYIXX1.YXX1CUS + ':' + dsYIXX1.YXX1CLC;
          else;
            TRN += (',' + dsYIXX1.YXX1CUS + ':' + dsYIXX1.YXX1CLC);
          endif;
        endif;
      endif;
    endif;

    read YIXX103LF.YXX1PFR dsYIXX1;
  enddo;

  return;

  begsr *pssr;
    dump;
  endsr;
end-proc;

У вас есть 5 минут чтобы переписать его на С++. Или Rust. Или C#. Или Java. Что вам ближе.

Время пошло.

На всякий случай - здесь нет никаких "внешних зависимостей". Используются только средства самого языка.

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

Именно так, Вы абсолютно уловили суть.

Меня еще в детском саду прозвали «сутеулавливатель». Или «супоувиливатель»? — не помню уже.

Ну вот именно что сарказм...

Нереально просто взять и переписать код со специализированного языка (коими являются COBOL и RPG у IBM) на обычный ЯВУ, не заточенный узко на выполнение конкретного спектра задач.

Т.е. речь пойдет не о переписать, а о написать заново. Решить ту же задачу, но другим способом и другими инструментами.

А это новая аналитика и новая разработка. И, почти наверняка, придется еще новую БД проектировать. И все данные переносить с реорганизацией.

И с точки зрения бизнеса это огромные затраты с непонятным "выхлопом" - что это даст с точки зрения прибыли? А пока бизнес не убедишь, финансирования не будет - лишних денег не бывает... На любую разработку нужно обоснованно выбивать бюджет.

И дело не в том, что бизнес тупой. Он не тупой, просто метрики другие. Если вы им говорите, что сейчас вы тратите на поддержку легаси условно 500 000 в год, а если вложите 750 000 000 за 5 лет, то потом будете тратить 100 000 в год, то они скажут - ну и за сколько лет окупятся эти 750 000 000? За 1 875 лет? А оно надо? И будут по-своему правы ведь...

PL/SQL аналог первого куска видимо такой

CREATE OR REPLACE PROCEDURE ProcessRDKMRecords(
    p_limit_dte DATE
)
AS
    -- Объявляем переменную для хранения TRN
    v_trn VARCHAR2(50);

    -- Курсор для выборки записей
    CURSOR c_rdk_records IS
        WITH CAF AS (
            SELECT 
                CAFCUS AS CUS,
                CAFCLC AS CLC,
                CAFTP AS TP
            FROM CAFPF
            WHERE CAFTP = 'P'
            AND (CAFATR1 = 'Y' OR CAFATR2 = 'Y')
        )
        SELECT 
            RDKCUS AS Cus,
            RDKCLC AS Clc,
            RDKSER AS Ser,
            RDKNUM AS Num,
            RDKOPN AS Opn,
            NVL(CAF.TP, ' ') AS Tp
        FROM RDKPF RDK
        LEFT JOIN CAF
        ON CAF.CUS = RDK.RDKCUS AND CAF.CLC = RDK.RDKCLC
        WHERE RDKOSN = 'Y'
        AND RDKSDL = 'Y'
        AND RDKUCD = '001'
        AND RDKEDT = p_limit_dte
        AND NOT EXISTS (
            SELECT RDKMCUS
            FROM RDKMPF RDKM
            WHERE RDKM.RDKMCUS = RDK.RDKCUS
            AND RDKM.RDKMCLC = RDK.RDKCLC
            AND RDKM.RDKMUCD = RDK.RDKUCD
            AND RDKM.RDKMSER = RDK.RDKSER
            AND RDKM.RDKMNUM = RDK.RDKNUM
            AND RDKM.RDKMOPN = RDK.RDKOPN
            AND RDKM.RDKMTP = '7'
        );
BEGIN
    -- Обрабатываем каждую запись из курсора
    FOR r_record IN c_rdk_records LOOP
        -- Для записей типа 'P' - добавляем их напрямую
        IF r_record.Tp = 'P' THEN
            INSERT INTO RDKMPF (
                RDKMCUS, RDKMCLC, RDKMSER, RDKMNUM, RDKMOPN,
                RDKMUCD, RDKMTP, RDKMDAT
            )
            VALUES (
                r_record.Cus, r_record.Clc, r_record.Ser, r_record.Num, r_record.Opn,
                '001', '7', SYSDATE
            );
        ELSE
            -- Проверка клиента
            IF CheckClientGoods(r_record.Cus, r_record.Clc) = 1 THEN
                -- Создаем TRN
                v_trn := MakeTRN(r_record.Cus, r_record.Clc);

                -- Если TRN создан, добавляем запись
                IF v_trn IS NOT NULL AND LENGTH(v_trn) > 0 THEN
                    INSERT INTO RDKMPF (
                        RDKMCUS, RDKMCLC, RDKMSER, RDKMNUM, RDKMOPN,
                        RDKMUCD, RDKMTP, RDKMDAT, RDKMTRN
                    )
                    VALUES (
                        r_record.Cus, r_record.Clc, r_record.Ser, r_record.Num, r_record.Opn,
                        '001', '7', SYSDATE, v_trn
                    );
                END IF;
            END IF;
        END IF;
    END LOOP;

    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
END;
/

-- Создаем вспомогательные функции
CREATE OR REPLACE FUNCTION CheckClientGoods(
    p_cus VARCHAR2,
    p_clc VARCHAR2
) RETURN NUMBER AS
    v_result NUMBER := 1;
BEGIN
    -- Здесь должна быть реальная логика проверки клиента
    -- Например:
    /*
    SELECT COUNT(*) INTO v_result
    FROM CLIENTGOODS 
    WHERE CLIENTID = p_cus AND CLCID = p_clc AND STATUS = 'ACTIVE';

    IF v_result > 0 THEN
        v_result := 1;
    ELSE
        v_result := 0;
    END IF;
    */

    RETURN v_result;
END;
/

CREATE OR REPLACE FUNCTION MakeTRN(
    p_cus VARCHAR2,
    p_clc VARCHAR2
) RETURN VARCHAR2 AS
    v_trn VARCHAR2(50);
BEGIN
    -- Здесь должна быть реальная логика создания TRN
    -- Например:
    v_trn := 'TRN-' || p_cus || '-' || p_clc || '-' || 
             TO_CHAR(SYSDATE, 'YYYYMMDD') || 
             LPAD(TRUNC(DBMS_RANDOM.VALUE(0, 10000)), 5, '0');

    RETURN v_trn;
END;
/

примерное описание бизнес смысла тут

https://LLMshare.syntxai.net/1d3e0c2f-2930-20b0-594e76b3

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

Это типичная реализация регулярного бэтч-процесса (batch process) в финансовых системах, который выполняется по расписанию для обработки транзакций, которые должны быть выполнены к определенной дате. Такие процессы обычно запускаются ночью или в период низкой нагрузки.

Ну в целом так, да. Похоже.

Но есть нюансы.

  for-each CTP in %subarr(arrCTP_G: 1: %elem(arrCTP_G));
    setll (CTP: CUS: CLC) GF48LF;

    if %equal(GF48LF);
      result = *on;
      leave;
    endif;
  endfor;

Очень быстрый способ проверки типа клиента (CTP) - входит он в список нужный нам типов или нет. Быстрый за счет того, что здесь нет чтения записи из БД. Проверка производится только по наличию в индексе записи для клиента с заданным УИК (CUS+CLC) заданного типа (CTP из списка arrCTP_G).

Это работает намного быстрее, чем SQL.

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

Именно поэтому основной запрос был максимально упрощен (хотя и стал избыточным), а сложная его часть (постфильтрация) была реализована средствами прямого доступа к БД (чтение по индексу). Фактически, из запроса было убрано обращение к 4-м таблицам, как минимум три из которых были достаточно объемные (десятки миллионов записей).

Там есть еще тонкости со статическими (план запроса строится на этапе компиляции) и динамическими (план запроса каждый раз строится в рантайме чего всесильно стараемся избегать) запросами.

Плюс работа с таблицей YIXX1 в процедуре MakeTRN реализована в режиме "блочного чтения" - когда при чтении одной записи с диска "поднимается" во внутренний буфер среза несколько последовательных по access path записей (и "чтение" следующей записи в цикле уже не требует физического обращения к диску - она берется из заполненного ранее внутреннего буфера). Сравнение с реальными PEX статистиками есть тут.

В данном конкретном случае выигрыш составил с 84 сек (старая версия) до 68 сек (новая версия) по результатам нагрузочного тестирования на копии промсреды.

Это все тонкости, но тонкости очень важные для Hi-Load систем. Так что при переписывании мало будет сделать ретест на сохранение логики, надо будет еще делать ретест на неухудшение (как минимум) производительности и потребления ресурсов. Так что не так все просто с переписыванием...

десятки миллионов записей

Надеюсь, он умеет шардирование?

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

Ну для таких объемов шардирование не нужно еще. Оно умеет, но смысла нет. Приход от шардирования тут начинается когда количество записей к миллиарду подползает...

Переделку можно начинать когда на 146% уверен в положительном ее результате. Чтобы не получилось что потратили кучу денег и времени, но лучше не стало. Бизнес такое не прощает.

И это не легаси в прямом смысле - система развивается как по железу, так и по софту. В 17-м году пришел - сервера были на Power8, операционка, по-моему, 7.2. Сейчас основные сервера на Power9 есть машинки на Power10. Анонсируют Power11 (но, вроде, не вышли еще). Операционка сейчас 7.4 (есть уже и 7.5). И это не считая минорных обновлений (TR - Technology Refresh которые пару раз в год выходят).

Просто достаточно экзотический у нас стек. Но в нем очень много всяких вкусностей. Например - интегрированная языковая среда (ILE) которая позволяет (не вдаваясь в подробности) писать основную часть бизнес-логики на RPG, а там, где его возможностей не хватает (или выглядит слишком неудобно или понимаем что на С/С++ эту часть можно реализовать более эффективно) пишем нужное на С/С++. А потом собираем все в один бинарник.

Такое переписывать будет совсем затруднительно :-)

Я лет 15 назад стоял рядом с разработкой рабис-2, рабис-нп, RTGS всё это на мейнфреймах с географически распределенными системами.

Только денег платили не очень...

Интересно, какое количество читатей Хабра вообще поймут, что значит ind (нет, это не индекс). Я впервые вижу этот RPG, но от похожести кусков на Pro*C прям вьетнамские флэшбэки испытал.

Там скорее от PL/I. Который IBM пыталась развивать, доразвивала до состояния что сами запутались и стали делать что попроще.

Но вот эти dcl-... - это явно из PL.

dcl-proc - объявление процедуры

dcl-pr - объявление прототипа процедуры

dcl-pi - объявление интерфейса процедуры (список параметров)

dcl-c - константа

dcl-s - переменная

dcl-ds - структура

dcl-f - файл

dcl-enum - перечисление...

А ind - это индикатор. Логическая переменная. Один байт, который может принимать значения '0' или '1' (да, символы 0 или 1). Или мнемоники *off ('0') или *on ('1').

На самом деле там достаточно простой синтаксис в целом...

Брр, меня и на предыдущем добивало, в частности, вот это сокращение до просто неприличных размеров. Типа, в спорах виндузятников и юниксоидов первые пеняли последним на какие-нибудь umount или strchr, а в финансах get сокращают до gt, ну куда уже! Глаз дергается...

А ind - это индикатор.

Зачем подсказывать было! Теперь они поди смогут нагуглить, для каких целей индикаторы применялись...

Само по себе программирование приносит 0 долларов. 0 центов. А в 2025 году ещё и не может ничего стоить.

Пока не попытаешься решить реальную проблему и написать софт, которым можно пользоваться. А там все по-старому - не появилось аналогов платных программ, которые написаны LLM-ками за 10 минут с пивом.

Реально что можно написать - это около 100 строк кода с помощью o1, и то нужно контролировать. Далее упирается в потолок, начинает ломать код. Нужно уже включаться, самому разбивать на блоки, создавать архитектуру, продумывать. На каком-то этапе понимаешь что лучше самому взять под свой контроль, иначе слишком много времени уходит на попытки объяснить.

Бла-бла-бла. Чесгря, вот эта без(д)умная реклама нейронок уже достала. Вот буквально во вторник вечером, у меня был готовый текст в markdown, нужно сделать презентацию в pdf (уже частично подготовленного для deckset). И шо ви таки думаете, LLM справилась? Нет, получилось полное говно, которое нужно было переформатировать вручную. Проще оказалось найти человека с ябблодевайсом и несколько часов потрахаться с этим deckset. Кому интересно, могу дать исходник и результирующий pdf - посмотрим, за сколько часов вы справитесь с переписыванием промптов.

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

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

P.S. Да, я знаю о чем говорю. В свои 38 лет я патчил компилятор GNU COBOL для переезда биллинга сотового оператора с Solaris/SPARC на Ubuntu/x86. Чем нормальный бизнес не занялся бы в принципе в мирное время, это импортозамещение приспичило. Нету в Коболе ничего страшного.

Насколько я понял, GNU COBOL - это не COBOL как таковой, а его эмулятор, позволяющий перетащить код из его "естественной среды обитания" куда-то еще.

Тот же RPG. Его пытались портировать. Тот же VisualRPG под .NET был даже. Но все это не прижилось т.к. оно глубоко интегрировано в платформу AS/400 (IBM i) и все прелести (в т.ч. быстродействие при работе с БД) его проявляются именно на этой платформе. Где БД (DB2) - часть операционки. SQL движок - часть операционки...

Ну, не сказал бы. Большая часть проекта и так была написана на Си, с которым у Microfocus Cobol тоже какой-то интерфейс взаимодействия был - например, я частенько видел в Кобол-коде вызовы сишной процедуры для получения юниксовой переменной окружения (getenv). Так что его метод трансляции Кобола в Си и потом его компиляция тем же gcc - это не эмуляция, оно будет работать быстро и нативно, это просто такая особенность реализации.

оно глубоко интегрировано в платформу AS/400 (IBM i)

Ну тут другая проблема - это мейнфреймы. Где вообще всё по-другому. К счастью, существуют не только вендорлоки от большого синего монополиста, и в случае с уже условно "нормальными" компьютерами, пусть это и SPARC и Oracle, при желании съехать можно - следующим большим этапом планировался как раз переход на Postgres.

Вопрос "можно ли съехать" у нас исследовался. Пришли к тому, что нет. Без потери производительности и надежности это будет неразумного дорого.

Да и система эта, при всей ее необычности, очень хороша :-)

Sign up to leave a comment.

Articles