Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where's the option for fallback function? #22

Open
cyantarek opened this issue Apr 30, 2019 · 5 comments
Open

Where's the option for fallback function? #22

cyantarek opened this issue Apr 30, 2019 · 5 comments
Assignees

Comments

@cyantarek
Copy link

No description provided.

@YoshiyukiMineo YoshiyukiMineo self-assigned this May 15, 2019
@YoshiyukiMineo
Copy link
Member

Which fallback function are you referring to? Do you mean callback functions?

https://github.com/sony/gobreaker/blob/master/gobreaker.go#L106-L107

@wjh000123
Copy link

Hi, @YoshiyukiMineo ,
in hystrix pattern, an optional fallback function is used when the original func failed. Here's the wiki.

@timjonesdev
Copy link

I didn't see fallback specifically in the example, but cb.Execute returns a specific error immediately if the request is not going to be allowed (this is documented). It looks like you can check for gobreaker.ErrOpenState to trigger fallback logic. Something like:

mySuccessReturn, err := cb.Execute(func() (interface{}, error) {
    // do stuff
})
if err != nil {
    if errors.Is(err, gobreaker.ErrOpenState) {
        // circuit is open
        // this is where a fallback option happens
    } else { // this will be the returned error from "do stuff"
    }
}

@ahmedashraff
Copy link

ahmedashraff commented Sep 5, 2020

@timjonesdev what you suggested to implement the circuit breaker default fallback is good as it's true. However, if there's a default function passed with the setting struct it will be more easy to point, simple to change without touch the actual implementation, and descriptive for each service.

Its an opinion at the end.

@1500mh
Copy link

1500mh commented Oct 28, 2020

@ahmedashraff hello, i think we can customize trigger conditions by replacing cb.afterRequest(generation, err != nil) with cb.afterRequest(generation, cb.shouldChangeState(err)) like this:

type CircuitBreaker struct {
    ...
   shouldChangeState func(err error) bool
}

func defaultShouldChange(err error) bool {
    return err != nil
}

func (cb *CircuitBreaker) Execute(req func() (interface{}, error)) (interface{}, error) {
        ...
	result, err := req()
	cb.afterRequest(generation, cb.shouldChangeState(err))
	return result, err
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants