func main() { ticker := time.NewTicker(50 * time.Millisecond) hystrixStreamHandler := hystrix.NewStreamHandler() hystrixStreamHandler.Start() go http.ListenAndServe(net.JoinHostPort("", "9090"), hystrixStreamHandler) for { select { case <-ticker.C: err := hystrix.Do("Localhost 8080", func() error { resp, err := http.Get("http://localhost:8080/") if resp != nil { resp.Body.Close() } return err }, nil) if err != nil { log.Printf("Error: %v", err) } } } }
func (m *RedisEngine) RunTask() { client, err := redis.Dial("tcp", m.RedisServer) if err != nil { log.Println("redis connection err", err) } defer client.Close() for { select { case <-m.ExitChannel: return case request := <-m.CmdChannel: err = hystrix.Do("RedisCmd", func() error { reply := client.Cmd(request.Cmd, request.Args...) if reply.Err != nil { return reply.Err } request.ReplyChannel <- reply return nil }, func(error) error { if err != nil { log.Println(request.Cmd, request.Args, err) } client.Close() client, err = redis.Dial("tcp", m.RedisServer) return err }) } } }
// GetWithFallback will fetch the HTTP resource from url using a GET method, wrapped in a circuit breaker named name. // If the operation fails, the fallback function f is called with the previous error as an argument func GetWithFallback(name string, url string, f func(error) error) (resp *http.Response, err error) { err = hystrix.Do(name, func() error { start := time.Now() var internalError error if resp, internalError = ht.Default.Get(url); internalError == nil { measureRequest(start, fmt.Sprintf("planb.breaker.%s", name)) } else { registerFailure(name) } return internalError }, f) return }
// Hystrix returns an endpoint.Middleware that implements the circuit // breaker pattern using the afex/hystrix-go package. // // When using this circuit breaker, please configure your commands separately. // // See https://godoc.org/github.com/afex/hystrix-go/hystrix for more // information. func Hystrix(commandName string) endpoint.Middleware { return func(next endpoint.Endpoint) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (response interface{}, err error) { var resp interface{} if err := hystrix.Do(commandName, func() (err error) { resp, err = next(ctx, request) return err }, nil); err != nil { return nil, err } return resp, nil } } }
func waitForProtected(c *echo.Context) error { var response *http.Response hystrix.Do("waitFor", func() error { var err error response, err = http.Get("http://127.0.0.1:8080/api/v1/wait/" + c.Param("timeout")) //response, err = http.Get(fmt.Sprintf("%s://%s%s", c.Request().URL.Scheme, c.Request().URL.Host, c.Request().URL.Path)) if err != nil { return err } r := response.Body w := c.Response().Writer() io.Copy(w, r) return nil }, func(err error) error { log15.Error(err.Error()) c.JSON(http.StatusInternalServerError, err.Error()) return nil }) return nil }
func index(w http.ResponseWriter, req *http.Request) { hystrix.Do("assign_guide", assignGuide(w), fallback(w)) }
func (c *clientWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { return hystrix.Do(req.Service()+"."+req.Method(), func() error { return c.Client.Call(ctx, req, rsp, opts...) }, nil) }
// ServeHTTP proxies the Request with an Access Token to the upstream and sends back the response // from the upstream func (h *tokenInfoProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { token := tokeninfo.AccessTokenFromRequest(req) if token == "" { tokeninfo.ErrInvalidRequest.Write(w) return } start := time.Now() item := h.cache.Get(token) if item != nil { if !item.Expired() { incCounter("planb.tokeninfo.proxy.cache.hits") w.Header().Set("Content-Type", "application/json;charset=UTF-8") w.Header().Set("X-Cache", "HIT") w.Write(item.Value().([]byte)) return } else { incCounter("planb.tokeninfo.proxy.cache.expirations") } } incCounter("planb.tokeninfo.proxy.cache.misses") err := hystrix.Do("proxy", func() error { upstreamStart := time.Now() rw := newResponseBuffer(w) rw.Header().Set("X-Cache", "MISS") h.upstream.ServeHTTP(rw, req) if rw.StatusCode == http.StatusOK && h.cacheTTL > 0 { h.cache.Set(token, rw.Buffer.Bytes(), h.cacheTTL) } upstreamTimer := metrics.DefaultRegistry.GetOrRegister("planb.tokeninfo.proxy.upstream", metrics.NewTimer).(metrics.Timer) upstreamTimer.UpdateSince(upstreamStart) return nil }, nil) if err != nil { status := http.StatusInternalServerError w.Header().Set("Content-Type", "text/plain; charset=UTF-8") switch err { case hystrix.ErrTimeout: { status = http.StatusGatewayTimeout incCounter("planb.tokeninfo.proxy.upstream.timeouts") } case hystrix.ErrMaxConcurrency: { status = http.StatusTooManyRequests incCounter("planb.tokeninfo.proxy.upstream.overruns") } case hystrix.ErrCircuitOpen: { status = http.StatusBadGateway incCounter("planb.tokeninfo.proxy.upstream.openrequests") } } w.WriteHeader(status) w.Write([]byte(http.StatusText(status))) return } t := metrics.DefaultRegistry.GetOrRegister("planb.tokeninfo.proxy", metrics.NewTimer).(metrics.Timer) t.UpdateSince(start) }