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

fix circuit breaker half-open state issue. #202

Merged
merged 3 commits into from
Aug 24, 2020

Conversation

louyuting
Copy link
Collaborator

@louyuting louyuting commented Aug 12, 2020

Describe what this PR does / why we need it

Fix the issue: #196
add defer to handle panic in entry.Exit func and move context recovery logic to defer

Does this pull request fix one issue?

#196

Describe how you did it

Describe how to verify it

UT and integration test
tests/core/circuitbreaker/circuitbreaker_slot_integration_test.go

Special notes for reviews

@louyuting louyuting requested a review from sczyh30 August 12, 2020 14:55
@codecov-commenter
Copy link

codecov-commenter commented Aug 12, 2020

Codecov Report

Merging #202 into master will increase coverage by 0.57%.
The diff coverage is 34.14%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #202      +/-   ##
==========================================
+ Coverage   43.44%   44.02%   +0.57%     
==========================================
  Files          81       81              
  Lines        4507     4534      +27     
==========================================
+ Hits         1958     1996      +38     
+ Misses       2319     2298      -21     
- Partials      230      240      +10     
Impacted Files Coverage Δ
core/base/slot_chain.go 97.46% <ø> (+5.06%) ⬆️
core/circuitbreaker/circuit_breaker.go 22.96% <0.00%> (-0.60%) ⬇️
core/circuitbreaker/rule.go 84.10% <0.00%> (ø)
core/circuitbreaker/rule_manager.go 50.83% <0.00%> (ø)
core/base/context.go 50.00% <60.00%> (+29.48%) ⬆️
core/base/entry.go 48.71% <62.50%> (+48.71%) ⬆️
api/api.go 32.05% <100.00%> (+0.88%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ff74314...ba916b8. Read the comment docs.

@louyuting louyuting force-pushed the 2020-08-11-circuit-breaker-fix branch from 44ecfca to f135f63 Compare August 13, 2020 15:24
@louyuting louyuting marked this pull request as ready for review August 13, 2020 15:25
@louyuting louyuting added area/circuit-breaking Issues or PRs related to circuit breaking kind/bug Something isn't working to-review PRs to review labels Aug 14, 2020
@louyuting louyuting added this to the 0.6.0 milestone Aug 14, 2020
@louyuting louyuting force-pushed the 2020-08-11-circuit-breaker-fix branch from 9012e9a to d8bf782 Compare August 18, 2020 13:47
@louyuting louyuting mentioned this pull request Aug 20, 2020
… but the request is blocked by other circuit breaker or check slot, the state of probing circuit breaker don't rollback the state.
@louyuting louyuting force-pushed the 2020-08-11-circuit-breaker-fix branch from be5386e to 2c32884 Compare August 21, 2020 09:44
if options.err != nil {
ctx.SetError(options.err)
}
e.exitCtl.Do(func() {
for _, handler := range e.exitHandlers {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to handle "panic" from exit handlers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add defer to handle panic and move context "Refurbish" to defer func

@@ -87,8 +87,9 @@ type CircuitBreaker interface {
TryPass(ctx *base.EntryContext) bool
// CurrentState returns current state of the circuit breaker.
CurrentState() State
// OnRequestComplete record a completed request with the given response time as well as error (if present),
// OnRequestComplete record a passed request with the given response time as well as error (if present),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

if entry == nil {
logging.Errorf("nil entry when probing, rule: %+v", b.rule)
} else {
entry.WhenExit(func(entry *base.SentinelEntry, ctx *base.EntryContext) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add some descriptions here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@@ -436,9 +453,11 @@ func (b *errorRatioCircuitBreaker) OnRequestComplete(rt uint64, err error) {
}
if curStatus == HalfOpen {
if err == nil {
logging.Debugf("probe successful, rule: %+v", b.BoundRule())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these debug logs needed? Actually we may add a state change observer to achieve this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for debug when no state change observer

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe register state change observer make more sense

@@ -79,7 +79,7 @@ func (b *RuleBase) IsApplicable() error {
if b.RetryTimeoutMs <= 0 {
return errors.New("invalid RetryTimeoutMs")
}
if b.MinRequestAmount <= 0 {
if b.MinRequestAmount < 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 0 does not make sense here? (at least 1)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's up to the user here?

@@ -284,6 +284,10 @@ func RegisterStateChangeListeners(listeners ...StateChangeListener) {
stateChangeListeners = append(stateChangeListeners, listeners...)
}

func ClearStateChangeListeners() {
stateChangeListeners = make([]StateChangeListener, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to keep the behavior consistent with RegisterStateChangeListeners regarding thread-safety. Actually this is not required to be thread-safe (describing it in comments is okay), as we didn't use read-lock when accessing the state change observers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's not thread-safety.
But i think this function is meaningful,
I will add comments upon func

Copy link
Member

@sczyh30 sczyh30 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sczyh30 sczyh30 merged commit d12f611 into alibaba:master Aug 24, 2020
@sczyh30
Copy link
Member

sczyh30 commented Aug 24, 2020

Nice work. Thanks for contributing!

@sczyh30 sczyh30 removed the to-review PRs to review label Aug 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/circuit-breaking Issues or PRs related to circuit breaking kind/bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG]Circuit breaker will remain half-open state forever when the request is blocked by upcoming rules
3 participants