fix_: last command of circuit breaker should always run

When added more command to the circuit breaker, we forget to keep a real fallback mechanism,
the last call should ALWAYS be made.

As such, i am manually skipping to use circuit breaker in that case.
This commit is contained in:
Anthony Laibe 2024-08-14 13:43:51 +02:00 committed by Andrea Maria Piana
parent 90b3d0fdcc
commit c08d10b8ab
1 changed files with 30 additions and 22 deletions

View File

@ -92,35 +92,44 @@ func (cb *CircuitBreaker) Execute(cmd *Command) CommandResult {
ctx = context.Background()
}
for _, f := range cmd.functors {
for i, f := range cmd.functors {
if cmd.cancel {
break
}
circuitName := f.circuitName
if cb.circuitNameHandler != nil {
circuitName = cb.circuitNameHandler(circuitName)
}
if hystrix.GetCircuitSettings()[circuitName] == nil {
hystrix.ConfigureCommand(circuitName, hystrix.CommandConfig{
Timeout: cb.config.Timeout,
MaxConcurrentRequests: cb.config.MaxConcurrentRequests,
RequestVolumeThreshold: cb.config.RequestVolumeThreshold,
SleepWindow: cb.config.SleepWindow,
ErrorPercentThreshold: cb.config.ErrorPercentThreshold,
})
}
err := hystrix.DoC(ctx, circuitName, func(ctx context.Context) error {
res, err := f.exec()
// Write to result only if success
var err error
// if last command, execute without circuit
if i == len(cmd.functors)-1 {
res, execErr := f.exec()
err = execErr
if err == nil {
result = CommandResult{res: res}
}
return err
}, nil)
} else {
circuitName := f.circuitName
if cb.circuitNameHandler != nil {
circuitName = cb.circuitNameHandler(circuitName)
}
if hystrix.GetCircuitSettings()[circuitName] == nil {
hystrix.ConfigureCommand(circuitName, hystrix.CommandConfig{
Timeout: cb.config.Timeout,
MaxConcurrentRequests: cb.config.MaxConcurrentRequests,
RequestVolumeThreshold: cb.config.RequestVolumeThreshold,
SleepWindow: cb.config.SleepWindow,
ErrorPercentThreshold: cb.config.ErrorPercentThreshold,
})
}
err = hystrix.DoC(ctx, circuitName, func(ctx context.Context) error {
res, err := f.exec()
// Write to result only if success
if err == nil {
result = CommandResult{res: res}
}
return err
}, nil)
}
if err == nil {
break
}
@ -134,7 +143,6 @@ func (cb *CircuitBreaker) Execute(cmd *Command) CommandResult {
// Lets abuse every provider with the same amount of MaxConcurrentRequests,
// keep iterating even in case of ErrMaxConcurrency error
}
return result
}