JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Unified stack refactor clean up

Clean up obsolete code and some warnings

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨356f714

⁨giterated-stack/src/runtime.rs⁩ - ⁨17628⁩ bytes
Raw
1 use std::{any::Any, collections::HashMap, sync::Arc};
2
3 use giterated_models::{
4 authenticated::AuthenticatedPayload,
5 error::OperationError,
6 message::GiteratedMessage,
7 object::{AnyObject, GiteratedObject, Object, ObjectRequestError},
8 object_backend::ObjectBackend,
9 operation::{AnyOperationV2, GiteratedOperation},
10 settings::{GetSetting, SetSetting, Setting},
11 value::{GetValue, GetValueV2, GiteratedObjectValue},
12 };
13 use tracing::trace;
14
15 use crate::{
16 GiteratedOperationHandler, ObjectMeta, ObjectOperationPair, ObjectValuePair, OperationMeta,
17 OperationWrapper, SettingMeta, StackOperationState, ValueMeta,
18 };
19
20 /// Temporary name for the next generation of Giterated stack
21 #[derive(Default)]
22 pub struct GiteratedRuntime {
23 operation_handlers: HashMap<ObjectOperationPair, HandlerTree>,
24 value_getters: HashMap<ObjectValuePair, OperationWrapper>,
25 setting_getters: HashMap<String, OperationWrapper>,
26 metadata: RuntimeMetadata,
27 }
28
29 impl GiteratedRuntime {
30 pub fn merge_builder<S: GiteratedRuntimeState>(
31 &mut self,
32 builder: RuntimeBuilder<S>,
33 ) -> &mut Self {
34 for (target, handler) in builder.operation_handlers {
35 let tree = self.get_or_create_tree(&target);
36
37 tree.push(handler);
38 }
39
40 for (target, handler) in builder.value_getters {
41 assert!(self.value_getters.insert(target, handler).is_none());
42 }
43
44 for (target, handler) in builder.setting_getters {
45 assert!(self.setting_getters.insert(target, handler).is_none());
46 }
47
48 self.metadata.append(builder.metadata);
49
50 self
51 }
52
53 fn get_or_create_tree(&mut self, target: &ObjectOperationPair) -> &mut HandlerTree {
54 if self.operation_handlers.contains_key(target) {
55 self.operation_handlers.get_mut(target).unwrap()
56 } else {
57 self.operation_handlers
58 .insert(target.clone(), HandlerTree::default());
59
60 self.operation_handlers.get_mut(target).unwrap()
61 }
62 }
63 }
64
65 pub struct HandlerTree {
66 elements: Vec<OperationWrapper>,
67 }
68
69 impl Default for HandlerTree {
70 fn default() -> Self {
71 Self { elements: vec![] }
72 }
73 }
74
75 impl HandlerTree {
76 pub fn push(&mut self, handler: OperationWrapper) {
77 self.elements.push(handler);
78 }
79
80 pub fn handle(
81 &self,
82 _object: &dyn Any,
83 _operation: Box<dyn Any>,
84 _operation_state: &StackOperationState,
85 ) -> Result<Box<dyn Any>, OperationError<Box<dyn Any>>> {
86 todo!()
87 }
88 }
89
90 /// Stores runtime metadata for all in-use Giterated protocol types.
91 #[derive(Default)]
92 struct RuntimeMetadata {
93 objects: HashMap<String, ObjectMeta>,
94 operations: HashMap<ObjectOperationPair, OperationMeta>,
95 values: HashMap<ObjectValuePair, ValueMeta>,
96 settings: HashMap<String, SettingMeta>,
97 }
98
99 /// Defines a type that is a valid Giterated runtime state.
100 ///
101 /// This allows for extraction of state in handlers, based on a
102 /// [`FromOperationState<S>`] impl on (what is in this case) [`Self`].
103 pub trait GiteratedRuntimeState: Send + Sync + Clone {}
104
105 impl<T: Send + Sync + Clone> GiteratedRuntimeState for T {}
106
107 pub struct RuntimeBuilder<S: GiteratedRuntimeState> {
108 operation_handlers: HashMap<ObjectOperationPair, OperationWrapper>,
109 value_getters: HashMap<ObjectValuePair, OperationWrapper>,
110 setting_getters: HashMap<String, OperationWrapper>,
111 metadata: RuntimeMetadata,
112 state: S,
113 }
114
115 impl<S: GiteratedRuntimeState + 'static> RuntimeBuilder<S> {
116 pub fn new() -> Self {
117 todo!()
118 }
119 }
120
121 impl<S: GiteratedRuntimeState + 'static> RuntimeBuilder<S> {
122 /// Insert an operation handler into the runtime builder.
123 ///
124 /// # Type Registration
125 /// Inserting the handler will automatically, if required, register the operation type of the
126 /// handler. It will **not** register the object type automatically.
127 pub fn operation<A, O, D, H>(&mut self, handler: H) -> &mut Self
128 where
129 O: GiteratedObject + 'static,
130 D: GiteratedOperation<O> + 'static,
131 H: GiteratedOperationHandler<A, O, D, S> + 'static + Clone,
132 {
133 let object_name = handler.object_name().to_string();
134 let operation_name = handler.operation_name().to_string();
135
136 let wrapped = OperationWrapper::new(handler, self.state.clone());
137
138 let pair = ObjectOperationPair {
139 object_name,
140 operation_name,
141 };
142
143 assert!(self.operation_handlers.insert(pair, wrapped).is_none());
144
145 self.metadata.register_operation::<O, D>();
146
147 self
148 }
149
150 /// Register a [`GiteratedObject`] type with the runtime.
151 ///
152 /// # Type Registration
153 /// This will register the provided object type.
154 pub fn object<O: GiteratedObject + 'static>(&mut self) -> &mut Self {
155 self.metadata.register_object::<O>();
156
157 self
158 }
159
160 /// Register a [`Setting`] type with the runtime.
161 ///
162 /// # Type Registration
163 /// This will register the provided setting type.
164 pub fn setting<T: Setting>(&mut self) -> &mut Self {
165 self.metadata.register_setting::<T>();
166
167 self
168 }
169
170 /// Register a [`GiteratedObjectValue<O>`] type with the runtime, providing
171 /// its associated handler for [`GetValue`].
172 ///
173 /// # Type Registration
174 /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified
175 /// object type. It will **not** register the object type automatically.
176 pub fn value<O, V, A, F>(&mut self, handler: F) -> &mut Self
177 where
178 O: GiteratedObject + 'static,
179 V: GiteratedObjectValue<Object = O> + 'static,
180 F: GiteratedOperationHandler<A, O, GetValue<V>, S> + Clone + 'static,
181 {
182 let object_name = handler.object_name().to_string();
183 let value_name = V::value_name().to_string();
184
185 let wrapped = OperationWrapper::new(handler, self.state.clone());
186
187 assert!(self
188 .value_getters
189 .insert(
190 ObjectValuePair {
191 object_kind: object_name,
192 value_kind: value_name
193 },
194 wrapped
195 )
196 .is_none());
197
198 self.metadata.register_value::<O, V>();
199
200 self
201 }
202
203 /// Register a handler for [`GetSetting`] for it's associated object type.
204 pub fn object_settings<O, A, F>(&mut self, handler: F) -> &mut Self
205 where
206 O: GiteratedObject + 'static,
207 F: GiteratedOperationHandler<A, O, GetSetting, S> + Clone + 'static,
208 {
209 let object_name = handler.object_name().to_string();
210
211 let wrapped = OperationWrapper::new(handler, self.state.clone());
212
213 assert!(self.setting_getters.insert(object_name, wrapped).is_none());
214
215 self
216 }
217 }
218
219 impl RuntimeMetadata {
220 fn register_object<O: GiteratedObject + 'static>(&mut self) {
221 let object_name = O::object_name().to_string();
222
223 let object_meta = ObjectMeta {
224 name: object_name.clone(),
225 from_str: Box::new(|str| Ok(Box::new(O::from_str(&str).map_err(|_| ())?))),
226 any_is_same: Box::new(|any| any.is::<O>()),
227 };
228
229 if self.objects.insert(object_name, object_meta).is_some() {
230 trace!(
231 "Registration of object {} overwrote previous registration.",
232 O::object_name()
233 );
234 } else {
235 trace!("Registration of object {}.", O::object_name())
236 }
237 }
238
239 fn register_operation<O: GiteratedObject + 'static, D: GiteratedOperation<O> + 'static>(
240 &mut self,
241 ) {
242 let object_name = O::object_name().to_string();
243 let operation_name = D::operation_name().to_string();
244
245 if self
246 .operations
247 .insert(
248 ObjectOperationPair {
249 object_name: object_name.clone(),
250 operation_name: operation_name.clone(),
251 },
252 OperationMeta {
253 name: operation_name,
254 object_kind: object_name,
255 deserialize: Box::new(|bytes| {
256 Ok(Box::new(serde_json::from_slice::<D>(bytes).unwrap())
257 as Box<dyn Any + Send + Sync>)
258 }),
259 any_is_same: Box::new(|any_box| any_box.is::<D>()),
260 serialize_success: Box::new(|any| {
261 let to_serialize = any.downcast::<D::Success>().unwrap();
262 serde_json::to_vec(&to_serialize)
263 }),
264 serialize_error: Box::new(|any| {
265 let to_serialize = any.downcast::<D::Failure>().unwrap();
266 serde_json::to_vec(&to_serialize)
267 }),
268 },
269 )
270 .is_some()
271 {
272 trace!(
273 "Registration of object operation {}<{}> overwrote previous registration.",
274 D::operation_name(),
275 O::object_name()
276 );
277 } else {
278 trace!(
279 "Registration of object operation {}<{}>.",
280 D::operation_name(),
281 O::object_name()
282 )
283 }
284 }
285
286 fn register_value<
287 O: GiteratedObject + 'static,
288 V: GiteratedObjectValue<Object = O> + 'static,
289 >(
290 &mut self,
291 ) {
292 let object_name = O::object_name().to_string();
293 let value_name = V::value_name().to_string();
294
295 if self
296 .values
297 .insert(
298 ObjectValuePair {
299 object_kind: object_name.clone(),
300 value_kind: value_name.clone(),
301 },
302 ValueMeta {
303 name: value_name,
304 deserialize: Box::new(|bytes| Ok(Box::new(serde_json::from_slice(&bytes)?))),
305 },
306 )
307 .is_some()
308 {
309 trace!(
310 "Registration of value <{}>::{} overwrote previous registration.",
311 O::object_name(),
312 V::value_name()
313 );
314 } else {
315 trace!(
316 "Registration of value <{}>::{}.",
317 O::object_name(),
318 V::value_name()
319 );
320 }
321 }
322
323 fn register_setting<S: Setting>(&mut self) {
324 let setting_name = S::name().to_string();
325
326 if self
327 .settings
328 .insert(
329 setting_name.clone(),
330 SettingMeta {
331 name: setting_name,
332 deserialize: Box::new(|bytes| Ok(Box::new(serde_json::from_slice(bytes)?))),
333 },
334 )
335 .is_some()
336 {
337 trace!(
338 "Registration of setting {} overwrote previous registration.",
339 S::name()
340 );
341 } else {
342 trace!("Registration of setting {}.", S::name());
343 }
344 }
345
346 fn append(&mut self, other: Self) {
347 self.objects.extend(other.objects);
348 self.operations.extend(other.operations);
349 self.values.extend(other.values);
350 self.settings.extend(other.settings);
351 }
352 }
353
354 #[async_trait::async_trait]
355 impl<L, O, D, S> GiteratedOperationHandler<L, O, D, S> for GiteratedRuntime
356 where
357 O: GiteratedObject + 'static,
358 D: GiteratedOperation<O> + 'static,
359 S: GiteratedRuntimeState + 'static,
360 {
361 fn operation_name(&self) -> &str {
362 D::operation_name()
363 }
364
365 fn object_name(&self) -> &str {
366 O::object_name()
367 }
368
369 async fn handle(
370 &self,
371 object: &O,
372 operation: D,
373 _state: S,
374 operation_state: &StackOperationState,
375 ) -> Result<D::Success, OperationError<D::Failure>> {
376 // Erase object and operation types.
377 let object = object as &dyn Any;
378 let operation = Box::new(operation) as Box<dyn Any>;
379
380 // We need to determine the type of the object, iterate through all known
381 // object types and check if the &dyn Any we have is the same type as the
382 // object type.
383 let object_type = {
384 let mut object_type = None;
385
386 for (object_name, object_meta) in self.metadata.objects.iter() {
387 if (object_meta.any_is_same)(object) {
388 object_type = Some(object_name.clone());
389 break;
390 }
391 }
392
393 object_type
394 }
395 .ok_or_else(|| OperationError::Unhandled)?;
396
397 // We need to hijack get_value, set_setting, and get_setting.
398 if operation.is::<GetValueV2>() {
399 todo!()
400 } else if operation.is::<GetSetting>() {
401 todo!()
402 } else if operation.is::<SetSetting>() {
403 todo!()
404 }
405
406 // Resolve the operation from the known operations table.
407 let operation_type = {
408 let mut operation_type = None;
409
410 for (target, operation_meta) in self.metadata.operations.iter() {
411 // Skip elements that we know will not match
412 if target.object_name != object_type {
413 continue;
414 }
415
416 if (operation_meta.any_is_same)(&operation) {
417 operation_type = Some(target.clone());
418 break;
419 }
420 }
421
422 operation_type
423 }
424 .ok_or_else(|| OperationError::Unhandled)?;
425
426 // Resolve the handler from our handler tree
427 let handler_tree = self
428 .operation_handlers
429 .get(&operation_type)
430 .ok_or_else(|| OperationError::Unhandled)?;
431
432 let raw_result = handler_tree.handle(object, operation, operation_state);
433
434 // Convert the dynamic result back into its concrete type
435 match raw_result {
436 Ok(result) => Ok(*result.downcast::<D::Success>().unwrap()),
437 Err(err) => Err(match err {
438 OperationError::Internal(internal) => OperationError::Internal(internal),
439 OperationError::Operation(boxed_error) => {
440 OperationError::Operation(*boxed_error.downcast::<D::Failure>().unwrap())
441 }
442 OperationError::Unhandled => OperationError::Unhandled,
443 }),
444 }
445 }
446 }
447
448 impl GiteratedRuntime {
449 /// Handles a giterated network message, returning either a raw success
450 /// payload or a serialized error payload.
451 pub async fn handle_network_message<S: GiteratedRuntimeState>(
452 &self,
453 message: AuthenticatedPayload,
454 _state: &S,
455 operation_state: &StackOperationState,
456 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
457 let message: GiteratedMessage<AnyObject, AnyOperationV2> = message.into_message_v2();
458
459 // Deserialize the object, also getting the object type's name
460 let (object_type, object) = {
461 let mut result = None;
462
463 for (object_type, object_meta) in self.metadata.objects.iter() {
464 if let Ok(object) = (object_meta.from_str)(&message.object.0) {
465 result = Some((object_type.clone(), object));
466 break;
467 }
468 }
469
470 result
471 }
472 .ok_or_else(|| OperationError::Unhandled)?;
473
474 let target = ObjectOperationPair {
475 object_name: object_type,
476 operation_name: message.operation,
477 };
478
479 // Resolve the target operations from the handlers table
480 let handler = self
481 .operation_handlers
482 .get(&target)
483 .ok_or_else(|| OperationError::Unhandled)?;
484
485 // Deserialize the operation
486 let meta = self
487 .metadata
488 .operations
489 .get(&target)
490 .ok_or_else(|| OperationError::Unhandled)?;
491
492 let operation =
493 (meta.deserialize)(&message.payload.0).map_err(|_| OperationError::Unhandled)?;
494
495 // Get the raw result of the operation, where the return values are boxed.
496 let raw_result = handler.handle(&object, operation, operation_state);
497
498 // Deserialize the raw result for the network
499 match raw_result {
500 Ok(success) => Ok((meta.serialize_success)(success)
501 .map_err(|e| OperationError::Internal(e.to_string()))?),
502 Err(err) => Err(match err {
503 OperationError::Operation(failure) => OperationError::Operation(
504 (meta.serialize_error)(failure)
505 .map_err(|e| OperationError::Internal(e.to_string()))?,
506 ),
507 OperationError::Internal(internal) => OperationError::Internal(internal),
508 OperationError::Unhandled => OperationError::Unhandled,
509 }),
510 }
511 }
512 }
513
514 use core::fmt::Debug;
515
516 #[async_trait::async_trait]
517 impl ObjectBackend<StackOperationState> for Arc<GiteratedRuntime> {
518 async fn object_operation<O, D>(
519 &self,
520 _object: O,
521 _operation: &str,
522 _payload: D,
523 _operation_state: &StackOperationState,
524 ) -> Result<D::Success, OperationError<D::Failure>>
525 where
526 O: GiteratedObject + Debug + 'static,
527 D: GiteratedOperation<O> + Debug,
528 {
529 todo!()
530 }
531
532 async fn get_object<O: GiteratedObject + Debug>(
533 &self,
534 _object_str: &str,
535 _operation_state: &StackOperationState,
536 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
537 todo!()
538 }
539 }
540