Adding 'Sending Shutdown Signals' section.
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 1m2s
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 1m2s
This commit is contained in:
66
README.md
66
README.md
@@ -396,6 +396,72 @@ So, to get around this, we'll need to synchronize access to the map of rate limi
|
||||
|
||||
If you're using HAProxy or Nginx as a load balancer or reverse proxy, both of these have built-in functionality for rate limiting that it would probably be sensible to use. Alternatively, you could use a fast database like Redis to maintain a request count for clients, running on a server which all your application servers can communicate with.
|
||||
|
||||
### Sending Shutdown Signals
|
||||
|
||||
When our application is running, we can terminate it at any time by sending it a specific signal. A common way to do this, which you've probably been using, is by pressing **Ctrl+C** on your keyboard to send an interrupt signal - also known as a **SIGINT**.
|
||||
|
||||
But this isn't the only type of signal which can stop our application. Some of the other common ones are:
|
||||
|
||||
| Signal | Description | Keyboard shortcut | Catchable |
|
||||
|---------|--------------------------------------|-------------------|-----------|
|
||||
| SIGINT | Interrupt from keyboard | Ctrl + C | Yes |
|
||||
| SIGQUIT | Quit from keyboard | Ctrl + C | Yes |
|
||||
| SIGKILL | Kill process (terminate immediately) | - | No |
|
||||
| SIGTERM | Terminate process in orderly manner | - | Yes |
|
||||
|
||||
It's important to explain upfront that some signals are _catchable_ and others are not. Catchable signals can be intercepted by our application and either ignored, or used to trigger a certain action (such as a graceful shutdown). Other signals, like **SIGKILL**, are not catchable and cannot be intercepted.
|
||||
|
||||
Let's take a quick look at these signals in action. First, run :
|
||||
|
||||
```bash
|
||||
$ go run ./cmd/api
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="database connection pool established"
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="starting server" addr=:4000 env=development
|
||||
```
|
||||
|
||||
Doing this should start a process with the name **api** on your machine. You can use the pgrep command to verify that this process exists, like so:
|
||||
|
||||
```bash
|
||||
$ pgrep -l api
|
||||
4414 api
|
||||
```
|
||||
|
||||
In my case, I can see that the **api** process is running and has the _process ID_ **4414** (your process ID will most likely be different).
|
||||
|
||||
Once that's confirmed, go ahead and try sending a **SIGKILL** signal to the **api** process using the pkill command like so:
|
||||
|
||||
```bash
|
||||
$ pkill -SIGKILL api
|
||||
```
|
||||
|
||||
If you go back to the terminal window that is running the API application, you should see that it has been terminated and the final line in the output stream is **signal: killed**. Similar to this :
|
||||
|
||||
```bash
|
||||
$ go run ./cmd/api
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="database connection pool established"
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="starting server" addr=:4000 env=development
|
||||
signal: killed
|
||||
```
|
||||
|
||||
Feel free to repeat the same process, but sending a SIGTERM signal instead:
|
||||
|
||||
```bash
|
||||
$ pkill -SIGTERM api
|
||||
```
|
||||
|
||||
This time, you should see the line **signal: terminated** at the end of the output, like so :
|
||||
|
||||
```bash
|
||||
$ go run ./cmd/api
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="database connection pool established"
|
||||
time=2023-09-10T10:59:13.722+02:00 level=INFO msg="starting server" addr=:4000 env=development
|
||||
signal: terminated
|
||||
```
|
||||
You can also try sending a **SIGQUIT** signal — either by pressing **Ctrl+\\** on your keyboard or running **pkill -SIGQUIT api**. This will cause the application to exit with a stack dump.
|
||||
|
||||
We can see that these signals are effective in terminating our application - but the **problem** we have is that they all cause our application to **exit immediately**.
|
||||
|
||||
|
||||
### Performance
|
||||
|
||||
**json.MarshalIndent()** takes 65% longer to run and uses around 30% more memory than **json.Marshal()**, as well as making two more heap allocations. Those figures will change depending on what you're encoding, but they're fairly indicative of the performance impact.
|
||||
|
||||
Reference in New Issue
Block a user