Repository navigation
Commit 5e6844d
perf(core): Create outbox and cache dirs lazily instead of during init (JAVA-613) (#5792)
* perf(core): Create outbox and cache dirs lazily instead of during init (JAVA-613)
Sentry.initConfigurations created the outbox and cache directories
synchronously on the init thread, which on Android is the main thread.
Create each directory lazily in its consumer instead: the cache dir on
the first envelope write (transport thread), and the outbox dir in the
file-observer integration (executor thread) and before writing the
startup-crash marker. The native SDK already creates the outbox dir
itself during sentry_init, so NDK crash writes are unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* changelog
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* ref(core): Encapsulate lazy dir creation in a LazyDirectory value object (JAVA-613)
Replace the duplicated "create the dir if it does not exist" idiom in the
envelope cache, outbox file observer, and startup-crash-marker paths with a
single LazyDirectory type that materializes the directory on first access.
CacheStrategy now owns its directory as a LazyDirectory: write paths call
getOrCreate(), while path-building and validity checks use getFile() so they
do not create the directory as a side effect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* ref(core): Inject the cache LazyDirectory via the constructor (JAVA-613)
Have the composition roots (EnvelopeCache.create and AndroidEnvelopeCache)
build the LazyDirectory and pass it into CacheStrategy, so the cache no
longer constructs its own directory collaborator from a path string. The
public String constructor is kept and delegates, preserving binary
compatibility.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(core): Create the outbox dir in external envelope writers (JAVA-613)
Creating the outbox dir lazily moved the mkdirs() off the init thread onto
the SDK executor, so the dir is no longer guaranteed to exist once
Sentry.init returns. Writers that drop envelopes into the outbox
themselves raced that executor task and could fail with ENOENT, which is
what EnvelopeTests.sendsNativeTransaction hit on a slow emulator.
Have both external writers create the dir before writing, and document on
getOutboxPath that the directory is created lazily so hybrid SDKs writing
envelopes directly know they have to do the same.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(core): Create the cache dir before writing app-start config (JAVA-613)
The removed init-time mkdirs() ran on the dsn-hashed cache path and created
the un-hashed parent as a side effect. handleAppStartProfilingConfig writes
app_start_profiling_config into that parent via createNewFile(), which fails
with IOException when the parent is missing, and the surrounding catch
swallows it into a log line. The next launch then finds no config and cannot
start app-start profiling.
This was masked because the profiling traces dir still calls mkdirs() on
<cacheDir>/<dsnHash>/profiling_traces, creating the un-hashed grandparent --
but only when profiling is enabled, which every existing test did. The new
test leaves profiling off so nothing else materializes the dir.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* ref(core): Simplify the lazy directory creation helpers (JAVA-613)
The LazyDirectory value object was doing two unrelated jobs: holding a
directory that a long-lived cache creates on first write, and acting as a
one-shot mkdirs() helper at three call sites that constructed it only to
discard it immediately.
Split those apart. FileUtils.createDirectory covers the one-shot case and
returns whether the directory exists afterwards, so the callers log the
failure instead of discarding mkdirs()' return value and failing later in
an unrelated-looking write. LazyDirectory keeps only the cache use and
gains resolve(), which creates the parent before returning the child, so
write paths no longer depend on an earlier getOrCreate() call having run.
Creation is deliberately not cached: on Android the cache dir lives under
Context.getCacheDir(), which the system may wipe at any time, so each
write re-checks and the directory heals itself.
Also revert the LazyDirectory injection into CacheStrategy. Nothing
injected a custom instance, so it only added a public EnvelopeCache
constructor to the API surface for an internal change.
* fix(core): Report success when losing the createDirectory race (JAVA-613)
File.mkdirs() returns false both when it cannot create the directory and
when another thread got there first, so createDirectory reported a failure
for a directory that was present. Callers act on that by skipping their
write: a startup crash would go unmarked and the app-start profiling config
would not be written, even though the directory existed.
Re-check for the directory when mkdirs() fails, which separates losing the
race from a genuine failure such as missing permissions.
The added test fails reliably without the fix, with most of the racing
threads observing false.
* fix(core): Don't recreate the cache dir when discarding (JAVA-613)
getCurrentFile went through LazyDirectory.resolve, which creates the
directory as a side effect. discard() calls it while deleting from the
cache, so discarding an envelope could resurrect a cache dir that had
just been removed.
Compute the path without touching the filesystem instead, and drop
resolve entirely: the remaining write paths already call getOrCreate
once before writing.
* docs(core): Note the lazy dir creation as a behavioral change (JAVA-613)
Sentry.init used to mkdirs() the outbox and cache dirs synchronously, so
both were guaranteed to exist once it returned. They are now created by
whichever component first writes into them, off the init thread, which
breaks anyone writing envelopes into the outbox path directly instead of
going through the SDK -- notably the hybrid SDKs' captureEnvelope.
Call that out under Behavioral Changes so hybrid maintainers see it; the
existing Performance entry only describes the win, not the cost.
* docs(core): Explain why LazyDirectory swallows a failed mkdirs (JAVA-613)
getOrCreate() ignoring the return value of createDirectory() reads like
an oversight next to the callers that do log it, so record that write
paths already surface the failure via their own error handling.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent c318acd commit 5e6844d
18 files changed
Lines changed: 311 additions & 36 deletions
File tree
- sentry-android-core/src
- main/java/io/sentry/android/core
- cache
- test/java/io/sentry/android/core
- cache
- sentry-android-integration-tests
- sentry-uitest-android-critical/src/main/java/io/sentry/uitest/android/critical
- sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android
- sentry
- api
- src
- main/java/io/sentry
- cache
- util
- test/java/io/sentry
- cache
- util
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
5 | 11 | | |
6 | 12 | | |
7 | 13 | | |
| |||
14 | 20 | | |
15 | 21 | | |
16 | 22 | | |
| 23 | + | |
17 | 24 | | |
18 | 25 | | |
19 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| |||
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
70 | 78 | | |
71 | 79 | | |
72 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
96 | | - | |
| 96 | + | |
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
110 | 117 | | |
111 | 118 | | |
112 | 119 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
122 | 124 | | |
123 | 125 | | |
124 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
125 | 142 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
128 | 142 | | |
129 | 143 | | |
130 | 144 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
69 | 72 | | |
70 | 73 | | |
71 | 74 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
262 | 262 | | |
263 | 263 | | |
264 | 264 | | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
265 | 270 | | |
266 | 271 | | |
267 | | - | |
| 272 | + | |
268 | 273 | | |
269 | 274 | | |
270 | 275 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7692 | 7692 | | |
7693 | 7693 | | |
7694 | 7694 | | |
| 7695 | + | |
7695 | 7696 | | |
7696 | 7697 | | |
7697 | 7698 | | |
| |||
7757 | 7758 | | |
7758 | 7759 | | |
7759 | 7760 | | |
| 7761 | + | |
| 7762 | + | |
| 7763 | + | |
| 7764 | + | |
| 7765 | + | |
| 7766 | + | |
7760 | 7767 | | |
7761 | 7768 | | |
7762 | 7769 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
463 | 463 | | |
464 | 464 | | |
465 | 465 | | |
| 466 | + | |
466 | 467 | | |
467 | | - | |
| 468 | + | |
468 | 469 | | |
469 | 470 | | |
470 | 471 | | |
| |||
481 | 482 | | |
482 | 483 | | |
483 | 484 | | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
484 | 493 | | |
485 | 494 | | |
486 | 495 | | |
| |||
616 | 625 | | |
617 | 626 | | |
618 | 627 | | |
619 | | - | |
620 | | - | |
621 | | - | |
622 | | - | |
623 | | - | |
624 | | - | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
625 | 631 | | |
626 | 632 | | |
627 | 633 | | |
628 | 634 | | |
629 | 635 | | |
630 | | - | |
631 | | - | |
632 | 636 | | |
633 | 637 | | |
634 | 638 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1104 | 1104 | | |
1105 | 1105 | | |
1106 | 1106 | | |
1107 | | - | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
1108 | 1112 | | |
1109 | 1113 | | |
1110 | 1114 | | |
| |||
0 commit comments