The long awaited, exhalted huge networking stack change.
parent: tbd commit: 21b6a72
1 | use ; |
2 | |
3 | use ; |
4 | use |
5 | |
6 | Error, GiteratedObject, GiteratedOperation, Instance, IntoInternalError, |
7 | NetworkOperationError, OperationError, |
8 | , |
9 | AnyFailure, AnyObject, AnyOperation, AnySuccess, GiteratedStack, ObjectOperationPair, |
10 | OperationState, StackOperationState, SubstackBuilder, |
11 | ; |
12 | use ; |
13 | use TcpStream; |
14 | use ; |
15 | use ; |
16 | |
17 | use crate:: |
18 | AuthenticatedPayload, AuthenticationSourceProviders, GiteratedMessage, NetworkOperationState, |
19 | ; |
20 | |
21 | /// A Giterated substack that attempts to resolve with a remote, networked Giterated Daemon. |
22 | /// |
23 | /// # Usage |
24 | /// |
25 | /// Convert the [`NetworkedSubstack`] into a [`SubStackBuilder<NetworkedSubstack>`] and merge it with |
26 | /// a runtime. |
27 | /// |
28 | /// ``` |
29 | /// let mut runtime = GiteratedStack::default(); |
30 | /// |
31 | /// let network_substack = NetworkedSubstack::default(); |
32 | /// |
33 | /// runtime.merge_builder(network_substack.into_substack()); |
34 | /// ``` |
35 | /// |
36 | /// To handle messages that are sourced from the network, use [`NetworkedObject`] and [`NetworkedOperation`]. |
37 | /// |
38 | /// These are wrappers around the raw payloads from the network. The return payload from handling [`NetworkedOperation`] is then |
39 | /// sent back to the requester. |
40 | /// |
41 | /// ``` |
42 | /// // Start with a network payload |
43 | /// let network_payload: AuthenticatedPayload = { todo!() }; |
44 | /// |
45 | /// let networked_object = runtime.get_object::<NetworkedObject>(network_payload.object).await?; |
46 | /// let operation_name = payload.operation; |
47 | /// let networked_operation = NetworkedOperation(payload); |
48 | /// |
49 | /// // Operation state depends on the authentication in the payload, it |
50 | /// // isn't relevant here. |
51 | /// let operation_state = StackOperationState::default(); |
52 | /// |
53 | /// let result = networked_object.request(networked_operation, &operation_state); |
54 | /// |
55 | /// // `result` is Result<Vec<u8>, OperationError<Vec<u8>> which is also the type that |
56 | /// // giterated's networked protocol uses for responses, so you can send it directly. |
57 | /// ``` |
58 | /// |
59 | /// TODO: The above docs are 100% false about the network protocol type |
60 | |
61 | |
62 | pub home_uri: , |
63 | |
64 | |
65 | |
66 | |
67 | Self |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | let mut stack = new; |
74 | |
75 | stack.; |
76 | stack.operation; |
77 | |
78 | // TODO: optional |
79 | stack.dynamic_operation; |
80 | |
81 | stack |
82 | |
83 | |
84 | |
85 | let mut stack: = |
86 | ; | new
87 | |
88 | stack.; |
89 | |
90 | // TODO: optional |
91 | stack.dynamic_operation; |
92 | |
93 | stack |
94 | |
95 | |
96 | |
97 | pub async |
98 | object: NetworkedObject, |
99 | operation: NetworkedOperation, |
100 | _state: NetworkedSubstack, |
101 | OperationState | : ,
102 | stack: , |
103 | |
104 | trace!; |
105 | let mut result = None; |
106 | |
107 | for in &stack.inner.metadata.objects |
108 | if object_meta.name == object_name |
109 | continue; |
110 | |
111 | |
112 | if let Ok = |
113 | result = Some; |
114 | break; |
115 | |
116 | |
117 | |
118 | let = result.ok_or_else?; |
119 | |
120 | trace! |
121 | "Resolved object type {} for network operation {}.", |
122 | object_meta.name, |
123 | operation.name |
124 | ; |
125 | |
126 | let operation_meta = stack |
127 | .inner |
128 | .metadata |
129 | .operations |
130 | .get |
131 | object_name: &object_meta.name, |
132 | operation_name: &operation.name, |
133 | |
134 | .ok_or_else?; |
135 | |
136 | trace! |
137 | "Resolved operation {}::{} for network operation.", |
138 | object_meta.name, |
139 | operation_meta.name |
140 | ; |
141 | |
142 | info!; |
143 | let operation = |
144 | .as_internal_error_with_context |
145 | "deserializing object operation {}::{}" |
146 | object_meta.name, operation_meta.name |
147 | )?; |
148 | |
149 | trace! |
150 | "Deserialized operation {}::{} for network operation.", |
151 | object_meta.name, |
152 | operation_meta.name |
153 | ; |
154 | |
155 | let result = stack |
156 | .new_operation_func |
157 | .await; |
158 | |
159 | match result |
160 | Ok => |
161 | trace! |
162 | "Network operation {}::{} was successful", |
163 | object_meta.name, |
164 | operation_meta.name |
165 | ; |
166 | |
167 | Ok |
168 | as_internal_error_with_context | .
169 | format! |
170 | "serializing success for object operation {}::{}" |
171 | object_meta.name, operation_meta.name |
172 | ), |
173 | ?, |
174 | |
175 | |
176 | Err => |
177 | trace! |
178 | "Network operation {}::{} failed", |
179 | object_meta.name, |
180 | operation_meta.name |
181 | ; |
182 | Err |
183 | => Operation | Operation
184 | as_internal_error_with_context | .
185 | format! |
186 | "serializing error for object operation {}::{}" |
187 | object_meta.name, operation_meta.name |
188 | ), |
189 | ?, |
190 | , |
191 | => | Internal
192 | warn! |
193 | "A networked operation encountered an internal error: {:#?}", |
194 | internal |
195 | ; |
196 | |
197 | Internal |
198 | |
199 | => Unhandled, | Unhandled
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | ; |
207 | |
208 | |
209 | type Err = ; |
210 | |
211 | |
212 | Ok |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | f.write_str |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | "networked_object" |
225 | |
226 | |
227 | |
228 | todo! |
229 | |
230 | |
231 | |
232 | todo! |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | pub name: String, |
239 | pub payload: , |
240 | |
241 | |
242 | |
243 | |
244 | Self |
245 | |
246 | |
247 | |
248 | |
249 | type Success = ; |
250 | |
251 | type Failure = ; |
252 | |
253 | |
254 | "networked_operation" |
255 | |
256 | |
257 | |
258 | /// Handler which will attempt to resolve any operation that doesn't resolve locally |
259 | /// against a remote instance. |
260 | pub async |
261 | object: AnyObject, |
262 | operation: AnyOperation, |
263 | state: NetworkedSubstack, |
264 | _stack: , |
265 | |
266 | if object. |
267 | return Err; |
268 | |
269 | trace! |
270 | "Try handling object operation {}::{} with remote", |
271 | object.kind, |
272 | operation.kind .operation_name |
273 | ; |
274 | // TODO: |
275 | // Ideally we support pass-through on object types that aren't used locally. |
276 | // For now, we aren't worrying about that. |
277 | let object_meta = object.meta .clone; |
278 | |
279 | let operation_meta = operation.meta .clone; |
280 | |
281 | trace! |
282 | "Serializing with {}::{}", |
283 | operation.kind .object_name, |
284 | operation.kind .operation_name |
285 | ; |
286 | |
287 | let object_home_uri = ; |
288 | |
289 | if let Some = state.home_uri |
290 | if home_uri == object_home_uri |
291 | // This isn't a remote request, requests aren't supposed to hit this layer |
292 | // if they're not remote. |
293 | warn! |
294 | operation.kind .operation_name; |
295 | |
296 | return Err; |
297 | |
298 | |
299 | |
300 | trace! |
301 | "Handling object operation {}::{} sending payload", |
302 | object.kind, |
303 | operation.kind .operation_name |
304 | ; |
305 | |
306 | let object = NetworkedObject; |
307 | let operation = new |
308 | operation_meta.name.clone, |
309 | as_internal_error_with_context | .
310 | "try serializing object operation {}::{} for remote" |
311 | object_meta.name, operation_meta.name |
312 | )?, |
313 | ; |
314 | |
315 | // let authenticated = Authenticated::new(object, operation); |
316 | |
317 | let message = GiteratedMessage |
318 | object, |
319 | operation: operation_name .to_string, |
320 | payload: operation, |
321 | ; |
322 | |
323 | let authenticated = new; |
324 | |
325 | let mut socket: = connect_to |
326 | & from_str .unwrap, |
327 | &Some, |
328 | |
329 | .await |
330 | .as_internal_error?; |
331 | |
332 | // TODO AUTH |
333 | |
334 | let result: = |
335 | send_expect .await; |
336 | |
337 | match result |
338 | Ok => |
339 | let success = |
340 | .as_internal_error_with_context |
341 | "try deserializing object operation success {}::{} for remote" |
342 | object_meta.name, operation_meta.name |
343 | )?; |
344 | |
345 | Ok |
346 | |
347 | Err => Err |
348 | => | Operation
349 | let failure = |
350 | .as_internal_error_with_context |
351 | "try deserializing object operation failure {}::{} for remote" |
352 | object_meta.name, operation_meta.name |
353 | )?; |
354 | |
355 | Operation |
356 | |
357 | => Internal, | Internal
358 | => Unhandled, | Unhandled
359 | , |
360 | |
361 | |
362 | |
363 | type Socket = ; |
364 | |
365 | async |
366 | instance: &Instance, |
367 | |
368 | socket_addr: & , |
369 | |
370 | if let Some = socket_addr |
371 | info! |
372 | "Connecting to {}", |
373 | format! |
374 | ; |
375 | |
376 | let = |
377 | connect_async .await?; |
378 | |
379 | info!; |
380 | |
381 | Ok |
382 | else |
383 | info! |
384 | "Connecting to {}", |
385 | format! |
386 | ; |
387 | |
388 | let = |
389 | connect_async .await?; |
390 | |
391 | info!; |
392 | |
393 | Ok |
394 | |
395 | |
396 | |
397 | async |
398 | socket: &mut Socket, |
399 | message: , |
400 | |
401 | let payload = serialize .unwrap; |
402 | |
403 | socket |
404 | .send |
405 | .await |
406 | .as_internal_error?; |
407 | |
408 | while let Some = socket.next .await |
409 | let payload = match message.as_internal_error? |
410 | => payload, | Binary
411 | |
412 | _ => |
413 | continue; |
414 | |
415 | ; |
416 | |
417 | let raw_result = |
418 | |
419 | .map_err?; |
420 | |
421 | trace! |
422 | "Received response for networked operation {}::{}.", |
423 | , | object_name
424 | operation_name |
425 | ; |
426 | |
427 | return match raw_result |
428 | Ok => Ok, |
429 | Err => Err |
430 | => | Operation
431 | Operation |
432 | |
433 | => Internal, | Internal
434 | => Unhandled, | Unhandled
435 | , |
436 | ; |
437 | |
438 | |
439 | panic! |
440 | |
441 | |
442 | |
443 | |
444 | ; |
445 | |
446 | |
447 | |
448 | |
449 | ; |
450 | |
451 | |
452 | |
453 | pub source: , |
454 | pub message: , |
455 | |
456 | |
457 | |
458 | |
459 | Self |
460 | source: vec!, |
461 | message, |
462 | |
463 | |
464 | |
465 | |
466 | &mut self, |
467 | authentication: , |
468 | |
469 | self.source.push; |
470 | |
471 | |
472 | |
473 | let payload = to_vec .unwrap; |
474 | |
475 | AuthenticatedPayload |
476 | object: self.message.object.to_string, |
477 | operation: self.message.operation, |
478 | source: self |
479 | .source |
480 | .drain |
481 | .map |
482 | .flatten |
483 | ., |
484 | payload, |
485 | |
486 | |
487 | |
488 |