-
Notifications
You must be signed in to change notification settings - Fork 83
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
Feature/injectable transport #116
base: master
Are you sure you want to change the base?
Feature/injectable transport #116
Conversation
I like that this is a non-invasive change and should not break existing users. Could you add a more concrete of an example (or describe) as to why this approach is advantageous over checking the host/port configuration prior to constructing |
d992eb3
to
f9f4569
Compare
Minor: fopen('/dev/null', 'r') is not cross-platform. As much as this will run in a *nix environment. I like to run test-suites on ANY reasonable machine.
Thanks to Yoast!
f9f4569
to
2a1c935
Compare
$socket = is_null($this->socketPath) ? socket_create(AF_INET, SOCK_DGRAM, SOL_UDP) | ||
: socket_create(AF_UNIX, SOCK_DGRAM, 0); | ||
socket_set_nonblock($socket); | ||
|
||
if (!is_null($this->socketPath)) { | ||
$res = socket_sendto($socket, $message, strlen($message), 0, $this->socketPath); | ||
} else { | ||
$res = socket_sendto($socket, $message, strlen($message), 0, $this->host, $this->port); | ||
} |
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.
IMO, this is a win.
$this->transportFactory = ( | ||
isset($config['transport_factory']) ? | ||
$transportFactory : | ||
new BridgingTransportFactory($this->socketPath, $this->host, $this->port) | ||
); | ||
|
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.
What I had hoped might be pointed out is that this could be an alternative to https://github.com/DataDog/php-datadogstatsd/pull/116/files#diff-baf3cb376e36dfcf767f6389163de7d731798b1b108a44f33a2047e8e98bae3bR88-R98
I didn't want to leap too far in a single refactoring; and I think this should be part of a Configuration, that specific factory implementations could offer. So that implementations of transport are simple, and do not have cascading logic, or magic coming from the environment; but another layer can add that for them, or omit that, as the example in the README.md does.
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 think we are pretty close. Nice PR - and nice additions.
Mostly comments about the documentation and wording.
@@ -465,15 +477,7 @@ public function flush($message) | |||
$message .= $this->flushTelemetry(); | |||
|
|||
// Non - Blocking UDP I/O - Use IP Addresses! |
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.
NIT: This comment can be removed
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.
Your comment?
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.
yep - this comment is no longer relevant since the implementation moved (plus It's not a great comment to begin with)
@@ -46,6 +46,64 @@ $statsd = new DogStatsd( | |||
|
|||
DogStatsd constructor, takes a configuration array. See the full list of available [DogStatsD Client instantiation parameters](https://docs.datadoghq.com/developers/dogstatsd/?code-lang=php#client-instantiation-parameters). | |||
|
|||
#### Migrating from legacy configuration |
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'd call this section "Using a custom transport factory"
Overall I think this whole section is valuable but perhaps a bit verbose for the readme. Could you create a root level docs
folder with this as a markdown document and link to it from the readme?
In this readme you could have a brief section
If you want more control over how transports are constructed see
custom-transport-factory.md
on how to implement a custom transport factory.
} | ||
``` | ||
|
||
##### Instantiating datadog with your new class |
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.
##### Instantiating datadog with your new class | |
##### Instantiating DogStatsd with your custom transport factory |
namespace YourOrg\Metrics; | ||
|
||
/** | ||
* This class works around the decisions the constructor of DogStatsd class |
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.
NIT: reword to something like:
Custom transport factory that validates a host and port are not empty. This extends the default behavior where these errors would otherwise fail silently.
@@ -46,6 +46,64 @@ $statsd = new DogStatsd( | |||
|
|||
DogStatsd constructor, takes a configuration array. See the full list of available [DogStatsD Client instantiation parameters](https://docs.datadoghq.com/developers/dogstatsd/?code-lang=php#client-instantiation-parameters). | |||
|
|||
#### Migrating from legacy configuration | |||
|
|||
In some setups, the use of environment variables can cause surprises, such as warnings, test-failures, etc. |
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.
NIT: just want to reword this a bit. We prefer to be brief in the readme with a focus on usage. If you feel that the extended explanation is valuable, please add it in the code comments or in a dedicated document (as suggested above)
Perhaps something like (replacing lines 51-53):
Using environment variables for configuration may not always be ideal. If you want extra control over how transports are constructed or validated consider implementing a custom
TransportFactory
. You can achieve this by implanting the DataDog\TransportFactoryinterface and suppling it to the
transport_factory` configuration.
); | ||
``` | ||
|
||
#### Why this structure? |
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 think we can drop this section from the readme. Perhaps add this as a code comment (or feel free to include it in a separate document)
@@ -19,16 +19,28 @@ x-dockerbuild-5: &dockerbuild-5 | |||
- run: composer lint | |||
|
|||
jobs: | |||
test-8.0: |
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.
Thanks for adding the extended test coverage 💯
Ive cherrypicked the test fixes from this PR #127 and merged them. |
Fixes #115
GitHub actions (until I'd fixed, I actually had a really slow feedback loop)The actual guard portion of this, doesn't have to be owned by this repo. In the README.md I added a section with example to bypass the magic, re-using the Ipv4Udp transport that is part of this PR, so that an example of instrumenting the control I was looking for (bypassing the magic in current constructor) is available.
I'm not 💯 sure about the construct with single method interface, but felt that opening and closing the socket separately to the functionality; could make some future testing easier. I Also didn't want to open a long-lived socket (although the classes don't hint at that, the way they are used in one place enforces for-now).
The interfaces are pretty stripped-back to deal with PHP 5.6 minimum. Not sure where DataDog is going with that, but I think users would get a lot of benefit rolling up to only 7.4 & 8+ in a future release.
Why interfaces
Short answer. I Hate the array approach. It's too open a design, and leads to choices where spooky [mis]configuration can happen. While this one interface won't change the entire codebase, it nudges in a direction a lot of PHP coders are going.
I'm not sure that adding
strict_mode
to counteract the magic will make this code any more readable or be the right way to counteract the magic cascade. For an upstream vendor to us this, implement the interface, I believe is a far more intentional choice, that leaves the majority of users happy where they are now. Internalgetenv
may be a feature for people who have not had silent misconfiguration lead to confusing bugs.Another reason for an interface based approach is that I think a test implementation that allows spy test-double would be a nice thing that this allows. Instead of using curl spy test class and the socket spy test class, which are namespace coordination dependent.
Lastly, This interface approach would enable any coder: