site and webhooks packages stubbed
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"ruben/inventory2/internal/site"
|
||||
"ruben/inventory2/internal/webhooks"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := runApp(context.Background()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("application shutdown")
|
||||
}
|
||||
|
||||
func runApp(ctx context.Context) error {
|
||||
ctx, shutdown := context.WithCancel(ctx)
|
||||
defer shutdown()
|
||||
|
||||
// start http server
|
||||
|
||||
srvErrCh := runServer(ctx)
|
||||
|
||||
// wait for interrupt signal or unrecoverable failure, then shutdown
|
||||
|
||||
osSignalCh := make(chan os.Signal, 1)
|
||||
signal.Notify(osSignalCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
var serverAlreadyShutdown bool
|
||||
select {
|
||||
case s := <-osSignalCh:
|
||||
fmt.Println("application received shutdown signal:", s)
|
||||
fmt.Println("shutting down")
|
||||
case err := <-srvErrCh:
|
||||
serverAlreadyShutdown = true
|
||||
fmt.Println("server shutdown unexpectedly")
|
||||
if err != nil {
|
||||
fmt.Println("server encountered error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
shutdown()
|
||||
|
||||
// capture application errors that occurred during or caused shutdown
|
||||
|
||||
var errs []error
|
||||
|
||||
if !serverAlreadyShutdown {
|
||||
if err := <-srvErrCh; err != nil {
|
||||
errs = append(errs, fmt.Errorf("server experienced an error: %w", err))
|
||||
}
|
||||
fmt.Println("server shut down")
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func buildHTTPHandler() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/webhooks/", http.StripPrefix("/webhooks", webhooks.New()))
|
||||
mux.Handle("/site/", http.StripPrefix("/site", site.NewSiteHandler()))
|
||||
|
||||
return mux
|
||||
}
|
||||
|
||||
func runServer(ctx context.Context) <-chan error {
|
||||
srv := &http.Server{
|
||||
Addr: ":9000", // local
|
||||
Handler: buildHTTPHandler(),
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
alreadyShutdownCh := make(chan struct{}, 1)
|
||||
|
||||
runningErrCh := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(runningErrCh)
|
||||
defer cancel()
|
||||
defer close(alreadyShutdownCh)
|
||||
|
||||
fmt.Println("server running on 9000...")
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
runningErrCh <- fmt.Errorf("server experienced error: %w", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
shutdownErrCh := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(shutdownErrCh)
|
||||
|
||||
select {
|
||||
case <-alreadyShutdownCh:
|
||||
return
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
shutdownCtx, cancelShutdown := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancelShutdown()
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
shutdownErrCh <- fmt.Errorf("error occurred attempting to shutdown server: %w", err)
|
||||
}
|
||||
}()
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(errCh)
|
||||
|
||||
err1 := <-runningErrCh
|
||||
err2 := <-shutdownErrCh
|
||||
if err := errors.Join(err1, err2); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
|
||||
return errCh
|
||||
}
|
||||
Reference in New Issue
Block a user