Mathias Gottschlag 5 anni fa
parent
commit
8c580eeaea

+ 94
- 0
src/client_side_sync.rs Vedi File

@@ -0,0 +1,94 @@
1
+struct ClientSideSync {
2
+    state_send: mpsc::Sender<(StateChange, oneshot::Sender<()>)>,
3
+    new_version_source: NewVersionSource,
4
+}
5
+
6
+// TODO: Parametrize the server protocol!
7
+// TODO: Can one directory be synchronized to multiple servers? Cycles are then possible!
8
+impl ClientSideSync {
9
+    // TODO: Restrict the size of the files downloaded by the synchronization client?
10
+    pub async fn new(
11
+        file_tree: Arc<Mutex<FileTree>>,
12
+        errors: mpsc::Sender<SynchronizationError>,
13
+    ) -> Result<ClientSideSync, Error> {
14
+        let new_version_source = file_tree.lock().await.new_version_source();
15
+        // Spawn the task that connects to the server as soon as unpause() is called.
16
+        let (state_send, pause_receive) = mpsc::channel(1);
17
+        tokio::spawn(async move {
18
+            let mut sync_task = ClientSideSyncTask {
19
+                file_tree,
20
+                errors,
21
+                new_version_source,
22
+            };
23
+            sync_task.task_paused(pause_receive).await;
24
+        });
25
+
26
+        Ok(ClientSideSync{
27
+            state_send,
28
+            new_version_source,
29
+        })
30
+    }
31
+
32
+    // TODO: Deduplicate this code.
33
+    pub async fn pause(&mut self) {
34
+        let (send, receive) = oneshot::channel();
35
+        self.state_send
36
+            .send((StateChange::Pause, send))
37
+            .await
38
+            .unwrap();
39
+        receive.await.unwrap();
40
+    }
41
+
42
+    pub async fn unpause(&mut self) {
43
+        let (send, receive) = oneshot::channel();
44
+        self.state_send
45
+            .send((StateChange::Unpause, send))
46
+            .await
47
+            .unwrap();
48
+        receive.await.unwrap();
49
+    }
50
+}
51
+
52
+struct ClientSideSyncTask {
53
+    file_tree: Arc<Mutex<FileTree>>,
54
+    errors: mpsc::Sender<SynchronizationError>,
55
+    new_version_source: NewVersionSource,
56
+}
57
+
58
+impl ClientSideSyncTask {
59
+    async fn task_paused(
60
+        &mut self,
61
+        mut state_receive: mpsc::Receiver<(StateChange, oneshot::Sender<()>)>,
62
+    ) {
63
+        let mut paused = true;
64
+
65
+        loop {
66
+            if paused {
67
+                // If we are paused, we only need to wait for state changes.
68
+                let (new_state, send) = state_receive.recv().await.unwrap();
69
+                match new_state {
70
+                    StateChange::Pause => paused = true,
71
+                    StateChange::Unpause => paused = false,
72
+                    StateChange::Terminate => break, // No reply, see drop().
73
+                }
74
+                send.send(()).unwrap();
75
+            } else {
76
+                // We were unpaused, initialize the file system watcher and start waiting for
77
+                // that as well.
78
+                let next_state = self.task_unpaused(&mut state_receive).await;
79
+                match next_state {
80
+                    StateChange::Pause => paused = true,
81
+                    StateChange::Unpause => paused = false,
82
+                    StateChange::Terminate => break,
83
+                }
84
+            }
85
+        }
86
+    }
87
+
88
+    async fn task_unpaused(
89
+        &mut self,
90
+        state_receive: &mut mpsc::Receiver<(StateChange, oneshot::Sender<()>)>,
91
+    ) -> StateChange {
92
+        // TODO
93
+    }
94
+}

+ 1
- 0
src/lib.rs Vedi File

@@ -3,6 +3,7 @@ use std::io;
3 3
 mod database;
4 4
 mod file_system_watcher;
5 5
 mod file_tree;
6
+pub mod network;
6 7
 
7 8
 pub use database::Database;
8 9
 pub use file_system_watcher::FileSystemWatcher;

+ 21
- 0
src/network/client.rs Vedi File

@@ -0,0 +1,21 @@
1
+use futures::Future;
2
+use serde::de::DeserializeOwned;
3
+use serde::Serialize;
4
+
5
+use std::time::Duration;
6
+
7
+trait Connection {
8
+    type Request: Serialize;
9
+    type Response: DeserializeOwned; // TODO: Better lifetime for zero-copy deserialization of large amounts of data?
10
+    type Call: RemoteCall<Output = Self::Response>;
11
+
12
+    fn call(call: Self::Request) -> Self::Call;
13
+
14
+    // TODO: Server-client events.
15
+}
16
+
17
+trait RemoteCall: Future {
18
+    // TODO
19
+
20
+    fn with_timeout(self, timeout: Duration) -> Self;
21
+}

+ 2
- 0
src/network/mod.rs Vedi File

