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 UserFeedback disk cache name conflicts with linked events #3116

Merged
merged 13 commits into from
Jan 26, 2024

Conversation

markushi
Copy link
Member

@markushi markushi commented Dec 21, 2023

📜 Description

Until now we used the event-id (if available) for determining the file name for the disk cache. But this fails for UserFeedback because it’s event-id can be identical to the event-id of a linked (Crash) Event.

Cocoa is using a unique file name based on a counter + random UUID, which sounds reasonable, so I resorted to always use as random UUID as well.

💡 Motivation and Context

Fixes #2902

💚 How did you test it?

Added unit tests

📝 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

Copy link
Contributor

github-actions bot commented Dec 21, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 382.80 ms 461.41 ms 78.61 ms
Size 1.70 MiB 2.27 MiB 584.63 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
8ff8fd0 432.77 ms 495.18 ms 62.41 ms
86f0096 368.63 ms 446.92 ms 78.29 ms
c7e2fbc 377.85 ms 426.35 ms 48.50 ms
2a3dd50 363.61 ms 440.18 ms 76.57 ms
0bd723b 375.20 ms 452.41 ms 77.20 ms
2465853 400.64 ms 465.47 ms 64.83 ms
4e29063 364.08 ms 445.51 ms 81.43 ms
4e260b3 388.40 ms 468.98 ms 80.58 ms
e6ffd7b 379.52 ms 449.30 ms 69.78 ms
c7e2fbc 393.98 ms 478.24 ms 84.27 ms

App size

Revision Plain With Sentry Diff
8ff8fd0 1.72 MiB 2.27 MiB 558.15 KiB
86f0096 1.72 MiB 2.29 MiB 576.50 KiB
c7e2fbc 1.72 MiB 2.29 MiB 576.40 KiB
2a3dd50 1.72 MiB 2.27 MiB 555.05 KiB
0bd723b 1.72 MiB 2.29 MiB 578.09 KiB
2465853 1.70 MiB 2.27 MiB 583.82 KiB
4e29063 1.72 MiB 2.29 MiB 578.38 KiB
4e260b3 1.72 MiB 2.27 MiB 554.95 KiB
e6ffd7b 1.72 MiB 2.29 MiB 579.13 KiB
c7e2fbc 1.72 MiB 2.29 MiB 576.40 KiB

Previous results on branch: fix/cache-conflict

Startup times

Revision Plain With Sentry Diff
6070114 392.96 ms 449.68 ms 56.72 ms
d39edd7 391.06 ms 473.57 ms 82.51 ms
cfa7caa 392.00 ms 470.24 ms 78.24 ms
673e0bb 433.27 ms 575.22 ms 141.96 ms
b57cee4 390.69 ms 443.68 ms 52.99 ms
03dc342 401.17 ms 477.33 ms 76.16 ms
829f669 383.06 ms 444.41 ms 61.35 ms

App size

Revision Plain With Sentry Diff
6070114 1.70 MiB 2.27 MiB 583.73 KiB
d39edd7 1.72 MiB 2.27 MiB 558.33 KiB
cfa7caa 1.70 MiB 2.27 MiB 584.63 KiB
673e0bb 1.72 MiB 2.27 MiB 558.30 KiB
b57cee4 1.70 MiB 2.27 MiB 583.74 KiB
03dc342 1.70 MiB 2.27 MiB 583.73 KiB
829f669 1.72 MiB 2.27 MiB 558.44 KiB

Copy link
Member

@romtsn romtsn left a comment

Choose a reason for hiding this comment

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

LGTM, but I only see one potential issue with this: when we are sending envelopes on app start (in DirectoryProcessor), there's a case when rate limiting gets active for an envelope and we're discarding it from cache here:

if (filteredEnvelope == null) {
if (cached) {
envelopeCache.discard(envelope);
}
} else {

With this change, the .discard method will not do anything, because it will not find the correct envelope file name, but will just generate a new one. I don't know if we should account for this case, but I guess we should? Or we could actually just remove this check I guess, because #2937 is doing all that already? And we anyway delete the envelope file in proccessFile here:

// Unless the transport marked this to be retried, it'll be deleted.
HintUtils.runIfHasTypeLogIfNot(
hint,
Retryable.class,
logger,
(retryable) -> {
if (!retryable.isRetry()) {
safeDelete(file, "after trying to capture it");
logger.log(SentryLevel.DEBUG, "Deleted file %s.", file.getAbsolutePath());
} else {
logger.log(
SentryLevel.INFO,
"File not deleted since retry was marked. %s.",
file.getAbsolutePath());
}
});

@markushi
Copy link
Member Author

markushi commented Jan 22, 2024

LGTM, but I only see one potential issue with this: when we are sending envelopes on app start (in DirectoryProcessor), there's a case when rate limiting gets active for an envelope and we're discarding it from cache here:

if (filteredEnvelope == null) {
if (cached) {
envelopeCache.discard(envelope);
}
} else {

With this change, the .discard method will not do anything, because it will not find the correct envelope file name, but will just generate a new one. I don't know if we should account for this case, but I guess we should? Or we could actually just remove this check I guess, because #2937 is doing all that already? And we anyway delete the envelope file in proccessFile here:

// Unless the transport marked this to be retried, it'll be deleted.
HintUtils.runIfHasTypeLogIfNot(
hint,
Retryable.class,
logger,
(retryable) -> {
if (!retryable.isRetry()) {
safeDelete(file, "after trying to capture it");
logger.log(SentryLevel.DEBUG, "Deleted file %s.", file.getAbsolutePath());
} else {
logger.log(
SentryLevel.INFO,
"File not deleted since retry was marked. %s.",
file.getAbsolutePath());
}
});

Yeah, good callout!
But doesn't the DirectoryProcessor set the SendCachedEnvelopeHint in order to avoid re-caching the same envelope? So cached would be false here, which is fine:

if (filteredEnvelope == null) {
if (cached) {
envelopeCache.discard(envelope);
}
} else {

@romtsn But I think I'm missing something, as where would the file from cache be finally deleted?

@romtsn
Copy link
Member

romtsn commented Jan 22, 2024

So cached would be false here, which is fine:

It'll be true actually, because SendCachedEnvelopeHint implements Cached:

if (HintUtils.hasType(hint, Cached.class)) {
currentEnvelopeCache = NoOpEnvelopeCache.getInstance();
cached = true;
options.getLogger().log(SentryLevel.DEBUG, "Captured Envelope is already cached");
}

@romtsn But I think I'm missing something, as where would the file from cache be finally deleted?

It's done here

if (!retryable.isRetry()) {
safeDelete(file, "after trying to capture it");
logger.log(SentryLevel.DEBUG, "Deleted file %s.", file.getAbsolutePath());

and looking at this we probably don't even need that envelopeCache.discard call, because the envelope is anyway gonna be deleted here^

@markushi markushi merged commit 7ab32b6 into main Jan 26, 2024
25 checks passed
@markushi markushi deleted the fix/cache-conflict branch January 26, 2024 15:47
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.

UserFeedback envelope not cached
3 participants