commit dbeba4fa94628c2ab34e83402d719444ff2e0d68 Author: Jordan Orelli Date: Sun Nov 28 03:08:48 2021 +0000 switching computers diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..023d575 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module orel.li/modularium + +go 1.17 diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..dee5890 --- /dev/null +++ b/handler.go @@ -0,0 +1,11 @@ +package main + +import ( + "net/http" +) + +type handler struct{} + +func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..3b1cb64 --- /dev/null +++ b/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "context" + _ "embed" + "fmt" + "log" + "net" + "net/http" + "os" + "os/signal" + "time" +) + +var log_error = log.New(os.Stderr, "", 0) +var log_info = log.New(os.Stdout, "", 0) + +func bail(status int, t string, args ...interface{}) { + if status != nil { + shutdown(fmt.Errorf(t, args...)) + } else { + log_info.Printf + } + out := log_info + if status != 0 { + out = log_error + } + out.Printf(t+"\n", args...) + shutdown(status) +} + +//go:embed usage +var usage string + +type options struct { + Path string +} + +func run(o options) error { + addr, err := net.ResolveUnixAddr("unix", o.Path) + if err != nil { + return fmt.Errorf("bad listen address: %w", err) + } + + l, err := net.ListenUnix("unix", addr) + if err != nil { + return fmt.Errorf("unable to open unix socket: %w", err) + } + onShutdown(func() { l.Close() }) + + server := http.Server{ + Handler: new(handler), + } + onShutdown(func() { server.Shutdown(nil) }) + + // ?? + start := time.Now() + err = server.Serve(l) + if err != nil { + // I dunno how to check for the right error, offhand + if time.Since(start) < time.Second { + return fmt.Errorf("unable to start server: %v", err) + } + } + log_info.Printf("http serve result: %v", err) + return nil +} + +func sigCancel(ctx context.Context) context.Context { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + + ctx, cancel := context.WithCancel(ctx) + onShutdown(cancel) + go func() { + <-c + shutdown() + }() + return ctx +} + +func main() { + ctx := context.Background() + ctx = sigCancel(ctx) + + if len(os.Args) != 2 { + bail(1, usage) + } + + var o options + o.Path = os.Args[1] + if err := run(o); err != nil { + bail(1, err.Error()) + } +} diff --git a/shutdown.go b/shutdown.go new file mode 100644 index 0000000..8f32caf --- /dev/null +++ b/shutdown.go @@ -0,0 +1,30 @@ +package main + +import ( + "sync" +) + +var shutdownHandlers []func() +var shutdownOnce sync.Once + +func shutdown(cause error) { + shutdownOnce.Do(func() { + status := 0 + if cause != nil { + status = 1 + log_error.Printf("shutting down due to error: %v", cause) + } else { + log_info.Print("shutting down") + } + for _, f := range shutdownHandlers { + if err := f(); err != nil { + log_error.Printf("error in shutdown: %v", err) + } + } + os.Exit(status) + }) +} + +func onShutdown(f func()) { + shutdownHandlers = append(shutdownHandlers, f) +} diff --git a/usage b/usage new file mode 100644 index 0000000..962c44b --- /dev/null +++ b/usage @@ -0,0 +1 @@ +modularium [listen-address]