Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to suspend node REPL and resume at a later stage with all the environment preserved?

I wish to suspend a REPL session so that I could shut down the system and then at a later time continue to work on the REPL session as if I'd never closed it, i.e. without having to lose all the environment.

I think that the possible solutions to this could be

  1. Snapshot memory, save to file and load env from file later: I think this would be the neatest solution, like happens when you use the 'hibernate' feature of Windows. I've found this heapdump utility which is intended to take a memory snapshot for analysis of memory leaks, but I don't know if you could resurrect the whole environment from that snapshot and I have found no tools that do so.

  2. Save commands and replay them: A major shortcoming of this method is while it works for simple things like var x = "Hello World";, it wouldn't work for things like var reciptId = bankAccount.makePayment(1000); as it will repeat actions on each replay rather than saving the details of the original function call.

  3. Serialize / Deserialize the whole environment: This would involve making a list of all objects that exist in the environment, and then make a mechanism to write each of them to a file i.e. serialize them, and then make a mechanism that deserializes these and loads them when required. I am yet to see a clean way to serialize and deserialize js variables without limitations. I think that the major limitation of this method is its inability to retain references, so the objects loose their class, things would have to be duplicated upon serialization and lose their equality on deserialization - e.g. 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 and cyclic references would probably not work (x = {}; x.cyclic = x;...). So this method, if it ever works would require a lot of dirty work.

So the question really is, how difficult is it to achieve what I wish to achieve? What could be some other solutions to do this? Is there a major obstruction to achieving this which I'm overlooking?

Also, are there any alternatives to the node repl program (like a console in a browser) that can be suspended like this?

Related :

  • Swift REPL: how to save/load the REPL state? (a.k.a. suspend/resume, snapshot, clone)
like image 845
Peeyush Kushwaha Avatar asked Oct 09 '15 06:10

Peeyush Kushwaha


People also ask

How do I pause a NodeJS process?

Simpler, you can call process. kill('SIGSTOP') to pause the process and and process. kill('SIGCONT') to resume it.

How can you exit from the REPL environment for node JS?

To exit the REPL, you can type . exit , or press CTRL+D once, or press CTRL+C twice, which will return you to the shell prompt.

What is process object and its role NodeJS?

The process object in Node. js is a global object that can be accessed inside any module without requiring it. There are very few global objects or properties provided in Node. js and process is one of them. It is an essential component in the Node.


1 Answers

So if you want to be able to "suspend" a REPL session and then pick up where you left off after a shut down doesn't seem to be directly available in Node.js's REPL. The closest thing to this is the Persistent History feature of the REPL which was added (i think) in Node 4.2.1. This will allow you to view the history of the commands in your REPL in plain text but thats the closest thing available out of the box with Node.

Persistent History

By default, the REPL will persist history between node REPL sessions by saving to a .node_repl_history file in the user's home directory. This can be disabled by setting the environment variable NODE_REPL_HISTORY="".

Previously in Node.js/io.js v2.x, REPL history was controlled by using a NODE_REPL_HISTORY_FILE environment variable, and the history was saved in JSON format. This variable has now been deprecated, and your REPL history will automatically be converted to using plain text. The new file will be saved to either your home directory, or a directory defined by the NODE_REPL_HISTORY variable, as documented below.

Full docs for the REPL module are available here.

However, there is a REPL "wrapper" node module that will do what you're asking. What you can do is, save your REPL history out to a file and then load the history file on the next session and gain access to what you saved to the file in your next REPL session.The module is Nesh. It has a lot of additional features including configuring your shell and evaluating different version of JS such as ES6/ES7 (Using Babel) & Coffeescript.

Install nesh:

npm install -g nesh

Launch nesh in the terminal by simply typing nesh. Work as you normally would within any other REPL session and when you want to save you can type the following in nesh to save your REPL history to the given file:

.save <filepath>

In your next REPL session, even after a shutdown, you can relaunch your nesh session and reload your history by typing:

.load <filepath>

This will re-evaluate the entire history file and will makes any variables or functions available in the current REPL/nesh session.

Hope this is helpful and I think it meets your needs.

like image 176
peteb Avatar answered Oct 05 '22 10:10

peteb