mirror of
https://github.com/rjNemo/go-microservices-tuto
synced 2026-06-06 02:16:46 +00:00
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
hclog "github.com/hashicorp/go-hclog"
|
|
"github.com/rjNemo/go-micro/images/files"
|
|
"github.com/rjNemo/go-micro/images/handlers"
|
|
)
|
|
|
|
const (
|
|
port = ":5000"
|
|
logLevel = "debug"
|
|
basePath = "./imagestore"
|
|
)
|
|
|
|
func main() {
|
|
|
|
l := hclog.New(
|
|
&hclog.LoggerOptions{
|
|
Name: "product-images",
|
|
Level: hclog.LevelFromString(logLevel),
|
|
},
|
|
)
|
|
|
|
// create a logger for the server from the default logger
|
|
sl := l.StandardLogger(&hclog.StandardLoggerOptions{InferLevels: true})
|
|
|
|
// create the storage class, use local storage
|
|
// max filesize 5MB
|
|
stor, err := files.NewLocal(basePath, 1024*1000*5)
|
|
if err != nil {
|
|
l.Error("Unable to create storage", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// create the handlers
|
|
fh := handlers.NewFiles(stor, l)
|
|
|
|
// create a new serve mux and register the handlers
|
|
sm := mux.NewRouter()
|
|
|
|
// filename regex: {filename:[a-zA-Z]+\\.[a-z]{3}}
|
|
// problem with FileServer is that it is dumb
|
|
ph := sm.Methods(http.MethodPost).Subrouter()
|
|
ph.HandleFunc("/images/{id:[0-9]+}/{filename:[a-zA-Z]+\\.[a-z]{3}}", fh.ServeHTTP)
|
|
|
|
// get files
|
|
gh := sm.Methods(http.MethodGet).Subrouter()
|
|
gh.Handle(
|
|
"/images/{id:[0-9]+}/{filename:[a-zA-Z]+\\.[a-z]{3}}",
|
|
http.StripPrefix("/images/", http.FileServer(http.Dir(basePath))),
|
|
)
|
|
|
|
// create a new server
|
|
s := http.Server{
|
|
Addr: port, // configure the bind address
|
|
Handler: sm, // set the default handler
|
|
ErrorLog: sl, // the logger for the server
|
|
ReadTimeout: 5 * time.Second, // max time to read request from the client
|
|
WriteTimeout: 10 * time.Second, // max time to write response to the client
|
|
IdleTimeout: 120 * time.Second, // max time for connections using TCP Keep-Alive
|
|
}
|
|
|
|
// start the server
|
|
go func() {
|
|
l.Info("Starting server", "bind_address", port)
|
|
|
|
err := s.ListenAndServe()
|
|
if err != nil {
|
|
l.Error("Unable to start server", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
}()
|
|
|
|
// trap sigterm or interupt and gracefully shutdown the server
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt)
|
|
signal.Notify(c, os.Kill)
|
|
|
|
// Block until a signal is received.
|
|
sig := <-c
|
|
l.Info("Shutting down server with", "signal", sig)
|
|
|
|
// gracefully shutdown the server, waiting max 30 seconds for current operations to complete
|
|
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
|
|
s.Shutdown(ctx)
|
|
}
|