Page MenuHomePhabricator

[native] Implement persistent rust backup client
ClosedPublic

Authored by michal on Jan 12 2024, 7:58 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Nov 21, 3:52 AM
Unknown Object (File)
Thu, Nov 21, 3:52 AM
Unknown Object (File)
Oct 22 2024, 1:06 PM
Unknown Object (File)
Oct 22 2024, 9:00 AM
Unknown Object (File)
Oct 22 2024, 8:37 AM
Unknown Object (File)
Oct 22 2024, 8:37 AM
Unknown Object (File)
Oct 22 2024, 8:37 AM
Unknown Object (File)
Oct 22 2024, 8:37 AM
Subscribers

Details

Summary

ENG-6213 : Create long lived backup client

Implemented a native rust backup client that creates a websocket connection for logs, keeps it alive and retries when getting an error.

Test Plan

Tested on Android and iOS:

  • Started the backup handler -> checked the backup service logs for new websocket connection
  • Waited a bit to make sure ping and pongs are handled correctly
  • Killed the backup service and restarted it -> the connectino was restarted automatically

Diff Detail

Repository
rCOMM Comm
Lint
No Lint Coverage
Unit
No Test Coverage

Event Timeline

native/native_rust_library/src/backup.rs
127

This will never resolve and is just for testing.

134

Tungstenite handles ping messages by itself, but we need to await it.

Harbormaster returned this revision to the author for changes because remote builds failed.Jan 12 2024, 8:11 AM
Harbormaster failed remote builds in B25728: Diff 35577!
Harbormaster returned this revision to the author for changes because remote builds failed.Jan 15 2024, 4:31 AM
Harbormaster failed remote builds in B25757: Diff 35608!
bartek requested changes to this revision.Jan 16 2024, 4:50 AM

Nothing wrong with the code, I just want to understand it better before accepting, left some questions. Feel free to re-request

native/native_rust_library/src/backup.rs
28–46 ↗(On Diff #35609)

One thing I don't like about code organization here is that:

  • start_backup_handler() does the UPLOAD_HANDLER.lock()?.take() directly inside the function
  • stop_backup_handler_sync() does it inside another function stop_backup_handler()

Also, can you briefly explain (from the sync/async/threading perspective) why one function is doing the lock().take() logic directly and then spawns a RUNTIME task, while the other does this inside that task?

41 ↗(On Diff #35609)

why is it called _sync while it spawns an async task and returns a promise?

118–120 ↗(On Diff #35609)
  1. Maybe another log that we're retrying connection now.
  2. This println has the same message as above in L104 - it's makes it a little bit harder to debug
  3. Should we consider using tracing in native_rust_library in the future?
This revision now requires changes to proceed.Jan 16 2024, 4:50 AM

Fixes

native/native_rust_library/src/backup.rs
28–46 ↗(On Diff #35609)

I have removed the async from the stop handler function and now it works like the start handler function.

The reason it looked like this is because when I was implementing this code, the stop_backup_handler could optionally wait for all data to be uploaded and this required some async operations (e.g. checking if all files were uploaded).

I decided to move this logic to a later diff but the general structure remained (but it's now fixed).

41 ↗(On Diff #35609)

This has been a naming convention I have been using for async functions exposed to cxx (because they can't be exposed directly).

  • fn xxx_sync(args, promise_id: u32) -> that spawns the task on runtime and handles resolving the promise
  • async fn xxx(args) -> Result<(), Error> -> that contains the business logic

for some identity functions we use fn xxx() and async fn xxx_helper() convention but I'm not a fan of that.

118–120 ↗(On Diff #35609)

1,2 fixed. I will make a task for 3

Some renames and code refactor to make it cleaner

Thanks for the explanations!

This revision is now accepted and ready to land.Jan 18 2024, 11:34 PM