From 731715fa600d7abe9dc823cc5f53d816dd3fcaa4 Mon Sep 17 00:00:00 2001 From: unintendedfraud Date: Mon, 11 Mar 2024 23:11:04 +0100 Subject: [PATCH] context examples --- context/http.go | 2 -- context/main.go | 71 ++++++++++++++++++++++++----------------------- context/server.go | 31 ++------------------- 3 files changed, 39 insertions(+), 65 deletions(-) delete mode 100644 context/http.go diff --git a/context/http.go b/context/http.go deleted file mode 100644 index c9ecbf5..0000000 --- a/context/http.go +++ /dev/null @@ -1,2 +0,0 @@ -package main - diff --git a/context/main.go b/context/main.go index b965b5a..39e2a77 100644 --- a/context/main.go +++ b/context/main.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "log" "net/http" "time" ) @@ -10,13 +11,9 @@ import ( const PORT = 8080 func main() { - server := NewServer(1 * time.Second) + server := &Server{} - server.Handle( - "/get-value", - addValueToContext, - handleGetValue, - ) + server.Handle("/get-value", addValueToContext, handleGetValue) if err := server.Listen(PORT); err != nil { panic(err) @@ -26,48 +23,50 @@ func main() { func handleGetValue(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Println("starting handleGetValue") - defer fmt.Println("finished executing handleGetNumber") + log.Println("handleGetValue started") + defer log.Println("handleGetNumber ended") - message, err := executeHandleGetValue(r.Context(), r) + ctx, cancelCtx := context.WithTimeout(r.Context(), 8*time.Second) + defer cancelCtx() + + err := someLongAction(ctx) if err != nil { - w.Write([]byte(fmt.Sprintf("\nError happened: %s", err.Error()))) - fmt.Println("Error happened: ", err) + w.Write([]byte(fmt.Sprintf("\n%s - Error happened: %s", t(), err.Error()))) + log.Println("Error happened: ", err) return } - w.Write([]byte(message)) - + w.Write([]byte(fmt.Sprintf("%s -- operation finished successfully", t()))) }) } -func executeHandleGetValue(ctx context.Context, r *http.Request) (string, error) { +func someLongAction(ctx context.Context) error { + log.Println("someLongAction started") + defer log.Println("someLongAction ended") + + select { + case err := <-simulatingOperation(): + return err + case <-ctx.Done(): + return ctx.Err() + } +} + +func simulatingOperation() chan error { + log.Println("simlatingOperation started") + defer log.Println("simlatingOperation ended") + chanErr := make(chan error, 1) go func() { - fmt.Println("executeHandleGetValue started") + log.Println("goroutine in simulatingOperation started") + defer log.Println("goroutine in simulatingOperation ended") - time.Sleep(2 * time.Second) - - // simulate errors - shouldError := true - - if shouldError { - chanErr <- fmt.Errorf("an error happened during goroutine") - } else { - chanErr <- nil - } - - fmt.Println("executeHandleGetValue ended") + time.Sleep(5 * time.Second) + chanErr <- fmt.Errorf("something terrible happened, PLEASE HELP!") }() - select { - case <-ctx.Done(): - <-chanErr - return "", ctx.Err() - case err := <-chanErr: - return "finished successfully", err - } + return chanErr } func addValueToContext(next http.Handler) http.Handler { @@ -93,6 +92,10 @@ func addValueToContext(next http.Handler) http.Handler { }) } +func t() string { + return time.Now().Format("15:06:05") +} + type ComplexStruct struct { question string possibleAnswers []string diff --git a/context/server.go b/context/server.go index c21abf1..ff9e4a2 100644 --- a/context/server.go +++ b/context/server.go @@ -1,34 +1,16 @@ package main import ( - "context" "fmt" "net/http" - "time" ) type ServerHandler func(http.Handler) http.Handler -type Server struct { - timeout time.Duration -} - -func NewServer(timeout time.Duration) *Server { - return &Server{ - timeout, - } -} +type Server struct{} func (s *Server) Handle(addr string, handlers ...ServerHandler) { - var middlewares []ServerHandler - - if s.timeout == 0 { - middlewares = handlers - } else { - middlewares = append([]ServerHandler{s.timeoutMiddleware}, handlers...) - } - - http.Handle(addr, handleMiddlewares(middlewares)) + http.Handle(addr, handleMiddlewares(handlers)) } func (s *Server) Listen(port int) error { @@ -39,15 +21,6 @@ func (s *Server) Listen(port int) error { return nil } -func (s *Server) timeoutMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx, cancel := context.WithTimeout(r.Context(), s.timeout) - defer cancel() - - next.ServeHTTP(w, r.WithContext(ctx)) - }) -} - func handleMiddlewares(handlers []ServerHandler) http.Handler { var handler http.Handler