-
Notifications
You must be signed in to change notification settings - Fork 79
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
Extracted CircuitBreaker states into 3 structures #62
Conversation
|
||
def initialize(exceptions:, success_threshold:, error_threshold:, error_timeout:) | ||
class CircuitBreaker #:nodoc: | ||
def initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, type_namespace:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of type_namespace
IMO we should call this an implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK.
Just a few comments that I believe are minor. Otherwise LGTM. |
@sirupsen any thoughts? The one bigger discussion would be this: #62 (diff) |
d291681
to
32f68ad
Compare
|
||
def increment(val = 1) | ||
@value = @allowed_symbols[(@allowed_symbols.index(@value) + val) % @allowed_symbols.size] | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually used? The only reason I suggested it before was because you inherited from the integer, since you don't do that anymore, I don't think you actually use this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not used in lib code. It is being tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to go back to a undef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might need SysV::Enum
to inherit from SysV::Integer
if byroot's suggestion goes through #62 (diff) because thats the only way it can be done if #value=
disappears or goes private
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @byroot's suggestion, which is in line with my comment above that this is not an implementation of an enumerator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. That's ok with me. You guys convinced me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't envision how that'd happen. You always go straight from closed to half_open.
No you don't. That's the only transition that doesn't make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this never have been a validation....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too bad I can't just make a create_accessors_and_setters
because of english: :closed
vs #close
. Otherwise I'd just do something like names.each { |name| define_method(name) { @value == name)}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want an #increment
32f68ad
to
4269df4
Compare
assert_equal(sliding_window_1.last, sliding_window_2.last) | ||
assert_equal(sliding_window_1.size, sliding_window_2.size) | ||
assert_equal(sliding_window_1.max_size, sliding_window_2.max_size) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should just be an array comparison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also never use this assertion.
All my comments are smaller things, looking good Kye. After this iteration, I think it should be ready to go in. Then we'll deploy it to Shopify to make sure all is fine, and start working on the next small PR. |
4269df4
to
7e1e6ff
Compare
module Semian | ||
module Simple | ||
class Enum #:nodoc: | ||
def initialize(symbol_list:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't make this argument named.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? Everything else is named already, like the max_size:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, but it's so key to this class and no default makes sense. It doesn't matter much. Up to you.
7e1e6ff
to
1cb63ae
Compare
1cb63ae
to
20335cc
Compare
Look over again, I suppose? |
20335cc
to
ad48ae4
Compare
LGTM |
def value=(val) | ||
raise ArgumentError unless @enums.include?(val) | ||
@value = val | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So then, if I remove this test_will_throw_error_when_invalid_symbol_given
will be gone as well? Also @enums is not needed either then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. No need to test a method that is not used. Just remove the method and the test althogether.
One last concern (unused method). Once it's solved 🐑 |
ad48ae4
to
52b11b9
Compare
52b11b9
to
9b8657f
Compare
I'd say merge this :) |
Extracted CircuitBreaker states into 3 structures
Older closed PR is this: #56
Even older massive PR that we're trying to split is this (probably a bit outdated by this point): #54
Three structures are for holding the
@success
,@state
, and@sliding_window
of theCircuitBreaker
class.They are now under
Semian::Simple
, and future SysV implementation will be underSemian::SysV
.Issue that came up and may/may not have been addressed:
self
as the last line, its so things like#<<
don't expose the inner array and leak the implementation, and instead return the appropriate wrapper class. Cascading still works:wrapper_class_instance << 1 << 2
Atomic
prefix was removed since it is misleading, and we probably won't be providing aMutex
orMonitor
Semian::Simple::Enum
toSemian::Simple::State
and be specialized for the three possible items::open
,:closed
,:half_open
. Similarly, also rename fromInteger
toSuccessCount
. I haven't changed it to those names yet, since it requires removing some code and makes some of the code a bit weird.Simple
stores the values directly, theSysV
enum type delegates the shared-ness to theSysV
integer type, and would need to keep aSysV::SuccessCount
type in theSysV::State
if we use those names.SysV
versions of the structure needing permissions and a name,Semian::Simple::SlidingWindow.new(max_size: 4)
andSemian::SysV::SlidingWindow.new(max_size: 4, permissions: 0660, name: "sample_int")
have different interfaces. Ways to solvedef initialize(max_size: , **_)
def initialize(options = {})
or something of the sortpermissions
andname
at all, but they have to come from somewhere else without leaking the implementation, possible fromSemian.register
#increment
because it was suggested that it could be used to iterate through the enums. May/may not be needed.TestCircuitBreaker
iscircuit_breaker_test.rb