Example #1
0
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)
			}
		}
	}
}
Example #2
0
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
			})

		}
	}
}
Example #3
0
// 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
}
Example #4
0
// 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
		}
	}
}
Example #5
0
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
}
Example #6
0
func index(w http.ResponseWriter, req *http.Request) {
	hystrix.Do("assign_guide", assignGuide(w), fallback(w))
}
Example #7
0
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)
}
Example #8
0
// 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)
}