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

ambee/giterated

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

Beginning of `stack-next` refactor

-Refactoring the protocol stack into something similar to a runtime. -Handles merging handler builders which is placing the ground work for plugins in. - Increased metadata generation during compilation enables less ser/de during execution. - Goal is to have an O(1) time from incoming operation to calling handlers. - Decreased penalty for using the statically typed API from within your code, now avoids some allocation. # Changes - Added `GiteratedRuntime` which is to replace the current unified stack - Added `RuntimeBuilder` which does what the current `OperationHandlers` struct does, but much better. - Added `RuntimeMetadata` to store type metadata for new `Any` based internals - Refactored serde_json out of the internal operation handling

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨708dea4

⁨giterated-stack/src/handler.rs⁩ - ⁨5876⁩ bytes
Raw
1 use giterated_models::{
2 error::OperationError,
3 instance::Instance,
4 object::{
5 AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse,
6 },
7 object_backend::ObjectBackend,
8 operation::{AnyOperation, GiteratedOperation},
9 };
10 use std::{any::Any, collections::HashMap, fmt::Debug, str::FromStr, sync::Arc};
11 use tokio::sync::Mutex;
12 use tracing::warn;
13
14 use crate::{
15 state::HandlerState,
16 update::{HandleSettingUpdatedFunction, HandleValueUpdatedFunction, ValueUpdateKind},
17 OperationHandlers,
18 };
19
20 use crate::StackOperationState;
21
22 #[derive(Clone)]
23 pub struct GiteratedBackend<S: HandlerState> {
24 state: S,
25 handlers: Arc<OperationHandlers<S>>,
26 }
27
28 impl<S: HandlerState> GiteratedBackend<S> {
29 pub fn new(state: S, handlers: OperationHandlers<S>) -> Self {
30 Self {
31 state,
32 handlers: Arc::new(handlers),
33 }
34 }
35
36 pub fn state(&self) -> &S {
37 &self.state
38 }
39 }
40
41 #[async_trait::async_trait]
42 impl<S: HandlerState> ObjectBackend<StackOperationState> for GiteratedBackend<S> {
43 async fn object_operation<O, D>(
44 &self,
45 object: O,
46 operation: &str,
47 payload: D,
48 operation_state: &StackOperationState,
49 ) -> Result<D::Success, OperationError<D::Failure>>
50 where
51 O: GiteratedObject + Debug + 'static,
52 D: GiteratedOperation<O> + Debug,
53 {
54 let serialized =
55 serde_json::to_value(payload).map_err(|e| OperationError::Internal(e.to_string()))?;
56 let object = (Box::new(object) as Box<dyn Any + Send + Sync>)
57 .downcast::<O>()
58 .unwrap();
59
60 if operation == ObjectRequest::operation_name() {
61 // We're doing an object request
62 let raw_result = self
63 .handlers
64 .resolve_object(
65 *(Box::new(object) as Box<dyn Any + Send + Sync>)
66 .downcast()
67 .unwrap(),
68 serde_json::from_value(serialized).unwrap(),
69 self.state.clone(),
70 &operation_state,
71 )
72 .await;
73
74 return match raw_result {
75 Ok(result) => Ok(serde_json::from_slice(&result)
76 .map_err(|e| OperationError::Internal(e.to_string()))?),
77 Err(err) => match err {
78 OperationError::Internal(internal) => {
79 warn!(
80 "Internal Error: {:?}",
81 OperationError::<()>::Internal(internal.clone())
82 );
83
84 Err(OperationError::Internal(internal))
85 }
86 OperationError::Unhandled => Err(OperationError::Unhandled),
87 OperationError::Operation(err) => Err(OperationError::Operation(
88 serde_json::from_slice(&err)
89 .map_err(|e| OperationError::Internal(e.to_string()))?,
90 )),
91 },
92 };
93 }
94
95 let raw_result = self
96 .handlers
97 .handle(
98 &*object,
99 operation,
100 AnyOperation(serialized),
101 self.state.clone(),
102 &operation_state,
103 )
104 .await;
105
106 match raw_result {
107 Ok(result) => Ok(serde_json::from_slice(&result)
108 .map_err(|e| OperationError::Internal(e.to_string()))?),
109 Err(err) => match err {
110 OperationError::Internal(internal) => {
111 warn!(
112 "Internal Error: {:?}",
113 OperationError::<()>::Internal(internal.clone())
114 );
115
116 Err(OperationError::Internal(internal))
117 }
118 OperationError::Unhandled => Err(OperationError::Unhandled),
119 OperationError::Operation(err) => Err(OperationError::Operation(
120 serde_json::from_slice(&err)
121 .map_err(|e| OperationError::Internal(e.to_string()))?,
122 )),
123 },
124 }
125 }
126
127 async fn get_object<O: GiteratedObject + Debug>(
128 &self,
129 object_str: &str,
130 operation_state: &StackOperationState,
131 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
132 let raw_result = self
133 .handlers
134 .resolve_object(
135 Instance::from_str("giterated.dev").unwrap(),
136 ObjectRequest(object_str.to_string()),
137 self.state.clone(),
138 operation_state,
139 )
140 .await;
141
142 let object: ObjectResponse = match raw_result {
143 Ok(result) => Ok(serde_json::from_slice(&result)
144 .map_err(|e| OperationError::Internal(e.to_string()))?),
145 Err(err) => match err {
146 OperationError::Internal(internal) => {
147 warn!(
148 "Internal Error: {:?}",
149 OperationError::<()>::Internal(internal.clone())
150 );
151
152 Err(OperationError::Internal(internal))
153 }
154 OperationError::Unhandled => Err(OperationError::Unhandled),
155 OperationError::Operation(err) => Err(OperationError::Operation(
156 serde_json::from_slice(&err)
157 .map_err(|e| OperationError::Internal(e.to_string()))?,
158 )),
159 },
160 }?;
161
162 unsafe {
163 Ok(Object::new_unchecked(
164 O::from_str(&object.0)
165 .map_err(|_| OperationError::Internal("deserialize failure".to_string()))?,
166 self.clone(),
167 ))
168 }
169 }
170 }
171