-
Notifications
You must be signed in to change notification settings - Fork 147
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
IPC based Circuit breaker allowing all currently running PHP processes to stop sending data to the agent #440
IPC based Circuit breaker allowing all currently running PHP processes to stop sending data to the agent #440
Conversation
5d2c28c
to
19613b6
Compare
19613b6
to
91d3b15
Compare
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.
Mind. Blown. Fantastic work @pawelchcki! I just left a few comments I'd love to get your thoughts on. :)
@@ -0,0 +1,137 @@ | |||
#include <fcntl.h> |
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 whole thing is 🔝! :)
prepare_cb(); | ||
|
||
atomic_fetch_add(&dd_trace_circuit_breaker->consecutive_failures, 1); | ||
atomic_fetch_add(&dd_trace_circuit_breaker->total_failures, 1); |
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.
Can total_failures
be removed? I don't see it being used anywhere else. :)
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 left in in since this is the data I would love to collect with runtime metrics. But right now it doesn't serve any purpose.
However I think actually might be good idea to add debug mode, where this data could be exposed.
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 ❤️ the idea of putting that at debug level. :)
@@ -0,0 +1,16 @@ | |||
--TEST-- | |||
Test circuit_breaker functionality |
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.
Would it be possible to make each of the test names a little bit more unique? They're all the same at the moment. :)
@@ -0,0 +1,325 @@ | |||
/* |
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.
Since this is the second lib we've vendored in, we should probably start considering were we put 3rd-party code. I put the MessagePack files in src/ext/mpack
but I'm not 100% happy with that location. And dropping in a vendor
folder could get confusing with Composer. So I'm open to ideas, but I'd love to consolidate all the vendered code. :)
Also - could we append this line to the .gitattributes
to have this auto-collapse in diffs:
src/ext/vendor_stdatomic.h* linguist-generated=true
If we throw all the vendored code into one directory, we can just always have it auto-collapse every time we add/update:
src/ext/vendored_code_here/* linguist-generated=true
Anyway - I'd love to hear your thoughts. :)
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.
Need to vendor in this file surprised me abit. Hopefully we'll be able to get rid of this once we'll be able to upgrade GCC in 7.3 build images
stdatomic.h
should be part of C11 standard but GCC lagged "a bit" in implementing it :(
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.
Basically I hope to get rid of vendor_stdatomic.h
"soon" so the sorest it looks the higher chance we'll remember to remove it.
overall I don't mind having vendor
folder. But I worry about being able to set include paths correctly so that the files don't need to be modified when they reference themselves under specifc paths. "Practicality beats purity" etc :)
src/ext/ddtrace.c
Outdated
RETURN_BOOL(1); | ||
} | ||
|
||
static PHP_FUNCTION(dd_tracer_circuit_breaker_open) { |
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.
As far as I can tell, the only functions that are being used in userland are dd_tracer_circuit_breaker_can_try()
, dd_tracer_circuit_breaker_register_error()
, and dd_tracer_circuit_breaker_register_success()
. So I'm curious if the other functions are just exposing an API for testing purposes? If so, I'm wondering if there's another solution that doesn't require adding additional functions in userland. Maybe only exposing them when compiling in debug mode or something? What are your thoughts? :)
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 wonder whats the downside keeping them in?
I would prefer to test as close to the final binary as possible so functions only exposed in tests would mean that we have two different binaries - which in turn could foster theoretical edge-cases which wouldn't be detected in tests.
Also those functions provide more access to the Circuit breaker and could be used to extend/ enhance the functioning a bit in the future.
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 wonder whats the downside keeping them in?
I'm just thinking of the commitment to ongoing maintenance and not exposing any API's that aren't necessary so we have fewer issues if we need to change or remove them. But I'm not saying we shouldn't add them, I'm just wondering if we have sufficient reason for adding them and are OK with any tradeoffs for adding them. So if you're confident, I'm confident too. :)
could be used to extend/ enhance the functioning a bit in the future.
I personally don't like adding code for possible future features since the domain could change and we have to commit to maintaining the future code for an indeterminate amount of time. In my experience, most times I've added future code, the future code is never used. :D
I would prefer to test as close to the final binary as possible
I agree - I think "to ensure stability" is a pretty good reason to expose these. I would prefer a method to ensure stability that doesn't expose any more public API's, but if there's really no other viable alternative, I'm on board with 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.
Excellent points Sammy!
I think I could remove a few functions though. Will probably be able to drop _close
and _open
. Probably _is_closed
to since its functionality is implemented by a new _info
.
91d3b15
to
8419d5a
Compare
72c4ac0
to
81a7cae
Compare
…exceptions for PHP 5
81a7cae
to
bc24a8e
Compare
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.
Lovely work @pawelchcki! :)
if ($this->isLogDebugActive() && function_exists('dd_tracer_circuit_breaker_info')) { | ||
self::logDebug('circuit breaker status: closed => {closed}, total_failures => {total_failures},' | ||
. 'consecutive_failures => {consecutive_failures}, opened_timestamp => {opened_timestamp}, ' | ||
. 'last_failure_timestamp=> {last_failure_timestamp}', dd_tracer_circuit_breaker_info()); |
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.
❤️
@@ -11,3 +11,4 @@ RELEASING.md export-ignore | |||
.circleci export-ignore | |||
.clang-format export-ignore | |||
src/ext/mpack/* linguist-generated=true | |||
src/ext/vendor_stdatomic.h linguist-generated=true |
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.
🔝
Description
This also persists the circuit breaker state between restarts so that if the PHP process is recycled it will inherit the CB state.
Its using
shm_open
to allocate shared memory object (on linux its an actual file in /dev/shm) base on path (path is built fromdd_trace_+VERSION_STRING
).Then that shared memory object is mapped to local address space and accessed locally via atomic C11 functions, guaranteeing consistency when setting /incrementing/changing a value.
See:
https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern
Readiness checklist