Skip to content

perf(service): construct RustInterface off the main thread - #346

Merged
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
0xbrayo:perf/background-service-off-thread-init
Oct 10, 2026
Merged

ErikBjare merged 1 commit into
ActivityWatch:masterfrom
0xbrayo:perf/background-service-off-thread-init

Conversation

@0xbrayo

@0xbrayo 0xbrayo commented Oct 8, 2026

Copy link
Copy Markdown
Member

Part of #333.

BackgroundService.onCreate constructed RustInterface on the main thread. Construction runs System.loadLibrary("aw_server") plus the JNI initialize / setDataDir, which the code's own comment notes "can take several seconds on slow/no-KVM emulators". #262 moved exactly this off the main thread for the watchers, MainActivity and the alarm receiver; the service was the remaining caller.

Change

  • rustInterface is now an OffThreadInit<RustInterface> started in onCreate, after foreground promotion as before.
  • Its three users (server start, hostname migration, watcher-bucket migration) already run on IO coroutines and now await() it there.
  • The server-start coroutine awaits before taking sanitizedMigrationLock. Construction doesn't open the database, so it doesn't need to be ordered against the hostname rewrite.
  • If the native library fails to load, that is logged and the dependent work is skipped, instead of crashing the service in onCreate.

Testing

  • ./gradlew :mobile:testStandardDebugUnitTest passes, including BackgroundServicePolicyTest and OffThreadInitTest.

@greptile-apps

greptile-apps Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] This PR appears safe to merge.

Summary

Moves RustInterface construction off the main thread in BackgroundService.

  • Server startup and both native migrations await initialization on IO coroutines.
  • Server startup keeps the existing migration lock and shutdown check.
  • 0xbrayo explicitly intends initialization failures to be logged and dependent work skipped.
  • No actionable issues found. Tests were inspected, not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["onCreate: enter foreground"] --> B["Start BackgroundService-init thread"]
    B --> C["Construct RustInterface"]
    A --> D["onStartCommand: prepare dashboard key"]
    D --> E["IO: await initialization"]
    D --> F["IO: await initialization"]
    C --> E
    C --> F
    E --> G["Take sanitizedMigrationLock"]
    G --> H{"Service destroyed?"}
    H -->|No| I["Rewrite hostname, then start server"]
    H -->|Yes| J["Skip server startup"]
    F --> K["Migrate hostname, then watcher buckets"]
    C -->|Failure| L["Log and skip dependent work"]
Loading

Reviews (1) · Last reviewed commit: "perf(service): construct RustInterface o..." · Reviewed by Greptile

BackgroundService.onCreate built RustInterface on the main thread, which
loads libaw_server.so and runs the JNI initialize: the startup hang
ActivityWatch#262 removed from the watchers. Construct it with OffThreadInit and
await it in the IO coroutines that already use it. A native-library
failure is now logged instead of crashing the service.
@0xbrayo
0xbrayo force-pushed the perf/background-service-off-thread-init branch from bf24a6c to f0a8819 Compare October 8, 2026 19:37
@ErikBjare
ErikBjare merged commit 9fd6879 into ActivityWatch:master Oct 10, 2026
7 of 8 checks passed
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.

2 participants