@@ -0,0 +1,2 @@
1
+mod client;
2
+mod server;

+ 8
- 0
src/network/packet_connection.rs Vedi File

@@ -0,0 +1,8 @@
1
+use serde::de::DeserializeOwned;
2
+use serde::Serialize;
3
+
4
+trait PacketConnection {
5
+    type Payload: Serialize + DeserializeOwned;
6
+
7
+    // TODO
8
+}

+ 1
- 0
src/network/server.rs Vedi File

@@ -0,0 +1 @@
1
+

+ 12
- 0
src/online_test.rs Vedi File

@@ -0,0 +1,12 @@
1
+trait OnlineTest {
2
+    // TODO
3
+}
4
+
5
+/// Tests whether the system is online by connecting the specified address.
6
+struct GenericOnlineTest {
7
+    // TODO
8
+}
9
+
10
+impl OnlineTest for GenericOnlineTest {
11
+    // TODO
12
+}

+ 123
- 0
src/protocol.rs Vedi File

@@ -0,0 +1,123 @@
1
+/*pub trait Protocol {
2
+    fn login_password(&mut self, user: &str, password: &str) -> Result<String, Error>;
3
+    fn login_app_key(&mut self, user: &str, key: &str) -> Result<(), Error>;
4
+
5
+    fn register_interest(&mut self, path: &str) -> Result<(), Error>;
6
+    fn unregister_interest(&mut self, path: &str) -> Result<(), Error>;
7
+    fn get_file_update_stream() ->
8
+
9
+    fn list_directory(path: &str) -> Result<DirectoryListing, Error>;
10
+    fn get_file_metadata(path: &str) -> Result<FileMetadata, Error>;
11
+    // TODO
12
+}*/
13
+
14
+pub struct DirectoryListing {
15
+    own_version: u64,
16
+    entries: Vec<FileMetadata>,
17
+    // TODO
18
+}
19
+
20
+pub struct FileMetadata {
21
+    name: String,
22
+    version: u64,
23
+    size: u64,
24
+    type_: DirectoryEntryType,
25
+}
26
+
27
+pub enum DirectoryEntryType {
28
+    Directory,
29
+    File,
30
+    SymbolicLink,
31
+}
32
+
33
+pub struct Packet {
34
+    pub serial_number: u32,
35
+    pub type_: PacketContent,
36
+}
37
+
38
+pub enum PacketContent {
39
+    Keepalive,
40
+    Error(Error),
41
+    ServerInfo,
42
+    ServerInfoResponse(ServerInfoResponse,
43
+    PasswordLogin(PasswordLogin),
44
+    PasswordLoginResponse(PasswordLoginResponse),
45
+    AppKeyLogin(AppKeyLogin),
46
+    AppKeyLoginResponse(AppKeyLoginResponse),
47
+    RegisterInterest(RegisterInterest),
48
+    RegisterInterestResponse(RegisterInterestResponse),
49
+    UnregisterInterest(UnregisterInterest),
50
+    UnregisterInterestResponse(UnregisterInterestResponse),
51
+    ListDirectory(ListDirectory),
52
+    ListDirectoryResponse(ListDirectoryResponse),
53
+    GetFileMetadata(GetFileMetadata),
54
+    GetFileMetadataResponse(GetFileMetadataResponse),
55
+    GetFileContent(GetFileContent),
56
+    GetFileContentResponse(GetFileContentResponse),
57
+    StartFileUpdate,
58
+    UpdateFileContent,
59
+    FinishFileUpdate,
60
+}
61
+
62
+pub enum Error {
63
+    // TODO
64
+}
65
+
66
+pub struct ServerInfoResponse {
67
+    // TODO: Version of the protocol, type of the server (encrypted/unencrypted).
68
+}
69
+
70
+pub struct PasswordLogin {
71
+    // TODO
72
+}
73
+
74
+pub struct PasswordLoginResponse {
75
+    // TODO
76
+}
77
+
78
+pub struct AppKeyLogin {
79
+    // TODO
80
+}
81
+pub struct AppKeyLoginResponse {
82
+    // TODO
83
+}
84
+
85
+pub struct RegisterInterest {
86
+    // TODO
87
+}
88
+
89
+pub struct RegisterInterestResponse {
90
+    // TODO
91
+}
92
+
93
+pub struct UnregisterInterest {
94
+    // TODO
95
+}
96
+
97
+pub struct UnregisterInterestResponse {
98
+    // TODO
99
+}
100
+
101
+pub struct ListDirectory {
102
+    // TODO
103
+}
104
+
105
+pub struct ListDirectoryResponse {
106
+    // TODO
107
+}
108
+
109
+pub struct GetFileMetadata {
110
+    // TODO
111
+}
112
+
113
+pub struct GetFileMetadataResponse {
114
+    // TODO
115
+}
116
+
117
+pub struct GetFileContent {
118
+    // TODO
119
+}
120
+
121
+pub struct GetFileContentResponse {
122
+    // TODO
123
+}

Loading…
Annulla
Salva