Skip to content
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

Fix crash on double SDK init #2679

Merged
merged 6 commits into from
Apr 28, 2023
Merged

Fix crash on double SDK init #2679

merged 6 commits into from
Apr 28, 2023

Conversation

stefanosiano
Copy link
Member

📜 Description

all calls to ISentryExecutorService are now wrapped in a try catch block
closing the hub will close the profiler and the performance collector

💡 Motivation and Context

Calling init() multiple times closes any previous instance of the SDK.
After closing, any call to the executor service which was previously scheduled resulted in a crash due to RejectedExecutionException.
Fixes #2493

💚 How did you test it?

Unit and ui test

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

closing the hub will close the profiler and the performance collector
added ui test for double init
span.setSpanFinishedCallback(null);
span.finish(SpanStatus.CANCELLED);
}
transaction.finish(SpanStatus.CANCELLED);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it right to close the current transaction?
Also, should we think about closing any other manual transaction started by the user?
Transactions keep a reference to the old options, and so to the executor service, possibly leading to a crash. In reality all calls are now wrapped in try catch blocks, so it's a non-issue.
It's more to understand if it makes sense to stop the transactions from a end user perspective

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense, especially for Mobile. @adinauer does this seem right for you as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are dropping canceling the transaction for the moment, as we have to be careful on the backend use case.
Worst case we will show some errors in the logs, pointing at a possible Sentry.close() previous call.
In another pr we will reevaluate cancelling the current transactions.

@stefanosiano stefanosiano marked this pull request as ready for review April 27, 2023 15:19
@github-actions
Copy link
Contributor

github-actions bot commented Apr 27, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 295.15 ms 336.50 ms 41.35 ms
Size 1.72 MiB 2.26 MiB 553.71 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
33c80c7 331.94 ms 370.54 ms 38.60 ms
d81684e 235.73 ms 328.76 ms 93.03 ms
17ab223 427.65 ms 484.31 ms 56.65 ms
33c80c7 318.88 ms 348.14 ms 29.26 ms

App size

Revision Plain With Sentry Diff
33c80c7 1.73 MiB 2.26 MiB 551.46 KiB
d81684e 1.73 MiB 2.26 MiB 547.78 KiB
17ab223 1.73 MiB 2.34 MiB 626.85 KiB
33c80c7 1.73 MiB 2.26 MiB 551.46 KiB

Previous results on branch: fix/multiple-sdk-init

Startup times

Revision Plain With Sentry Diff
06cb003 280.50 ms 319.10 ms 38.60 ms
8899387 327.19 ms 381.38 ms 54.19 ms

App size

Revision Plain With Sentry Diff
06cb003 1.72 MiB 2.26 MiB 553.71 KiB
8899387 1.72 MiB 2.26 MiB 553.62 KiB

Copy link
Member

@markushi markushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good already, please have a look at my comments!

span.setSpanFinishedCallback(null);
span.finish(SpanStatus.CANCELLED);
}
transaction.finish(SpanStatus.CANCELLED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense, especially for Mobile. @adinauer does this seem right for you as well?

sentry/src/main/java/io/sentry/Hub.java Outdated Show resolved Hide resolved
transaction.finish()
sampleScenario.moveToState(Lifecycle.State.DESTROYED)
val transaction2 = Sentry.startTransaction("e2etests", "testInit")
transaction2.finish()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I think there's one more test to cover which would fail right now: Initializing the SDK with the same options twice.

val options = {}
Sentry.init(options)
Sentry.close()
Sentry.init(options)

I guess the solution here would be to re-init the executor-service in .init()

profiling is now stopped on executorService exceptions
transaction bound to the scope is not cancelled automatically anymore on Sentry.close()
ISentryExecutorService is re-init in Sentry.init if it was shutdown
@codecov
Copy link

codecov bot commented Apr 28, 2023

Codecov Report

Patch coverage: 89.13% and project coverage change: +0.04 🎉

Comparison is base (544da32) 81.28% compared to head (c0607ab) 81.33%.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2679      +/-   ##
============================================
+ Coverage     81.28%   81.33%   +0.04%     
- Complexity     4263     4271       +8     
============================================
  Files           337      337              
  Lines         15759    15795      +36     
  Branches       2080     2083       +3     
============================================
+ Hits          12810    12847      +37     
+ Misses         2128     2125       -3     
- Partials        821      823       +2     
Impacted Files Coverage Δ
sentry/src/main/java/io/sentry/Sentry.java 83.66% <80.00%> (+0.67%) ⬆️
...sentry/DefaultTransactionPerformanceCollector.java 91.54% <89.47%> (-1.18%) ⬇️
sentry/src/main/java/io/sentry/Hub.java 76.99% <100.00%> (+0.16%) ⬆️
...main/java/io/sentry/NoOpSentryExecutorService.java 85.71% <100.00%> (+52.38%) ⬆️
...io/sentry/NoOpTransactionPerformanceCollector.java 100.00% <100.00%> (ø)
...c/main/java/io/sentry/NoOpTransactionProfiler.java 100.00% <100.00%> (ø)
...ry/SendCachedEnvelopeFireAndForgetIntegration.java 68.08% <100.00%> (+2.96%) ⬆️
...src/main/java/io/sentry/SentryExecutorService.java 95.23% <100.00%> (+0.50%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@markushi markushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks good to me!

@stefanosiano stefanosiano merged commit 64bd675 into main Apr 28, 2023
18 checks passed
@stefanosiano stefanosiano deleted the fix/multiple-sdk-init branch April 28, 2023 16:14
@@ -339,6 +339,10 @@ public void close() {
((Closeable) integration).close();
}
}

withScope(scope -> scope.clear());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

late to the party, but this is not gonna do much, because withScope will duplicate the scope, and then we're trying to clear the duplicated scope, but the main scope stays untouched. This should be changed to configureScope. I think we need a custom lint rule to never use withScope on mobile 😅 this is the second time we introduced something like this (this one is not as severe though).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

java.util.concurrent.RejectedExecutionException
3 participants