Files
sablier/pkg/strategy/blocking_strategy.go
Alexis Couvreur b4f5eebaac feat: add blocking request (#12)
* feat: add blocking strategy

* docs: add examples for blocking strategy

* ci: run go tests recursively

* perf: wait for BlockCheckInterval for each request

* fix: use camel case instead of snake case for yaml config

* docs: add loading and error page customization as a feature

* fix: use errorPage

* fix: return json instead of html page

* set json key

* update development config

* docs: add comment about custom loading pages

* ci: add beta release
2021-12-11 15:46:56 +01:00

52 lines
1.3 KiB
Go

package strategy
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
type BlockingStrategy struct {
Request string
Name string
Next http.Handler
Timeout time.Duration
BlockDelay time.Duration
BlockCheckInterval time.Duration
}
type InternalServerError struct {
ServiceName string `json:"serviceName"`
Error string `json:"error"`
}
// ServeHTTP retrieve the service status
func (e *BlockingStrategy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
for start := time.Now(); time.Since(start) < e.BlockDelay; {
log.Printf("Sending request: %s", e.Request)
status, err := getServiceStatus(e.Request)
log.Printf("Status: %s", status)
if err != nil {
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(rw).Encode(InternalServerError{ServiceName: e.Name, Error: err.Error()})
return
}
if status == "started" {
// Service started forward request
e.Next.ServeHTTP(rw, req)
return
}
time.Sleep(e.BlockCheckInterval)
}
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(rw).Encode(InternalServerError{ServiceName: e.Name, Error: fmt.Sprintf("Service was unreachable within %s", e.BlockDelay)})
}