-
-
Notifications
You must be signed in to change notification settings - Fork 452
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
Implement support for flushable clients #813
Implement support for flushable clients #813
Conversation
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 change seems too overly complicated to me, especially compared to #799. Since PHP doesn't have pure async, this seems an overkill to have not so much advantage. Also, due to the fact that the user still needs to call a specific method, using #799 and wrapping the await/flush
call in an async tool of their own seems a better choice to me.
I decided to drop the |
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.
🚢
Please edit the description of this PR then, I was thrown off-track by that 😅 |
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 did just a quick scan, but LGTM 👍
Any updates on when this will be released? :) |
We are currently preparing for the release of 2.2 which will contain this PR. So it'll be soon :) |
@stayallive Is there anything we can do to help? We are missing out on a ton of data because we are using Sentry in production - with this level of support I have actually started looking into alternative solutions to Sentry. I guess it is really not a rare use case to use Sentry on queue consumers and other kinds of CLI scripts |
@Spriz, 2.2 was released a few days ago. An issue was fixed when $client = \Sentry\SentrySdk::getCurrentHub()->getClient();
if ($client instanceof FlushableClientInterface) {
$client->flush();
} The code above will force all events that might be in the queue to be sent immediately and not wait for the script to exit, ofcourse it still sends the events once a script exits. For an implementation example you can look at the Laravel integration which flushes events in the queue worker after processing an queue job: https://github.com/getsentry/sentry-laravel/blob/db55dfbb7d45fbda042131ec65ddf5b3eaf2a90e/src/Sentry/Laravel/Integration.php#L89-L102 Let me know if this solves your issues or we missed a use case! |
Amazing @stayallive - we will implement one of the next few days, and I will get back at ya if we miss anything! 👏 🎉 |
@stayallive I've been looking at the latest release and the Laravel integration, but I'm still struggling to understand how it is currently meant to work and also don't exactly know where you're heading with a 3.0 release. As far as I understand the code in HttpTransport all events are now sent directly and synchronously. Also, with the current implementation So the code in Laravel is currently a Noop, as the integration does not provide their own HttpTransport implementation. Speaking of that. I also looked into what I would need to do to implement my own Transport. To do so, it would basically require me to also completely implement (or copy) My goals I'm trying to achieve is creating an
While I can certainly do that, I don't feel comfortable with the amount of adaptation I need to do and therefore asking for your advice. Should I just implement my own I'd happily do the latter, but wonder why Thanks a bunch! |
You made a bunch of good questions. I will speak for the core SDK as I don't know how the Laravel integration is implemented.
That transport was never meant to be asyncronous nor was meant to delay sending of events until the shutdown of the application, but I didn't know at the time I coded it that requests are not sent until you call
You're again right. The issue has been fixed with #855 which is scheduled for release with version
The
The plan for |
Ah, OK good to know. So the intention always was to send events immediately and synchronously. And that in 2.2 events were delayed until PHP shutdown was actually a bug (#799, #811), which was fixed here. Correct?
No, that is how it now works. Thanks for the clarification.
Ah, cool. That would be exactly what I need, when implementing my own Transport.
Also good to know, thanks!
Do I understand it correctly, that I could do a pull request to do so, or it does not matter much because of:
I have a sense what you mean, but just to be sure we're on the same page, I try to rephrase in my own words: In a synchronous PHP application (not ReactPHP or similar), there is no way to execute code asynchronously, so In a ReactPHP application a Transport implementation of If my understanding is correct, then all is fine for me and I can adapt to that with my integration. Last remaining question though: I would still like to have to possibility that my integration is notified for each event that failed to be sent. While I could implement my own HttpTransport for that, it feels a bit like too much for this little addition (even with #855 in place). Would you accept a PR that adds an option Thanks again! |
So, I thought one thing and I wrote something else so I will amend my previous statement, sorry for this. When I implemented the
As I see it now it's a kind of bug since the name of the transport implies that it's syncronous. However, to not break the behavior of existing applications I cannot change when the events are sent and this would anyway heavily hurt performances. Plus, since PHP has no concept of async and we send one request at time we will always send one at time, no matter what or where we do it.
Actually the problem of requests that are not sent until the shutdown in long-running processes is not fixed with this PR as it's missing the implementation of the
You understood right. The key is that PHP has no concept of async and Curl can only send requests in parallel, but not asyncronously. Libraries like ReactPHP implements their own event loop, so as long as you integrate with it you can have a "truly" asyncronous application and
This is being discussed in #886. The proposal I did was to log errors/debug messages using a PSR-3 logger (which by default would be noop). For sure we won't let exceptions throw/bubble as it would break the entire application of course making this library useless. I would like to avoid adding more options as we already have many of them. I'm not sure if the Unified API specs says something on this matter, but I strongly suggest anyway to continue the discussion in the referenced PR |
No worries! Just trying to understand and adapt based on that. Thanks for giving me further details promptly!
Got it, thanks.
Speaking of the default implementation (using
As I tried to point out above, it isn't very easy to rely on the default behavior of the
You will only face the problem, when implementing providing your own instance of HttpTransport using the deprecated behavior (neither of these integrations does so btw.). What I'm trying to say is: default usage of sentry-php
Are we now on the same page? :) |
Stepping back from the discussion here, I wanted to provide some sample real-world numbers on two different HTTP performance improvements:
Some sample metrics for sending four events to my on-premise Sentry server:
|
Thanks @mfb! Sounds reasonable. Have implemented that for sentry-php? If so, it would be great if you could share how (either as code or just the way you did it). Thanks. |
Not yet, just doing some benchmarking to see what directions are worth exploring. |
This is indeed a regression and change of default behavior (what I was trying to explain in the comments I wrote before) and will be fixed in #905. For long-running processes, since PHP doesn't have true async you should implement your own transport that flush events using the
The |
Perfect! Thanks a bunch! |
This PR is another attempt other than #799 to fix #811 and getsentry/sentry-laravel#222.
It involves much more changes and do not follow the unified API that expect some methods on the client likeflush
orclose
. Instead, it exposes new methods with theAsync
suffix that return promises and, depending on the implementation, these may be resolved immediatly when they are created (think about a syncronous transport) or at some point in time. The decision to not follow the unified API is because in PHP there is no concept of real async, so having such methods that internally resolves the promises like in the JavaScript SDK would just make them syncronous. There are also some libraries and frameworks like Swoople or ReactPHP that use an event loop (similar to NodeJS) that runs and can periodically tick a queue or advance a timer: this is what we are looking for. cURL can send requests in parallel but is not async at all. To do it in fact, you have to use a loop that will tick the internal queue of requests to send them a little at a time, but obviously this will block the code execution. This is why some HTTP clients like Guzzle have their own queue that can be ticked from the outside and this is what users must do by integrating such libraries with their own event-driven loop.It follows the specs of the Unified API and implements a
flush
method on the client that can be called by clients to drain the queue of events being sent on-demand. Since in PHP there is no concept of async out-of-the-box there is no implementation of an async client provided, thus the$timeout
parameter is effectively ignored.