Пауза, сериализация состояния программы и продолжение
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Пытаюсь решить такую проблему сериализации/десериализации программы/процесса.
Допустим, у нас есть программа, которая выполняется (псевдокод):
void main() { action_1(); checkpoint(); int count = action_2("hello world"); checkpoint(); for (i = 0; i < count; i++) { action_3(i); checkpoint(); } }
checkpoint
обозначает место, где мы бы хотели сделать «чекпоинт» — конкретно, сохранить текущее состояние программы и прервать ее выполнение. При этом процес ОС может быть полностью уничтожен.
Далее это состояние может быть загружено обратно в память и выполнение программы может быть возобновлено с места последнего чекпоинта. Это может быть сделано даже на другом физическом компьютере, сразу же, или через несколько дней. С точки зрения программы будет выглядеть так будто она никогда не останавливалась, и она продолжит работу как ни в чем ни бывало.
Есть ли технологии, которые позволили бы это запилить? Какие есть варианты?
Пока думаю о таких constraints, в неопределенном порядке:
1) Программу можно написать на одном из мейнстримовых языков программирования.
2) Минимальные требования к окружению (ОС или оборудованию)
3) Сериализированное состояние должно быть как можно меньше
4) Реализация должна быть безопасной (whatever this means)
5) Минимальные ограничения на то, что может использовать программист в своей программе (но разумные обоснованные ограничения допустимы).
Думал о таких вариантах:
1) Сериализировать виртуальную машину языка
Есть языки программирования, которые насколько тривиальны, что состояние выполнения программы легко сериализировать наивным способом (например, brainfuck).
Недостатки: такой язык будет мало полезен на практике.
2) Сохранить все состояние ОС
Использовать какую-то технологию виртуализации, которая позволяет перевести виртуальную машину в режим гибернации, и сохранить весь дамп виртуальной машины.
Недостатки: состояние машины будет достаточно большим (сотни мегабайт)
3) Сохранить дам памяти процесса
Гипотетически, если снять дам памяти процесса, сохранить его на диск, потом снова загрузить в память, теоретически можно возобновить выполнение программы.
Недостатки: после такого «перезапуска» часть компонентов программы может быть неработоспособной. Например, если были отрыты сокеты или файловые дескрипторы, они будут недействительный (или будут ссылаться на какие-то существующие дескрипторы, которые уже невалидны).
Нужно убедиться, что адресация памяти «до» и «после» совпадают, что сложнее сделать в некоторых ОС, которые рандомизируют расположение памяти.
Состояние памяти все еще относительно большое (десятки МБ)
4) Представить граф выполнения программы как «данные» и сериализировать их.
Есть языки программирования, которые позволяют сконвертировать код программы в state machine (например, C# или Rust с его yield/async/await).
Недостатки: проблема расположения данных в памяти становится еще более актуальной, так как мы уже не имеем контроля над ней. Куча данных в состоянии программы не могут быть сериализированы (например, ссылка на другой метод aka делегат).
====
Какие еще есть варианты/идеи/предложения? Мой предварительный поиск информации привел к выводу, что простого решения проблемы нет и нужно будет проделать существенную часть работы, чтоб получить хоть что-то работающее и не имеющее серьезных ограничений. Какое направление, вы считаете, выглядит более обещающим?
Найкращі коментарі пропустити