Как приостановить node REPL и возобновить на более позднем этапе с сохранением всей среды?
Я хочу приостановить сеанс REPL, чтобы я мог отключить систему, а затем в более позднее время продолжаю работать над сеансом REPL, как если бы я никогда не закрывал его, т.е. не теряя всю среду.
Я думаю, что возможные решения этого могут быть
-
Память моментальных снимков, сохранение в файл и загрузка env из файла позже. Я думаю, что это было бы самым аккуратным решением, например, когда вы используете функцию "спящий режим" Windows. Я нашел эту утилиту heapdump, которая предназначена для получения моментального снимка памяти для анализа утечек памяти, но я не знаю, если вы можете воскресить всю среду из этого моментального снимка, и я не нашел инструментов, которые это делают.
-
Сохранить команды и воспроизвести их. Основной недостаток этого метода заключается в том, что он работает для простых вещей, таких как var x = "Hello World";
, он не будет работать для таких вещей, как var reciptId = bankAccount.makePayment(1000);
, поскольку он будет повторять действия для каждого повтора, а не сохранять детали исходного вызова функции.
-
Сериализация/десериализация всей среды. Это будет включать в себя создание списка всех объектов, существующих в среде, а затем создать механизм для записи каждого из них в файл, то есть сериализовать их, а затем создать механизм, который десериализует их и загружает при необходимости. Я еще не вижу чистого способа сериализации и десериализации переменных js без ограничений. Я думаю, что основным ограничением этого метода является его неспособность сохранять ссылки, поэтому объекты теряют свой класс, вещи должны дублироваться при сериализации и теряют свое равенство при десериализации - например,
var f = function (x) {...};
var a = {};
a.f = f;
a.f === f? //is true, not true if your serialization mechanism saves a function defn for f and a.f separately and deserializes them separately
и циклические ссылки, вероятно, не будут работать (x = {}; x.cyclic = x;
...). Поэтому этот метод, если он когда-либо будет работать, потребует много грязной работы.
Итак, вопрос в том, насколько трудно достичь того, чего я хочу достичь? Какие могут быть другие решения? Существует ли серьезное препятствие для достижения этого, о котором я не замечаю?
Также есть ли какие-либо альтернативы программе замены node (например, консоли в браузере), которая может быть приостановлена так?
Связанный:
Ответы
Ответ 1
Итак, если вы хотите "приостановить" сеанс REPL, а затем выбрать, где вы остановились после закрытия, похоже, не доступны прямо в Node.js REPL. Ближе всего к этому относится функция постоянной хронологии REPL, которая была добавлена (я думаю) в Node 4.2.1. Это позволит вам просматривать историю команд в вашем REPL в виде простого текста, но это самая близкая вещь, доступная из коробки с помощью Node.
Постоянная история
По умолчанию REPL будет сохранять историю между сеансами Node REPL, сохраняя файл .node_repl_history в домашнем каталоге пользователя. Это можно отключить, установив переменную окружения NODE_REPL_HISTORY = "".
Ранее в Node.js/io.js v2.x, история REPL контролировалась с помощью переменной окружения NODE_REPL_HISTORY_FILE, и история была сохранена в формате JSON. Эта переменная теперь устарела, и ваша история REPL будет автоматически преобразована в обычный текст. Новый файл будет сохранен в вашем домашнем каталоге или в каталоге, определяемом переменной NODE_REPL_HISTORY, как описано ниже.
Полные документы для модуля REPL доступны здесь.
Однако есть модуль REPL "обертка" Node, который будет делать то, что вы просите. Что вы можете сделать, сохраните историю REPL в файл, а затем загрузите файл истории на следующем сеансе и получите доступ к тому, что вы сохранили в файле в следующем сеансе REPL. Модуль Nesh. Он имеет множество дополнительных функций, включая настройку оболочки и оценку другой версии JS, такой как ES6/ES7 (с использованием Babel) и Coffeescript.
Установить nesh:
npm install -g nesh
Запустите nesh в терминале, просто набрав nesh
. Работайте, как обычно, в любом другом сеансе REPL, и когда вы хотите сохранить, вы можете ввести следующее в nesh, чтобы сохранить историю REPL в данном файле:
.save <filepath>
В следующем сеансе REPL, даже после выключения, вы можете перезапустить сеанс nesh и перезагрузить свою историю, набрав:
.load <filepath>
Это приведет к переоценке всего файла истории и сделает любые переменные или функции доступными в текущем сеансе REPL/nesh.
Надеюсь, что это полезно, и я думаю, что оно отвечает вашим потребностям.
Ответ 2
Я думаю, что вы ищете, как приостановить и возобновить процесс. См. этот ответ о том, как приостановить и возобновить процесс