[improvement/server-graceful-shutdown] Add support of graceful shutdown (#312)

This commit is contained in:
Edwar Baron 2020-06-08 11:08:08 -05:00 committed by GitHub
parent 69f8590c64
commit 06a6c80433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 7 deletions

View File

@ -78,7 +78,7 @@ COPY --from=builder /etc/ssl/certs /etc/ssl/certs
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && \
apt-get install --no-install-recommends -y \
libglib2.0-0 libjpeg62-turbo libpng16-16 libopenexr23 \
procps libglib2.0-0 libjpeg62-turbo libpng16-16 libopenexr23 \
libwebp6 libwebpmux3 libwebpdemux2 libtiff5 libgif7 libexif12 libxml2 libpoppler-glib8 \
libmagickwand-6.q16-6 libpango1.0-0 libmatio4 libopenslide0 \
libgsf-1-114 fftw3 liborc-0.4-0 librsvg2-2 libcfitsio7 libimagequant0 libheif1 && \

View File

@ -205,6 +205,16 @@ You can enable it simply passing a flag to the binary:
$ imaginary -concurrency 20
```
### Graceful shutdown
When you use a cluster, it is necessary to control how the deployment is executed, and it is very useful to finish the containers in a controlled.
You can use the next command:
```
$ ps auxw | grep 'bin/imaginary' | awk 'NR>1{print buf}{buf = $2}' | xargs kill -TERM > /dev/null 2>&1
```
### Scalability
If you're looking for a large scale solution for massive image processing, you should scale `imaginary` horizontally, distributing the HTTP load across a pool of imaginary servers.

View File

@ -219,10 +219,7 @@ func main() {
LoadSources(opts)
// Start the server
err := Server(opts)
if err != nil {
exitWithError("cannot start the server: %s", err)
}
Server(opts)
}
func getPort(port int) int {

View File

@ -1,9 +1,13 @@
package main
import (
"context"
"net/http"
"net/url"
"log"
"os"
"os/signal"
"syscall"
"path"
"strconv"
"strings"
@ -56,7 +60,7 @@ func (e Endpoints) IsValid(r *http.Request) bool {
return true
}
func Server(o ServerOptions) error {
func Server(o ServerOptions) {
addr := o.Address + ":" + strconv.Itoa(o.Port)
handler := NewLog(NewServerMux(o), os.Stdout, o.LogLevel)
@ -68,7 +72,27 @@ func Server(o ServerOptions) error {
WriteTimeout: time.Duration(o.HTTPWriteTimeout) * time.Second,
}
return listenAndServe(server, o)
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := listenAndServe(server, o); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
<-done
log.Print("Graceful shutdown")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer func() {
// extra handling here
cancel()
}()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("Server Shutdown Failed:%+v", err)
}
}
func listenAndServe(s *http.Server, o ServerOptions) error {