Skip to content

Commit 4693f31

Browse files
Rocky43007fogodev
andauthored
Working Sync & Thumbnail Sync (#2875)
* First draft on new p2p design * Test sync * Sync works * Update version * Fix merge conflicts * More stuff for thumbnail sync * Get the thumbnail * Update mod.rs * Working thumbnail sync * Format * Update thumbnails.rs * Update runner.rs * Update runner.rs --------- Co-authored-by: Ericson Soares <[email protected]>
1 parent 2ee6218 commit 4693f31

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1857
-447
lines changed

Cargo.lock

Lines changed: 296 additions & 271 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,50 +20,53 @@ rust-version = "1.81"
2020

2121
[workspace.dependencies]
2222
# First party dependencies
23-
sd-cloud-schema = { git = "https://github.com/spacedriveapp/cloud-services-schema", rev = "4e4565bee4" }
23+
sd-cloud-schema = { git = "https://github.com/spacedriveapp/cloud-services-schema", rev = "515ba740ea" }
2424

2525
# Third party dependencies used by one or more of our crates
26+
anyhow = "1.0.94"
2627
async-channel = "2.3"
2728
async-stream = "0.3.6"
2829
async-trait = "0.1.83"
29-
axum = "0.7.7"
30-
axum-extra = "0.9.4"
30+
axum = "0.7.9"
31+
axum-extra = "0.9.6"
3132
base64 = "0.22.1"
32-
blake3 = "1.5.4"
33-
bytes = "1.7.1" # Update blocked by hyper
34-
chrono = "0.4.38"
33+
blake3 = "1.5.5"
34+
bytes = "1.9.0"
35+
chrono = "0.4.39"
3536
ed25519-dalek = "2.1"
3637
flume = "0.11.0"
3738
futures = "0.3.31"
38-
futures-concurrency = "7.6"
39+
futures-concurrency = "7.6.2"
3940
globset = "0.4.15"
40-
http = "1.1"
41-
hyper = "1.5"
42-
image = "0.25.4"
41+
http = "1.2.0"
42+
hyper = "1.5.2"
43+
image = "0.25.5"
44+
iroh = "0.29.0"
4345
itertools = "0.13.0"
4446
lending-stream = "1.0"
45-
libc = "0.2.159"
47+
libc = "0.2.169"
4648
mimalloc = "0.1.43"
4749
normpath = "1.3"
48-
pin-project-lite = "0.2.14"
50+
pin-project-lite = "0.2.15"
51+
quic-rpc = "0.17.3"
4952
rand = "0.9.0-alpha.2"
50-
regex = "1.11"
51-
reqwest = { version = "0.12.8", default-features = false }
53+
regex = "1.11.1"
54+
reqwest = { version = "0.12.9", default-features = false }
5255
rmp = "0.8.14"
5356
rmp-serde = "1.3"
5457
rmpv = { version = "1.3", features = ["with-serde"] }
55-
serde = "1.0"
56-
serde_json = "1.0"
58+
serde = "1.0.216"
59+
serde_json = "1.0.133"
5760
specta = "=2.0.0-rc.20"
5861
strum = "0.26"
5962
strum_macros = "0.26"
60-
tempfile = "3.13"
61-
thiserror = "1.0"
62-
tokio = "1.40"
63-
tokio-stream = "0.1.16"
64-
tokio-util = "0.7.12"
65-
tracing = "0.1.40"
66-
tracing-subscriber = "0.3.18"
63+
tempfile = "3.14.0"
64+
thiserror = "2.0.8"
65+
tokio = "1.42.0"
66+
tokio-stream = "0.1.17"
67+
tokio-util = "0.7.13"
68+
tracing = "0.1.41"
69+
tracing-subscriber = "0.3.19"
6770
tracing-test = "0.2.5"
6871
uhlc = "0.8.0" # Must follow version used by specta
6972
uuid = "1.10" # Must follow version used by specta

apps/desktop/src-tauri/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sd-desktop"
3-
version = "0.4.3"
3+
version = "0.5.0"
44

55
authors = ["Spacedrive Technology Inc <[email protected]>"]
66
default-run = "sd-desktop"
@@ -69,9 +69,9 @@ sd-desktop-linux = { path = "../crates/linux" }
6969
# WARNING: dbus must NOT be vendored, as that breaks the app on Linux,X11,Nvidia
7070
dbus = { version = "0.9.7", features = ["stdfd"] }
7171
# https://github.com/tauri-apps/tauri/blob/tauri-v2.0.0/crates/tauri/Cargo.toml#L101
72+
gtk = { version = "0.18", features = ["v3_24"] }
73+
tao = { version = "0.31.1", features = ["serde"] }
7274
webkit2gtk = { version = "=2.0.1", features = ["v2_40"] }
73-
gtk = { version = "0.18", features = ["v3_24"] }
74-
tao = { version = "0.31.1", features = ["serde"] }
7575

7676

7777
[target.'cfg(target_os = "macos")'.dependencies]

apps/desktop/src/App.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
libraryClient,
99
RspcProvider,
1010
useBridgeMutation,
11+
useLibraryMutation,
1112
useSelector
1213
} from '@sd/client';
1314
import {
@@ -61,21 +62,21 @@ declare global {
6162
}
6263

6364
// Disabling until sync is ready.
64-
// SuperTokens.init({
65-
// appInfo: {
66-
// apiDomain: AUTH_SERVER_URL,
67-
// apiBasePath: '/api/auth',
68-
// appName: 'Spacedrive Auth Service'
69-
// },
70-
// cookieHandler: getCookieHandler,
71-
// windowHandler: getWindowHandler,
72-
// recipeList: [
73-
// Session.init({ tokenTransferMethod: 'header' }),
74-
// EmailPassword.init(),
75-
// ThirdParty.init(),
76-
// Passwordless.init()
77-
// ]
78-
// });
65+
SuperTokens.init({
66+
appInfo: {
67+
apiDomain: AUTH_SERVER_URL,
68+
apiBasePath: '/api/auth',
69+
appName: 'Spacedrive Auth Service'
70+
},
71+
cookieHandler: getCookieHandler,
72+
windowHandler: getWindowHandler,
73+
recipeList: [
74+
Session.init({ tokenTransferMethod: 'header' }),
75+
EmailPassword.init()
76+
// ThirdParty.init(),
77+
// Passwordless.init()
78+
]
79+
});
7980

8081
const startupError = (window as any).__SD_ERROR__ as string | undefined;
8182

@@ -232,7 +233,7 @@ type RedirectPath = { pathname: string; search: string | undefined };
232233
function AppInner() {
233234
const [tabs, setTabs] = useState(() => [createTab()]);
234235
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
235-
const cloudBootstrap = useBridgeMutation('cloud.bootstrap');
236+
const cloudBootstrap = useLibraryMutation('cloud.bootstrap');
236237

237238
useEffect(() => {
238239
(async () => {

apps/desktop/src/commands.ts

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sd-core"
3-
version = "0.4.3"
3+
version = "0.5.0"
44

55
authors = ["Spacedrive Technology Inc <[email protected]>"]
66
description = "Virtual distributed filesystem engine that powers Spacedrive."
@@ -35,10 +35,10 @@ sd-ffmpeg = { path = "../crates/ffmpeg", optional = true }
3535
sd-file-ext = { path = "../crates/file-ext" }
3636
sd-images = { path = "../crates/images", features = ["rspc", "serde", "specta"] }
3737
sd-media-metadata = { path = "../crates/media-metadata" }
38-
sd-p2p = { path = "../crates/p2p", features = ["specta"] }
39-
sd-p2p-block = { path = "../crates/p2p/crates/block" }
40-
sd-p2p-proto = { path = "../crates/p2p/crates/proto" }
41-
sd-p2p-tunnel = { path = "../crates/p2p/crates/tunnel" }
38+
sd-old-p2p = { path = "../crates/old-p2p", features = ["specta"] }
39+
sd-old-p2p-block = { path = "../crates/old-p2p/crates/block" }
40+
sd-old-p2p-proto = { path = "../crates/old-p2p/crates/proto" }
41+
sd-old-p2p-tunnel = { path = "../crates/old-p2p/crates/tunnel" }
4242
sd-prisma = { path = "../crates/prisma" }
4343
sd-sync = { path = "../crates/sync" }
4444
sd-task-system = { path = "../crates/task-system" }

core/crates/cloud-services/Cargo.toml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ edition = "2021"
66

77
[dependencies]
88
# Core Spacedrive Sub-crates
9-
sd-core-sync = { path = "../sync" }
9+
sd-core-heavy-lifting = { path = "../heavy-lifting" }
10+
sd-core-prisma-helpers = { path = "../prisma-helpers" }
11+
sd-core-sync = { path = "../sync" }
1012

1113
# Spacedrive Sub-crates
1214
sd-actors = { path = "../../../crates/actors" }
@@ -16,13 +18,16 @@ sd-prisma = { path = "../../../crates/prisma" }
1618
sd-utils = { path = "../../../crates/utils" }
1719

1820
# Workspace dependencies
21+
anyhow = { workspace = true }
1922
async-stream = { workspace = true }
2023
base64 = { workspace = true }
2124
blake3 = { workspace = true }
2225
chrono = { workspace = true, features = ["serde"] }
2326
flume = { workspace = true }
2427
futures = { workspace = true }
2528
futures-concurrency = { workspace = true }
29+
iroh = { workspace = true, features = ["discovery-local-network"] }
30+
quic-rpc = { workspace = true, features = ["iroh-transport", "quinn-transport"] }
2631
rmp-serde = { workspace = true }
2732
rspc = { workspace = true }
2833
serde = { workspace = true, features = ["derive"] }
@@ -37,12 +42,9 @@ uuid = { workspace = true, features = ["serde"] }
3742
zeroize = { workspace = true }
3843

3944
# External dependencies
40-
anyhow = "1.0.86"
41-
dashmap = "6.1.0"
42-
iroh = { version = "0.29.0", features = ["discovery-local-network"] }
43-
paste = "=1.0.15"
44-
quic-rpc = { version = "0.17.1", features = ["iroh-transport", "quinn-transport"] }
45-
quinn = { package = "iroh-quinn", version = "0.12" }
45+
dashmap = "6.1.0"
46+
paste = "=1.0.15"
47+
quinn = { package = "iroh-quinn", version = "0.12" }
4648
# Using whatever version of reqwest that reqwest-middleware uses, just putting here to enable some features
4749
reqwest = { version = "0.12", features = ["json", "native-tls-vendored", "stream"] }
4850
reqwest-middleware = { version = "0.4", features = ["json"] }

core/crates/cloud-services/src/client.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
use crate::p2p::{NotifyUser, UserResponse};
22

3-
use sd_cloud_schema::{Client, Request, Response, ServicesALPN};
3+
use sd_cloud_schema::{Client, Service, ServicesALPN};
44

55
use std::{net::SocketAddr, sync::Arc, time::Duration};
66

77
use futures::Stream;
88
use iroh::relay::RelayUrl;
9-
use quic_rpc::{transport::quinn::QuinnConnector, RpcClient, RpcMessage};
9+
use quic_rpc::{client::QuinnConnector, RpcClient};
1010
use quinn::{crypto::rustls::QuicClientConfig, ClientConfig, Endpoint};
1111
use reqwest::{IntoUrl, Url};
1212
use reqwest_middleware::{reqwest, ClientBuilder, ClientWithMiddleware};
13+
// use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
1314
use tokio::sync::{Mutex, RwLock};
1415
use tracing::warn;
1516

1617
use super::{
1718
error::Error, key_manager::KeyManager, p2p::CloudP2P, token_refresher::TokenRefresher,
1819
};
1920

21+
pub type CloudServicesClient = Client<QuinnConnector<Service>>;
22+
2023
#[derive(Debug, Default, Clone)]
21-
enum ClientState<In: RpcMessage, Out: RpcMessage> {
24+
enum ClientState {
2225
#[default]
2326
NotConnected,
24-
Connected(Client<QuinnConnector<In, Out>>),
27+
Connected(CloudServicesClient),
2528
}
2629

2730
/// Cloud services are a optional feature that allows you to interact with the cloud services
@@ -34,7 +37,7 @@ enum ClientState<In: RpcMessage, Out: RpcMessage> {
3437
/// that core can always operate without the cloud services.
3538
#[derive(Debug)]
3639
pub struct CloudServices {
37-
client_state: Arc<RwLock<ClientState<Response, Request>>>,
40+
client_state: Arc<RwLock<ClientState>>,
3841
get_cloud_api_address: Url,
3942
http_client: ClientWithMiddleware,
4043
domain_name: String,
@@ -157,7 +160,7 @@ impl CloudServices {
157160
http_client: &ClientWithMiddleware,
158161
get_cloud_api_address: Url,
159162
domain_name: String,
160-
) -> Result<Client<QuinnConnector<Response, Request>>, Error> {
163+
) -> Result<CloudServicesClient, Error> {
161164
let cloud_api_address = http_client
162165
.get(get_cloud_api_address)
163166
.send()
@@ -256,7 +259,7 @@ impl CloudServices {
256259
.map_err(Error::FailedToCreateEndpoint)?;
257260
endpoint.set_default_client_config(client_config);
258261

259-
Ok(Client::new(RpcClient::new(QuinnConnector::new(
262+
Ok(Client::new(RpcClient::new(QuinnConnector::<Service>::new(
260263
endpoint,
261264
cloud_api_address,
262265
domain_name,
@@ -268,7 +271,7 @@ impl CloudServices {
268271
/// If the client is not connected, it will try to connect to the cloud services.
269272
/// Available routes documented in
270273
/// [`sd_cloud_schema::Service`](https://github.com/spacedriveapp/cloud-services-schema).
271-
pub async fn client(&self) -> Result<Client<QuinnConnector<Response, Request>>, Error> {
274+
pub async fn client(&self) -> Result<CloudServicesClient, Error> {
272275
if let ClientState::Connected(client) = { &*self.client_state.read().await } {
273276
return Ok(client.clone());
274277
}

core/crates/cloud-services/src/error.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,22 @@ pub enum Error {
177177
ReadNonceStreamDecryption(io::Error),
178178
#[error("Incomplete download bytes sync messages")]
179179
IncompleteDownloadBytesSyncMessages,
180+
#[error("Timed out while waiting to recive thumbnail data")]
181+
ThumbnailRequestTimeout,
180182

181183
// Temporary errors
182184
#[error("Device missing secret key for decrypting sync messages")]
183185
MissingKeyHash,
186+
#[error("Not Implemented yet")]
187+
NotImplemented,
188+
#[error("Device not found")]
189+
DeviceNotFound,
190+
#[error("Invalid CAS ID")]
191+
InvalidCasId,
192+
#[error("Internal Error")]
193+
InternalError,
194+
#[error("Remote Device Error")]
195+
RemoteDeviceError,
184196
}
185197

186198
#[derive(thiserror::Error, Debug)]

core/crates/cloud-services/src/p2p/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use sd_cloud_schema::{
88
SecretKey as IrohSecretKey,
99
};
1010
use sd_crypto::{CryptoRng, SeedableRng};
11+
use sd_prisma::prisma::file_path::cas_id;
1112

12-
use std::{sync::Arc, time::Duration};
13+
use std::{path::PathBuf, sync::Arc, time::Duration};
1314

1415
use iroh::{
1516
discovery::{
@@ -35,6 +36,12 @@ pub struct JoinedLibraryCreateArgs {
3536
pub description: Option<String>,
3637
}
3738

39+
#[derive(Debug)]
40+
pub struct RecivedGetThumbnailArgs {
41+
pub cas_id: cas_id::Type,
42+
pub error: Option<Error>,
43+
}
44+
3845
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, specta::Type)]
3946
#[serde(transparent)]
4047
#[repr(transparent)]
@@ -108,6 +115,7 @@ impl CloudP2P {
108115
dns_origin_domain: String,
109116
dns_pkarr_url: Url,
110117
relay_url: RelayUrl,
118+
data_directory: PathBuf,
111119
) -> Result<Self, Error> {
112120
let dht_discovery = DhtDiscovery::builder()
113121
.secret_key(iroh_secret_key.clone())
@@ -156,6 +164,7 @@ impl CloudP2P {
156164
cloud_services,
157165
msgs_tx.clone(),
158166
endpoint,
167+
data_directory,
159168
)
160169
.await?;
161170
let user_response_rx = cloud_services.user_response_rx.clone();
@@ -232,6 +241,28 @@ impl CloudP2P {
232241
.await
233242
.expect("Channel closed");
234243
}
244+
245+
/// Requests the binary of a thumbnail from a specific device endpoint
246+
///
247+
/// # Panics
248+
/// Will panic if the actor channel is closed, which should never happen
249+
pub async fn request_thumbnail_data(
250+
&self,
251+
device_pub_id: devices::PubId,
252+
cas_id: cas_id::Type,
253+
library_pub_id: libraries::PubId,
254+
tx: oneshot::Sender<RecivedGetThumbnailArgs>,
255+
) {
256+
self.msgs_tx
257+
.send_async(runner::Message::Request(runner::Request::GetThumbnail {
258+
device_pub_id,
259+
cas_id,
260+
library_pub_id,
261+
tx,
262+
}))
263+
.await
264+
.expect("Channel closed");
265+
}
235266
}
236267

237268
impl Drop for CloudP2P {

0 commit comments

Comments
 (0)