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
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

native/native_rust_library/src/backup.rs
127 ↗(On Diff #35577)

This will never resolve and is just for testing.

134 ↗(On Diff #35577)

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