Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Architecture and operations

Deployment

When does a running server change after you edit the code?

The server in this lab (Node.js) is a program that reads in a source file (a file in which code is written) and answers requests with that code. When you start the server, the computer runs the server program and creates one process (a running program), and this process reads in the source file server.js when it starts. After that it runs only on the code it has read in, and this server does not read the file on the disk again. So even if you edit and save the file, a server that is already running keeps answering with the old code. To make it use the new code, you have to stop the server and start it again with the new code, and making a new version really run like this is called deployment. The code box is not Java code. It is a list of the things a person does, in order (lines that start with # are numbered to-do items). In this lab you remove or reorder line 2, which edits the source file, and line 3, which stops and starts the server, one at a time, and you see which version answers the request in line 4.

Checked against real execution · Ran six combinations with a Node.js 24.18.0 server (a child process) that was really started, with the server.js file edited, and with the server stopped and started, sending requests from an http client, and checked against the model

Concepts in this lab

Deployment
Deployment is the work of putting a new version of the code into a server that is really running, so that users' requests reach the new version. Editing and saving a source file is not enough to make a deployment. A server that is already running runs on the code it read in when it started, so the server has to change to the new code. The simplest way is to stop the server and start it again with the new code, and with this way, when there is only one server, requests fail while it is stopped. The Kubernetes documentation explains this work as replacing old Pods with new Pods, and it distinguishes Recreate, which ends all the existing Pods and then creates new ones, from RollingUpdate, which replaces them gradually.
Server restart
A server restart is ending a running server process and running the same server program again to create a new process. The code the ended process held disappears with it, and the new process reads in the source file from the beginning when it starts. So a restart is a way of bringing the code that is on the disk at that moment into the server. Until it is stopped and started again, no process accepts connections, so a request that arrives in between fails with a connection refused error. If you restart without editing the source file, the server only reads the same code again.
Code loaded at startup
The server of this lab (Node.js) reads in the source file when the process starts, and after that it runs on the code it holds inside itself. The Node.js documentation explains that a module loaded with require is cached after it is first loaded, and that calling the same module several times does not run the module code several times. However, the server.js of this lab is not a module loaded with require but a start file run directly with the node command, so this documentation does not decide the behavior of server.js. On Node.js 24.18.0 on the PC used to write this lab, even when I waited 0.5s after starting the server and editing the file, the code held by the live process stayed the same, and a server that was not started again answered requests with the old code. The file on the disk and the code inside the process are in different places.
Connection refused error
A connection refused error is the error that the sender gets when it asks for a TCP connection but no program has that port open and is waiting. In Node.js, the error event comes instead of the connect event, and the error code appears as ECONNREFUSED (the Node.js errors documentation describes ECONNREFUSED as "Connection refused: No connection could be made because the target machine actively refused it", and the net documentation says that if there is a problem with the connection, error comes instead of connect). Because the connection was not opened, not a single letter of text is sent. The TCP standard says to send a reset signal (RST) to a request that comes with no connection (RFC 9293 section 3.5.2).

Try these

Running with the default settings

  1. Line 1: start the server. The computer runs the server program and creates one process (a running program). When it starts, this process reads in the source file server.js on the disk. The code written in the file says to answer "Version 1" when a request arrives, and the process waits for requests holding this code that it has read in.
  2. Line 2: a person opens the source file server.js, changes "Version 1" to "Version 2", and saves it. Now the file on the disk says "Version 2". But the running server already read in the file when it started, and it does not pick up that the file changed afterward. Even when 0.5s had passed after the edit and the running server was asked directly, the code the server held was still "Version 1". The file and the code inside the server are in different places.
  3. Line 3: stop the server. The server process ends, and the code it had read in and was holding disappears with it.
  4. Line 3, continued: start the server again. The server program is run again and creates a new process, and the new process reads in the source file from the beginning when it starts. The file now says "Version 2", so the new process holds code that answers "Version 2". The edited code has now come inside the server.
  5. Line 4: the client sends a GET /hello request to the server. It is the same as the request a browser sends when you type the address localhost:8080/hello in the address bar.
  6. The server answers "Version 2" with the code its process holds, and the client receives "Version 2". The text in the file on the disk is also still "Version 2", so the file and the code inside the server are the same. The edited new version answered the request.

Result of this run

Code

# 1. Start the server (its code answers "Version 1")
# 2. Change "Version 1" to "Version 2" in the source file
# 3. Stop and start the server
# 4. Send a request

Assumptions of this model

The server is an http server of Node.js 24.18.0. For each combination I really wrote the server.js file (a short program that reads in the line const answer = 'Version 1' when it starts and answers that value when a request arrives) and really started node server.js as a child process. The code on the screen is not the program that was run but a list of what a person does, and the Probe ran this list line by line as it is. Starting means starting the child process, editing means really rewriting the server.js file, stopping means ending that process, and the request is GET /hello with the http module. I ran all six combinations (the different ones among the eight settings, since without the line that starts the server again you cannot choose when to send the request) and checked against the model the response to the request (or the connection refused error), the value the live process held at that time (asked with a separate request), the value written in the file on the disk at that time, whether the process after stopping and starting is a different process from the first, the number of times the server was started, whether the value held by the first process was still the same even after waiting 0.5s after editing the file, and, for the combination that sent the request while the server was stopped, the answer to one more request sent after it was started again. I also checked for each combination that the code on the screen is the same text as the list the Probe ran. Within one combination, the same port was used after stopping and starting, and localhost:8080 on the screen is an example address; in the real runs a free port was taken once. The server in this lab is a short program that reads the file only once, when it starts, so tools that read it in again by themselves when the file changes (such as automatic restart tools for development) and programs that read the file at every request were not covered. What I checked against documentation is the Caching section of Modules in the Node.js documentation (a module is cached after it is first loaded, and unless the require cache is changed, calling the same module several times does not run the module code several times) and Deployments in the Kubernetes documentation (the introduction that a Deployment manages declarative updates of Pods, and in the Strategy section that Recreate ends all the existing Pods before creating new Pods and RollingUpdate replaces them gradually). I only read the two documents, and that a server runs on the code it read in when it started was checked not by the documents but by the runs above. The Caching section of the Node.js documentation is about modules loaded with require, and the server.js of this lab is a start file run directly with the node command, so I do not write that the documentation decides the behavior of server.js. Not covered: how to remove the gap while a server is stopped and started (rolling several machines one after another, blue-green, which builds a whole new environment, and so on) is covered in the in-depth lab "Deployment strategies", the automation that builds, tests, and puts the edited code on a server is covered in "CI/CD pipelines", and the way that Kubernetes replaces servers packed in containers is covered in "Kubernetes self-healing". In a compiled language such as Java there is one more step, compiling again after you edit the source file, and this lab showed only a Node.js source file, which has no compile step.

Previous lab: Message queues · Next lab: Git commits and branches

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these