sentry-dart icon indicating copy to clipboard operation
sentry-dart copied to clipboard

Events for blocking calls

Open ueman opened this issue 2 years ago • 8 comments

Problem Statement

Similar to https://twitter.com/brungarc/status/1711484812702171309 it should be possible in Dart to detect blocking file IO calls.

There's also a lint rule (https://dart.dev/tools/linter-rules/avoid_slow_async_io) to enforce sync io but that can't be detected for 3rd party code. Depending on the lint rule, it could make sense to send events based on sync or async file io. In mobile apps, async io is probably the better choice, while on CLIs or backend code sync io could be better.

Solution Brainstorm

Whenever a sync file API is called, an event should be sent to Sentry. This can be done with the existing file plugin by adding extra events when the sync APIs are called.

Are you willing to submit a PR?

None

ueman avatar Oct 09 '23 21:10 ueman

Relates to: https://github.com/getsentry/sentry-dotnet/pull/2709

bruno-garcia avatar Oct 09 '23 21:10 bruno-garcia

This could be a performance issue generated by the backend, without the need to send an event when one of those APIs is called. We already have file.async in the span, so we could leverage that. Also, this is probably relevant to Flutter projects only

stefanosiano avatar Oct 12 '23 13:10 stefanosiano

How could a backend know if a File I/O call in a flutter app has been made? or am I understanding it wrong

buenaflor avatar Nov 06 '23 10:11 buenaflor

@buenaflor the idea is that we create a perf issue for sync file I/O, but only for Flutter apps. Since we already have the file.async flag in the file spans we send, the detector living in the backend needs to check if it's a Flutter app and can then create a perf issue.

kahest avatar Nov 06 '23 10:11 kahest

Got it, sounds reasonable, I would also opt for that route since we already have the mechanism in place to make it happen - unless there are other concerns

buenaflor avatar Nov 06 '23 11:11 buenaflor

In .NET the situation we want to track is when an async call is blocked on:

async Execute(delegate d)
{
     SomeAsyncMethod().Wait(); // blocks and can cause thread pool starvation

   // right call would be: 
   await SomeAsyncMethod();
}

So that's any async method (not just I/O) that happens on a async flow that's blocked on. Any .Result or .Wait() for example. A simple blocking file I/O wouldn't fire the detection, unless that was called within an async method (anywhere in the call chain).

In other words: On a program: void Main() { File.ReadAllLines()} -> Blocking I/O wouldn't fire anything because there's nothing async here being blocked on.

bruno-garcia avatar Nov 09 '23 00:11 bruno-garcia

Let's understand if it makes sense for Flutter, too. Let's investigate if the await keyword has the same meaning in Dart and .NET, and if Dart has a similar mechanism of .NET's Wait()

stefanosiano avatar Nov 14 '23 15:11 stefanosiano

We can check if we run on the main or the background isolate, so we can add this info in the file plugin to spans wrapping sync/async calls.

https://github.com/getsentry/sentry-dart/issues/1727#issuecomment-1838656748

https://github.com/getsentry/sentry-dart/issues/1727#issuecomment-1840739291

denrase avatar Dec 05 '23 15:12 denrase