`giterated_cache` initial implementation
# Giterated Stack - Added the ability for dynamic substack handlers to exist for operations relevant to caching. - Added type metadata to the dynamic types. # Giterated Cache - Created - Implemented caching and fetching from cache. Hell fucking yes!!!! It works so good. Are you snooping in the commit logs because you're curious about the history of giterated? Cool that it got so big... tell me I say hi :)
parent: tbd commit: 86afeef
Showing 12 changed files with 617 insertions and 499 deletions
Cargo.lock
@@ -844,6 +844,7 @@ dependencies = [ | ||
844 | 844 | "futures-util", |
845 | 845 | "git2", |
846 | 846 | "giterated-api", |
847 | "giterated-cache", | |
847 | 848 | "giterated-models", |
848 | 849 | "giterated-stack", |
849 | 850 | "jsonwebtoken", |
giterated-cache/src/cache_get.rs
@@ -14,3 +14,41 @@ | ||
14 | 14 | // ) -> Result<Value, OperationError<anyhow::Error>> { |
15 | 15 | // todo!() |
16 | 16 | // } |
17 | ||
18 | use std::sync::Arc; | |
19 | ||
20 | use giterated_models::error::OperationError; | |
21 | use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState}; | |
22 | use tracing::trace; | |
23 | ||
24 | use crate::{CacheKey, CacheSubstack}; | |
25 | ||
26 | pub async fn get_cached( | |
27 | object: AnyObject, | |
28 | value_kind: String, | |
29 | cache: CacheSubstack, | |
30 | _operation_state: StackOperationState, | |
31 | stack: Arc<GiteratedStack>, | |
32 | ) -> Result<AnyValue, OperationError<anyhow::Error>> { | |
33 | let object_meta = stack | |
34 | .metadata | |
35 | .objects | |
36 | .get(object.kind()) | |
37 | .ok_or_else(|| OperationError::Unhandled)?; | |
38 | let object_str = (object_meta.to_str)(object.clone()); | |
39 | let cache_key = CacheKey { | |
40 | object: object_str, | |
41 | value_name: value_kind.clone(), | |
42 | }; | |
43 | ||
44 | trace!("Check cache for {}::{}", object.kind(), value_kind); | |
45 | ||
46 | if let Some(cached_value) = cache.cache.get(&cache_key).await { | |
47 | trace!("Found cached for {}::{}", object.kind(), value_kind); | |
48 | ||
49 | Ok(cached_value.clone()) | |
50 | } else { | |
51 | trace!("Nothing cached for {}::{}", object.kind(), value_kind); | |
52 | Err(OperationError::Unhandled) | |
53 | } | |
54 | } |
giterated-cache/src/cache_update.rs
@@ -1,348 +1,42 @@ | ||
1 | // use std::{any::Any, pin::Pin, process::Output, sync::Arc}; | |
2 | ||
3 | // use futures_util::{future::LocalBoxFuture, Future, FutureExt}; | |
4 | // use giterated_models::{ | |
5 | // error::{ExtractorError, OperationError, RepositoryError}, | |
6 | // object::GiteratedObject, | |
7 | // operation::GiteratedOperation, | |
8 | // repository::{Repository, RepositoryBranch, RepositoryBranchesRequest}, | |
9 | // settings::SetSetting, | |
10 | // user::{DisplayName, User}, | |
11 | // value::{GetValue, GiteratedObjectValue}, | |
12 | // }; | |
13 | // use giterated_stack::{ | |
14 | // AuthorizedUser, FromOperationState, GiteratedStack, MissingValue, StackOperationState, | |
15 | // }; | |
16 | ||
17 | // use crate::CacheSubstack; | |
18 | ||
19 | // async fn value_update( | |
20 | // object: AnyObject<'_>, | |
21 | // value: AnyValue<'_>, | |
22 | // cache: CacheSubstack, | |
23 | // stack: Arc<GiteratedStack>, | |
24 | // ) -> Result<(), anyhow::Error> { | |
25 | // todo!() | |
26 | // } | |
27 | ||
28 | // pub struct AnyObject<'o>(&'o (dyn Any + Send + Sync)); | |
29 | ||
30 | // pub struct AnyValue<'v>(&'v (dyn Any + Send + Sync)); | |
31 | ||
32 | // #[async_trait::async_trait(?Send)] | |
33 | // pub trait GiteratedHandler<RequiredParameters, AdditionalParameters, State, OperationState, Output> | |
34 | // { | |
35 | // async fn handle( | |
36 | // &self, | |
37 | // parameters: RequiredParameters, | |
38 | // additional_parameters: AdditionalParameters, | |
39 | // state: Arc<State>, | |
40 | // operation_state: &OperationState, | |
41 | // ) -> Output; | |
42 | // } | |
43 | ||
44 | // #[async_trait::async_trait(?Send)] | |
45 | // impl<R1, S, O, Output, F, Fut> GiteratedHandler<(R1,), (), S, O, Output> for F | |
46 | // where | |
47 | // F: FnMut(R1, S, &O) -> Fut, | |
48 | // Fut: Future<Output = Output>, | |
49 | // S: 'static, | |
50 | // R1: 'static, | |
51 | // { | |
52 | // async fn handle( | |
53 | // &self, | |
54 | // parameters: (R1,), | |
55 | // additional_parameters: (), | |
56 | // state: Arc<S>, | |
57 | // operation_state: &O, | |
58 | // ) -> Output { | |
59 | // todo!() | |
60 | // } | |
61 | // } | |
62 | ||
63 | // #[async_trait::async_trait(?Send)] | |
64 | // impl<R1, A1, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1,), S, O, Output> for F | |
65 | // where | |
66 | // F: FnMut(R1, S, &O, A1) -> Fut, | |
67 | // Fut: Future<Output = Output>, | |
68 | // S: 'static, | |
69 | // R1: 'static, | |
70 | // A1: 'static + HandlerResolvable<(R1,), O, A1>, | |
71 | // { | |
72 | // async fn handle( | |
73 | // &self, | |
74 | // parameters: (R1,), | |
75 | // additional_parameters: (A1,), | |
76 | // state: Arc<S>, | |
77 | // operation_state: &O, | |
78 | // ) -> Output { | |
79 | // todo!() | |
80 | // } | |
81 | // } | |
82 | ||
83 | // #[async_trait::async_trait(?Send)] | |
84 | // impl<R1, A1, A2, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1, A2), S, O, Output> for F | |
85 | // where | |
86 | // F: FnMut(R1, S, &O, A1, A2) -> Fut, | |
87 | // Fut: Future<Output = Output>, | |
88 | // S: 'static, | |
89 | // R1: 'static, | |
90 | // A1: 'static + HandlerResolvable<(R1,), O, A1>, | |
91 | // A2: 'static + HandlerResolvable<(R1,), O, A2>, | |
92 | // { | |
93 | // async fn handle( | |
94 | // &self, | |
95 | // parameters: (R1,), | |
96 | // additional_parameters: (A1, A2), | |
97 | // state: Arc<S>, | |
98 | // operation_state: &O, | |
99 | // ) -> Output { | |
100 | // todo!() | |
101 | // } | |
102 | // } | |
103 | ||
104 | // #[async_trait::async_trait(?Send)] | |
105 | // impl<R1, A1, A2, A3, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1, A2, A3), S, O, Output> for F | |
106 | // where | |
107 | // F: FnMut(R1, S, &O, A1, A2, A3) -> Fut, | |
108 | // Fut: Future<Output = Output>, | |
109 | // S: 'static, | |
110 | // R1: 'static, | |
111 | // A1: 'static + HandlerResolvable<(R1,), O, A1>, | |
112 | // A2: 'static + HandlerResolvable<(R1,), O, A2>, | |
113 | // A3: 'static + HandlerResolvable<(R1,), O, A3>, | |
114 | // { | |
115 | // async fn handle( | |
116 | // &self, | |
117 | // parameters: (R1,), | |
118 | // additional_parameters: (A1, A2, A3), | |
119 | // state: Arc<S>, | |
120 | // operation_state: &O, | |
121 | // ) -> Output { | |
122 | // todo!() | |
123 | // } | |
124 | // } | |
125 | ||
126 | // #[async_trait::async_trait(?Send)] | |
127 | // impl<R1, R2, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (), S, O, Output> for F | |
128 | // where | |
129 | // F: FnMut(R1, R2, S, &O) -> Fut, | |
130 | // Fut: Future<Output = Output>, | |
131 | // S: 'static, | |
132 | // R1: 'static, | |
133 | // R2: 'static, | |
134 | // { | |
135 | // async fn handle( | |
136 | // &self, | |
137 | // parameters: (R1, R2), | |
138 | // additional_parameters: (), | |
139 | // state: Arc<S>, | |
140 | // operation_state: &O, | |
141 | // ) -> Output { | |
142 | // todo!() | |
143 | // } | |
144 | // } | |
145 | ||
146 | // #[async_trait::async_trait(?Send)] | |
147 | // impl<R1, R2, A1, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (A1,), S, O, Output> for F | |
148 | // where | |
149 | // F: FnMut(R1, R2, S, &O, A1) -> Fut, | |
150 | // Fut: Future<Output = Output>, | |
151 | // S: 'static, | |
152 | // R1: 'static, | |
153 | // R2: 'static, | |
154 | // A1: 'static + HandlerResolvable<(R1, R2), O, A1>, | |
155 | // { | |
156 | // async fn handle( | |
157 | // &self, | |
158 | // parameters: (R1, R2), | |
159 | // additional_parameters: (A1,), | |
160 | // state: Arc<S>, | |
161 | // operation_state: &O, | |
162 | // ) -> Output { | |
163 | // todo!() | |
164 | // } | |
165 | // } | |
166 | ||
167 | // #[async_trait::async_trait(?Send)] | |
168 | // impl<R1, R2, A1, A2, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (A1, A2), S, O, Output> for F | |
169 | // where | |
170 | // F: FnMut(R1, R2, S, &O, A1, A2) -> Fut, | |
171 | // Fut: Future<Output = Output>, | |
172 | // S: 'static, | |
173 | // R1: 'static, | |
174 | // R2: 'static, | |
175 | // A1: 'static + HandlerResolvable<(R1, R2), O, A1>, | |
176 | // A2: 'static + HandlerResolvable<(R1, R2), O, A2>, | |
177 | // { | |
178 | // async fn handle( | |
179 | // &self, | |
180 | // parameters: (R1, R2), | |
181 | // additional_parameters: (A1, A2), | |
182 | // state: Arc<S>, | |
183 | // operation_state: &O, | |
184 | // ) -> Output { | |
185 | // todo!() | |
186 | // } | |
187 | // } | |
188 | ||
189 | // #[async_trait::async_trait(?Send)] | |
190 | // impl<R1, R2, A1, A2, A3, S, O, Output, F, Fut> | |
191 | // GiteratedHandler<(R1, R2), (A1, A2, A3), S, O, Output> for F | |
192 | // where | |
193 | // F: FnMut(R1, R2, S, &O, A1, A2, A3) -> Fut, | |
194 | // Fut: Future<Output = Output>, | |
195 | // S: 'static, | |
196 | // R1: 'static, | |
197 | // R2: 'static, | |
198 | // A1: 'static + HandlerResolvable<(R1, R2), O, A1>, | |
199 | // A2: 'static + HandlerResolvable<(R1, R2), O, A2>, | |
200 | // A3: 'static + HandlerResolvable<(R1, R2), O, A3>, | |
201 | // { | |
202 | // async fn handle( | |
203 | // &self, | |
204 | // parameters: (R1, R2), | |
205 | // additional_parameters: (A1, A2, A3), | |
206 | // state: Arc<S>, | |
207 | // operation_state: &O, | |
208 | // ) -> Output { | |
209 | // todo!() | |
210 | // } | |
211 | // } | |
212 | ||
213 | // #[async_trait::async_trait(?Send)] | |
214 | // impl<R1, R2, R3, S, O, Output, F, Fut> GiteratedHandler<(R1, R2, R3), (), S, O, Output> for F | |
215 | // where | |
216 | // F: FnMut(R1, R2, R3, S, &O) -> Fut, | |
217 | // Fut: Future<Output = Output>, | |
218 | // S: 'static, | |
219 | // R1: 'static, | |
220 | // R2: 'static, | |
221 | // R3: 'static, | |
222 | // { | |
223 | // async fn handle( | |
224 | // &self, | |
225 | // parameters: (R1, R2, R3), | |
226 | // additional_parameters: (), | |
227 | // state: Arc<S>, | |
228 | // operation_state: &O, | |
229 | // ) -> Output { | |
230 | // todo!() | |
231 | // } | |
232 | // } | |
233 | ||
234 | // fn test_fn<O, A, S, V, F>(handler: F) | |
235 | // where | |
236 | // F: GiteratedHandler<(O, V), A, S, StackOperationState, Result<(), anyhow::Error>>, | |
237 | // O: GiteratedObject, | |
238 | // V: GiteratedObjectValue<Object = O>, | |
239 | // { | |
240 | // } | |
241 | ||
242 | // fn other_fn() { | |
243 | // let a = String::from("a"); | |
244 | // let test = move |object: User, | |
245 | // value: GetValue, | |
246 | // state: (), | |
247 | // operation_state: &StackOperationState, | |
248 | // authorized_user: AuthorizedUser| { async move { () } }; | |
249 | ||
250 | // let wrapper = HandlerWrapper::<(User, GetValue), _>::new((), test); | |
251 | // } | |
252 | ||
253 | // pub struct HandlerWrapper<P, O> { | |
254 | // func: Box<dyn Fn(P, StackOperationState) -> LocalBoxFuture<'static, O>>, | |
255 | // state: Arc<dyn Any + Send + Sync>, | |
256 | // } | |
257 | ||
258 | // impl<P, O> HandlerWrapper<P, O> { | |
259 | // pub fn new<S, F, A>(state: S, handler: F) -> Self | |
260 | // where | |
261 | // F: GiteratedHandler<P, A, S, StackOperationState, O>, | |
262 | // S: Send + Sync + 'static, | |
263 | // A: HandlerResolvableGroup<P>, | |
264 | // { | |
265 | // let state = Arc::new(state); | |
266 | ||
267 | // let func = |required: P, operation_state: StackOperationState| { | |
268 | // // async move { handler.handle(required, (), state, &operation_state) }.boxed_local() | |
269 | // todo!() | |
270 | // }; | |
271 | ||
272 | // Self { | |
273 | // func: Box::new(func), | |
274 | // state, | |
275 | // } | |
276 | // } | |
277 | // } | |
278 | ||
279 | // #[async_trait::async_trait(?Send)] | |
280 | // pub trait HandlerResolvable<RequiredParameters, OperationState, Output> { | |
281 | // async fn from_handler_state( | |
282 | // required_parameters: &RequiredParameters, | |
283 | // operation_state: &OperationState, | |
284 | // ) -> Output; | |
285 | // } | |
286 | ||
287 | // #[async_trait::async_trait(?Send)] | |
288 | // impl HandlerResolvable<(User, GetValue), StackOperationState, Self> for Arc<GiteratedStack> { | |
289 | // async fn from_handler_state( | |
290 | // required_parameters: &(User, GetValue), | |
291 | // operation_state: &StackOperationState, | |
292 | // ) -> Self { | |
293 | // todo!() | |
294 | // } | |
295 | // } | |
296 | ||
297 | // // #[async_trait::async_trait(?Send)] | |
298 | // // impl<O, D, T> HandlerResolvable<(O, D), StackOperationState, T> for T | |
299 | // // where | |
300 | // // O: GiteratedObject, | |
301 | // // D: GiteratedOperation<O>, | |
302 | // // T: FromOperationState<O, D>, | |
303 | // // { | |
304 | // // async fn from_handler_state( | |
305 | // // required_parameters: &(O, D), | |
306 | // // operation_state: &StackOperationState, | |
307 | // // ) -> T { | |
308 | // // todo!() | |
309 | // // } | |
310 | // // } | |
311 | ||
312 | // #[async_trait::async_trait(?Send)] | |
313 | // pub trait HandlerResolvableGroup<RequiredParameters> { | |
314 | // async fn group_from_handler_state( | |
315 | // required_parameters: &RequiredParameters, | |
316 | // operation_state: &StackOperationState, | |
317 | // ) -> Self; | |
318 | // } | |
319 | ||
320 | // #[async_trait::async_trait(?Send)] | |
321 | // impl<RequiredParameters, A1> HandlerResolvableGroup<RequiredParameters> for (A1,) | |
322 | // where | |
323 | // A1: HandlerResolvable<RequiredParameters, StackOperationState, A1>, | |
324 | // { | |
325 | // async fn group_from_handler_state( | |
326 | // required_parameters: &RequiredParameters, | |
327 | // operation_state: &StackOperationState, | |
328 | // ) -> (A1,) { | |
329 | // (A1::from_handler_state(required_parameters, operation_state).await,) | |
330 | // } | |
331 | // } | |
332 | ||
333 | // #[async_trait::async_trait(?Send)] | |
334 | // impl<RequiredParameters, A1, A2> HandlerResolvableGroup<RequiredParameters> for (A1, A2) | |
335 | // where | |
336 | // A1: HandlerResolvable<RequiredParameters, StackOperationState, A1>, | |
337 | // A2: HandlerResolvable<RequiredParameters, StackOperationState, A2>, | |
338 | // { | |
339 | // async fn group_from_handler_state( | |
340 | // required_parameters: &RequiredParameters, | |
341 | // operation_state: &StackOperationState, | |
342 | // ) -> (A1, A2) { | |
343 | // ( | |
344 | // A1::from_handler_state(required_parameters, operation_state).await, | |
345 | // A2::from_handler_state(required_parameters, operation_state).await, | |
346 | // ) | |
347 | // } | |
348 | // } | |
1 | use std::sync::Arc; | |
2 | ||
3 | use giterated_models::error::OperationError; | |
4 | use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState}; | |
5 | use tracing::trace; | |
6 | ||
7 | use crate::{CacheKey, CacheSubstack}; | |
8 | ||
9 | pub async fn cache_updated( | |
10 | object: AnyObject, | |
11 | value: AnyValue, | |
12 | state: CacheSubstack, | |
13 | _operation_state: StackOperationState, | |
14 | stack: Arc<GiteratedStack>, | |
15 | ) -> Result<(), OperationError<anyhow::Error>> { | |
16 | let object_meta = stack | |
17 | .metadata | |
18 | .objects | |
19 | .get(object.kind()) | |
20 | .ok_or_else(|| OperationError::Unhandled)?; | |
21 | let object_str = (object_meta.to_str)(object.clone()); | |
22 | let cache_key = CacheKey { | |
23 | object: object_str, | |
24 | value_name: value.kind().value_kind.to_string(), | |
25 | }; | |
26 | ||
27 | let value_kind = value.kind().value_kind; | |
28 | trace!( | |
29 | "Beginning cache update for {}::{}", | |
30 | object.kind(), | |
31 | value_kind | |
32 | ); | |
33 | ||
34 | state.cache.insert(cache_key, value).await; | |
35 | ||
36 | trace!( | |
37 | "Completed cache update for {}::{}", | |
38 | object.kind(), | |
39 | value_kind | |
40 | ); | |
41 | Ok(()) | |
42 | } |
giterated-cache/src/lib.rs
@@ -1,25 +1,42 @@ | ||
1 | // pub mod cache_get; | |
2 | // pub mod cache_update; | |
1 | use cache_get::get_cached; | |
2 | use giterated_stack::{AnyValue, SubstackBuilder}; | |
3 | use moka::future::Cache; | |
4 | ||
5 | use crate::cache_update::cache_updated; | |
6 | ||
7 | pub mod cache_get; | |
8 | pub mod cache_update; | |
3 | 9 | |
4 | 10 | // use giterated_stack::{ObjectValuePair, SubstackBuilder}; |
5 | 11 | // use moka::future::Cache; |
6 | 12 | // use serde_json::Value; |
7 | 13 | |
8 | // #[derive(Clone)] | |
9 | // pub struct CacheSubstack { | |
10 | // cache: Cache<ObjectValuePair, Value>, | |
11 | // } | |
12 | ||
13 | // impl Default for CacheSubstack { | |
14 | // fn default() -> Self { | |
15 | // Self { | |
16 | // cache: Cache::new(20_000), | |
17 | // } | |
18 | // } | |
19 | // } | |
20 | ||
21 | // impl CacheSubstack { | |
22 | // pub fn into_substack(self) -> SubstackBuilder<Self> { | |
23 | // todo!() | |
24 | // } | |
25 | // } | |
14 | #[derive(Hash, PartialEq, Eq)] | |
15 | pub struct CacheKey { | |
16 | object: String, | |
17 | value_name: String, | |
18 | } | |
19 | ||
20 | #[derive(Clone)] | |
21 | pub struct CacheSubstack { | |
22 | cache: Cache<CacheKey, AnyValue>, | |
23 | } | |
24 | ||
25 | impl Default for CacheSubstack { | |
26 | fn default() -> Self { | |
27 | Self { | |
28 | cache: Cache::new(20_000), | |
29 | } | |
30 | } | |
31 | } | |
32 | ||
33 | impl CacheSubstack { | |
34 | pub fn into_substack(self) -> SubstackBuilder<Self> { | |
35 | let mut stack = SubstackBuilder::new(self); | |
36 | ||
37 | stack.value_change(cache_updated); | |
38 | stack.dynamic_value(get_cached); | |
39 | ||
40 | stack | |
41 | } | |
42 | } |
giterated-daemon/Cargo.toml
@@ -32,6 +32,7 @@ semver = {version = "1.0", features = ["serde"]} | ||
32 | 32 | giterated-models = { path = "../giterated-models" } |
33 | 33 | giterated-api = { path = "../../giterated-api" } |
34 | 34 | giterated-stack = { path = "../giterated-stack" } |
35 | giterated-cache = { path = "../giterated-cache" } | |
35 | 36 | deadpool = "0.9" |
36 | 37 | bincode = "1.3" |
37 | 38 | tokio-util = {version = "0.7", features = ["rt"]} |
giterated-daemon/src/database_backend/mod.rs
@@ -25,7 +25,7 @@ use self::handler::{ | ||
25 | 25 | instance_registration_request, repository_commit_before, repository_commit_by_id, |
26 | 26 | repository_diff, repository_diff_patch, repository_file_from_id, repository_file_from_path, |
27 | 27 | repository_get_branches, repository_get_statistics, repository_info, |
28 | repository_last_commit_of_file, repository_latest_commit, user_get_repositories, | |
28 | repository_last_commit_of_file, user_get_repositories, | |
29 | 29 | }; |
30 | 30 | |
31 | 31 | /// A backend implementation which attempts to resolve data from the instance's database. |
@@ -75,7 +75,7 @@ impl DatabaseBackend { | ||
75 | 75 | .value_setting::<Repository, Visibility>() |
76 | 76 | .value_setting::<Repository, DefaultBranch>(); |
77 | 77 | |
78 | builder.value(repository_latest_commit); | |
78 | // builder.value(repository_latest_commit); | |
79 | 79 | |
80 | 80 | builder |
81 | 81 | .operation(user_get_repositories) |
@@ -116,13 +116,13 @@ impl MetadataProvider for DatabaseBackend { | ||
116 | 116 | setting: AnySetting, |
117 | 117 | setting_meta: &SettingMeta, |
118 | 118 | ) -> Result<(), anyhow::Error> { |
119 | if let Some(repository) = object.0.downcast_ref::<Repository>() { | |
119 | if let Some(repository) = object.downcast_ref::<Repository>() { | |
120 | 120 | sqlx::query!("INSERT INTO repository_settings VALUES ($1, $2, $3) ON CONFLICT (repository, name) DO UPDATE SET value = $3", |
121 | 121 | repository.to_string(), setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?) |
122 | 122 | .execute(&self.pool).await?; |
123 | 123 | |
124 | 124 | Ok(()) |
125 | } else if let Some(user) = object.0.downcast_ref::<User>() { | |
125 | } else if let Some(user) = object.downcast_ref::<User>() { | |
126 | 126 | sqlx::query!("INSERT INTO user_settings VALUES ($1, $2, $3) ON CONFLICT (username, name) DO UPDATE SET value = $3", |
127 | 127 | user.username, setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?) |
128 | 128 | .execute(&self.pool).await?; |
@@ -139,7 +139,7 @@ impl MetadataProvider for DatabaseBackend { | ||
139 | 139 | _object_meta: &ObjectMeta, |
140 | 140 | setting_meta: &SettingMeta, |
141 | 141 | ) -> Result<Value, anyhow::Error> { |
142 | if let Some(repository) = object.0.downcast_ref::<Repository>() { | |
142 | if let Some(repository) = object.downcast_ref::<Repository>() { | |
143 | 143 | let row = sqlx::query_as!( |
144 | 144 | RepositorySettingRow, |
145 | 145 | "SELECT * FROM repository_settings WHERE repository = $1 AND name = $2", |
@@ -153,7 +153,7 @@ impl MetadataProvider for DatabaseBackend { | ||
153 | 153 | serde_json::from_str(&row.value).context("deserializing setting from database")?; |
154 | 154 | |
155 | 155 | Ok(setting) |
156 | } else if let Some(user) = object.0.downcast_ref::<User>() { | |
156 | } else if let Some(user) = object.downcast_ref::<User>() { | |
157 | 157 | info!("User for {}", setting_meta.name); |
158 | 158 | let row = sqlx::query_as!( |
159 | 159 | UserSettingRow, |
giterated-daemon/src/main.rs
@@ -1,5 +1,6 @@ | ||
1 | 1 | use anyhow::Error; |
2 | 2 | use connection::{Connections, RawConnection}; |
3 | use giterated_cache::CacheSubstack; | |
3 | 4 | use giterated_daemon::{ |
4 | 5 | authentication::AuthenticationTokenGranter, |
5 | 6 | backend::{ |
@@ -100,6 +101,9 @@ async fn main() -> Result<(), Error> { | ||
100 | 101 | let database_backend = database_backend.into_substack(); |
101 | 102 | runtime.merge_builder(database_backend); |
102 | 103 | |
104 | let cache_backend = CacheSubstack::default(); | |
105 | runtime.merge_builder(cache_backend.into_substack()); | |
106 | ||
103 | 107 | let runtime = Arc::new(runtime); |
104 | 108 | |
105 | 109 | stack_cell |
giterated-models/src/settings/operations.rs
@@ -42,5 +42,5 @@ impl<O: GiteratedObject> GiteratedOperation<O> for SetSetting { | ||
42 | 42 | #[derive(Error, Debug, Serialize, Deserialize, Clone)] |
43 | 43 | pub enum SetSettingError { |
44 | 44 | #[error("Invalid setting `{0}` on object `{0}`")] |
45 | InvalidSetting(String, String) | |
45 | InvalidSetting(String, String), | |
46 | 46 | } |
giterated-stack/src/lib.rs
@@ -29,7 +29,7 @@ use giterated_models::{ | ||
29 | 29 | value::{GetValue, GiteratedObjectValue}, |
30 | 30 | }; |
31 | 31 | |
32 | #[derive(Clone, Debug, Hash, Eq, PartialEq)] | |
32 | #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] | |
33 | 33 | pub struct ObjectOperationPair<'a> { |
34 | 34 | pub object_name: &'a str, |
35 | 35 | pub operation_name: &'a str, |
@@ -45,7 +45,7 @@ impl ObjectOperationPair<'static> { | ||
45 | 45 | } |
46 | 46 | } |
47 | 47 | |
48 | #[derive(Clone, Debug, Hash, Eq, PartialEq)] | |
48 | #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] | |
49 | 49 | pub struct ObjectValuePair<'a> { |
50 | 50 | pub object_kind: &'a str, |
51 | 51 | pub value_kind: &'a str, |
@@ -60,7 +60,7 @@ impl ObjectValuePair<'static> { | ||
60 | 60 | } |
61 | 61 | } |
62 | 62 | |
63 | #[derive(Clone, Debug, Hash, Eq, PartialEq)] | |
63 | #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] | |
64 | 64 | pub struct ObjectSettingPair<'a> { |
65 | 65 | pub object_kind: &'a str, |
66 | 66 | pub setting_name: &'a str, |
@@ -452,19 +452,213 @@ where | ||
452 | 452 | } |
453 | 453 | |
454 | 454 | #[derive(Clone)] |
455 | pub struct AnyObject(pub Arc<dyn Any + Send + Sync>); | |
455 | pub struct AnyObject { | |
456 | inner: Arc<dyn Any + Send + Sync>, | |
457 | kind: &'static str, | |
458 | } | |
459 | ||
460 | impl AnyObject { | |
461 | pub fn new<O: GiteratedObject + 'static>(object: O) -> Self { | |
462 | Self { | |
463 | inner: Arc::new(object) as _, | |
464 | kind: O::object_name(), | |
465 | } | |
466 | } | |
467 | ||
468 | pub fn new_raw(_object: Arc<dyn Any + Send + Sync>, _kind: &'static str) -> Self { | |
469 | todo!() | |
470 | } | |
471 | ||
472 | pub fn kind(&self) -> &'static str { | |
473 | self.kind | |
474 | } | |
475 | } | |
476 | ||
477 | impl Deref for AnyObject { | |
478 | type Target = dyn Any + Send + Sync; | |
479 | ||
480 | fn deref(&self) -> &Self::Target { | |
481 | self.inner.as_ref() | |
482 | } | |
483 | } | |
456 | 484 | |
457 | 485 | #[derive(Clone)] |
458 | pub struct AnyOperation(pub Arc<dyn Any + Send>); | |
486 | pub struct AnyOperation { | |
487 | inner: Arc<dyn Any + Send + Sync>, | |
488 | kind: ObjectOperationPair<'static>, | |
489 | } | |
490 | ||
491 | impl AnyOperation { | |
492 | pub fn new<O: GiteratedObject, D: GiteratedOperation<O> + 'static>(operation: D) -> Self { | |
493 | Self { | |
494 | inner: Arc::new(operation) as _, | |
495 | kind: ObjectOperationPair::from_types::<O, D>(), | |
496 | } | |
497 | } | |
498 | ||
499 | pub fn new_raw( | |
500 | _operation: Arc<dyn Any + Send + Sync>, | |
501 | _kind: ObjectOperationPair<'static>, | |
502 | ) -> Self { | |
503 | todo!() | |
504 | } | |
505 | ||
506 | pub fn kind(&self) -> ObjectOperationPair<'static> { | |
507 | self.kind | |
508 | } | |
509 | } | |
510 | ||
511 | impl Deref for AnyOperation { | |
512 | type Target = dyn Any + Send + Sync; | |
513 | ||
514 | fn deref(&self) -> &Self::Target { | |
515 | self.inner.as_ref() | |
516 | } | |
517 | } | |
459 | 518 | |
460 | 519 | #[derive(Clone)] |
461 | pub struct AnySuccess(pub Arc<dyn Any + Send>); | |
520 | pub struct AnyValue { | |
521 | inner: Arc<dyn Any + Send + Sync>, | |
522 | kind: ObjectValuePair<'static>, | |
523 | } | |
524 | ||
525 | impl AnyValue { | |
526 | pub fn new<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static>( | |
527 | value: V, | |
528 | ) -> Self { | |
529 | Self { | |
530 | inner: Arc::new(value) as _, | |
531 | kind: ObjectValuePair::from_types::<O, V>(), | |
532 | } | |
533 | } | |
534 | ||
535 | pub fn new_raw(_value: Arc<dyn Any + Send + Sync>, _kind: ObjectValuePair<'static>) -> Self { | |
536 | todo!() | |
537 | } | |
538 | ||
539 | pub fn kind(&self) -> ObjectValuePair<'static> { | |
540 | self.kind | |
541 | } | |
542 | } | |
543 | ||
544 | impl Deref for AnyValue { | |
545 | type Target = dyn Any + Send + Sync; | |
546 | ||
547 | fn deref(&self) -> &Self::Target { | |
548 | self.inner.as_ref() | |
549 | } | |
550 | } | |
462 | 551 | |
463 | 552 | #[derive(Clone)] |
464 | pub struct AnyFailure(pub Arc<dyn Any + Send>); | |
553 | pub struct AnySetting { | |
554 | inner: Arc<dyn Any + Send + Sync>, | |
555 | kind: ObjectSettingPair<'static>, | |
556 | } | |
557 | ||
558 | impl AnySetting { | |
559 | pub fn new<O: GiteratedObject, S: Setting + 'static>(setting: S) -> Self { | |
560 | Self { | |
561 | inner: Arc::new(setting) as _, | |
562 | kind: ObjectSettingPair::from_types::<O, S>(), | |
563 | } | |
564 | } | |
565 | ||
566 | pub fn new_raw( | |
567 | _setting: Arc<dyn Any + Send + Sync>, | |
568 | _kind: ObjectSettingPair<'static>, | |
569 | ) -> Self { | |
570 | todo!() | |
571 | } | |
572 | ||
573 | pub fn kind(&self) -> ObjectSettingPair<'static> { | |
574 | self.kind | |
575 | } | |
576 | } | |
577 | ||
578 | impl Deref for AnySetting { | |
579 | type Target = dyn Any + Send + Sync; | |
580 | ||
581 | fn deref(&self) -> &Self::Target { | |
582 | self.inner.as_ref() | |
583 | } | |
584 | } | |
465 | 585 | |
466 | 586 | #[derive(Clone)] |
467 | pub struct AnyValue(pub Arc<dyn Any + Send>); | |
587 | pub struct AnySuccess(pub Arc<dyn Any + Send>); | |
468 | 588 | |
469 | 589 | #[derive(Clone)] |
470 | pub struct AnySetting(pub Arc<dyn Any + Send + Sync>); | |
590 | pub struct AnyFailure(pub Arc<dyn Any + Send>); | |
591 | ||
592 | /// Should be renamed. | |
593 | /// | |
594 | /// Allows accepting object types that are either GiteratedObject types or | |
595 | /// AnyObject. | |
596 | pub trait MaybeDynamicObject: Clone { | |
597 | fn from_any(object: &AnyObject) -> Self; | |
598 | ||
599 | fn object_name() -> &'static str; | |
600 | } | |
601 | ||
602 | impl<O: GiteratedObject> MaybeDynamicObject for O { | |
603 | fn from_any(_object: &AnyObject) -> Self { | |
604 | todo!() | |
605 | } | |
606 | ||
607 | fn object_name() -> &'static str { | |
608 | <O as GiteratedObject>::object_name() | |
609 | } | |
610 | } | |
611 | ||
612 | impl MaybeDynamicObject for AnyObject { | |
613 | fn from_any(object: &AnyObject) -> Self { | |
614 | object.clone() | |
615 | } | |
616 | ||
617 | fn object_name() -> &'static str { | |
618 | "any" | |
619 | } | |
620 | } | |
621 | ||
622 | pub trait MaybeDynamicValue { | |
623 | fn from_any(value: &AnyValue) -> Self; | |
624 | fn into_any(self) -> AnyValue; | |
625 | fn meta() -> Option<ValueMeta>; | |
626 | ||
627 | fn value_name() -> &'static str; | |
628 | } | |
629 | ||
630 | impl<V: GiteratedObjectValue> MaybeDynamicValue for V { | |
631 | fn from_any(_object: &AnyValue) -> Self { | |
632 | todo!() | |
633 | } | |
634 | ||
635 | fn value_name() -> &'static str { | |
636 | todo!() | |
637 | } | |
638 | ||
639 | fn into_any(self) -> AnyValue { | |
640 | todo!() | |
641 | } | |
642 | ||
643 | fn meta() -> Option<ValueMeta> { | |
644 | todo!() | |
645 | } | |
646 | } | |
647 | ||
648 | impl MaybeDynamicValue for AnyValue { | |
649 | fn value_name() -> &'static str { | |
650 | "any" | |
651 | } | |
652 | ||
653 | fn from_any(value: &AnyValue) -> Self { | |
654 | value.clone() | |
655 | } | |
656 | ||
657 | fn into_any(self) -> AnyValue { | |
658 | self | |
659 | } | |
660 | ||
661 | fn meta() -> Option<ValueMeta> { | |
662 | todo!() | |
663 | } | |
664 | } |
giterated-stack/src/meta/mod.rs
@@ -141,11 +141,11 @@ impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValu | ||
141 | 141 | } |
142 | 142 | |
143 | 143 | fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error> { |
144 | Ok(AnyValue(Arc::new(serde_json::from_slice(buffer)?))) | |
144 | Ok(AnyValue::new(serde_json::from_slice::<V>(buffer)?)) | |
145 | 145 | } |
146 | 146 | |
147 | 147 | fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> { |
148 | let value = value.0.downcast_ref::<V>().unwrap(); | |
148 | let value = value.downcast_ref::<V>().unwrap(); | |
149 | 149 | |
150 | 150 | serde_json::to_vec(&*value) |
151 | 151 | } |
@@ -157,7 +157,7 @@ impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValu | ||
157 | 157 | } |
158 | 158 | |
159 | 159 | fn is_get_value_typed(typed_get_value: AnyOperation) -> bool { |
160 | typed_get_value.0.is::<GetValueTyped<V>>() | |
160 | typed_get_value.is::<GetValueTyped<V>>() | |
161 | 161 | } |
162 | 162 | } |
163 | 163 | |
@@ -202,9 +202,7 @@ where | ||
202 | 202 | } |
203 | 203 | |
204 | 204 | fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error> { |
205 | Ok(AnyOperation( | |
206 | Arc::new(serde_json::from_slice::<D>(buffer)?) as Arc<dyn Any + Send + Sync> | |
207 | )) | |
205 | Ok(AnyOperation::new(serde_json::from_slice::<D>(buffer)?)) | |
208 | 206 | } |
209 | 207 | |
210 | 208 | fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> { |
@@ -237,6 +235,7 @@ impl OperationMeta { | ||
237 | 235 | |
238 | 236 | pub struct ObjectMeta { |
239 | 237 | pub name: String, |
238 | pub to_str: Box<dyn Fn(AnyObject) -> String + Send + Sync>, | |
240 | 239 | pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>, |
241 | 240 | pub any_is_same: fn(&dyn Any) -> bool, |
242 | 241 | } |
@@ -257,13 +256,18 @@ impl<O: GiteratedObject + 'static> IntoObjectMeta for O { | ||
257 | 256 | } |
258 | 257 | |
259 | 258 | impl ObjectMeta { |
260 | pub fn new<I: IntoObjectMeta + Send + Sync + 'static>() -> Self { | |
259 | pub fn new<I: IntoObjectMeta + Send + Sync + 'static + GiteratedObject>() -> Self { | |
261 | 260 | Self { |
262 | 261 | name: I::name(), |
263 | 262 | from_str: Box::new(|source| { |
264 | 263 | let object = I::from_str(source).map_err(|_| ())?; |
265 | 264 | |
266 | Ok(AnyObject(Arc::new(object) as Arc<dyn Any + Send + Sync>)) | |
265 | Ok(AnyObject::new(object)) | |
266 | }), | |
267 | to_str: Box::new(|source| { | |
268 | let object: &I = source.downcast_ref().unwrap(); | |
269 | ||
270 | object.to_string() | |
267 | 271 | }), |
268 | 272 | any_is_same: I::any_is_same, |
269 | 273 | } |
@@ -300,11 +304,11 @@ impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta | ||
300 | 304 | } |
301 | 305 | |
302 | 306 | fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> { |
303 | Ok(AnySetting(Arc::new(serde_json::from_value::<S>(value)?))) | |
307 | Ok(AnySetting::new::<O, S>(serde_json::from_value::<S>(value)?)) | |
304 | 308 | } |
305 | 309 | |
306 | 310 | fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> { |
307 | serde_json::to_value(setting.0.downcast_ref::<S>().unwrap()) | |
311 | serde_json::to_value(setting.downcast_ref::<S>().unwrap()) | |
308 | 312 | } |
309 | 313 | |
310 | 314 | fn setting_updated( |
@@ -316,8 +320,8 @@ impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta | ||
316 | 320 | async move { |
317 | 321 | stack |
318 | 322 | .setting_update( |
319 | object.0.downcast_ref::<O>().unwrap().clone(), | |
320 | setting.0.downcast_ref::<S>().unwrap().clone(), | |
323 | object.downcast_ref::<O>().unwrap().clone(), | |
324 | setting.downcast_ref::<S>().unwrap().clone(), | |
321 | 325 | operation_state, |
322 | 326 | ) |
323 | 327 | .await |
giterated-stack/src/stack.rs
@@ -1,6 +1,7 @@ | ||
1 | 1 | use std::any::Any; |
2 | 2 | |
3 | 3 | use std::fmt::Debug; |
4 | use std::ops::Deref; | |
4 | 5 | use std::{collections::HashMap, sync::Arc}; |
5 | 6 | |
6 | 7 | use giterated_models::authenticated::AuthenticatedPayload; |
@@ -8,7 +9,7 @@ use giterated_models::error::{GetValueError, IntoInternalError}; | ||
8 | 9 | use giterated_models::message::GiteratedMessage; |
9 | 10 | use giterated_models::object::NetworkAnyObject; |
10 | 11 | use giterated_models::operation::NetworkAnyOperation; |
11 | use giterated_models::settings::{GetSettingError, Setting, SetSettingError}; | |
12 | use giterated_models::settings::{GetSettingError, SetSettingError, Setting}; | |
12 | 13 | use giterated_models::value::{GetValue, GiteratedObjectValue}; |
13 | 14 | use giterated_models::{ |
14 | 15 | error::OperationError, |
@@ -17,8 +18,8 @@ use giterated_models::{ | ||
17 | 18 | operation::GiteratedOperation, |
18 | 19 | settings::{GetSetting, SetSetting}, |
19 | 20 | }; |
20 | use serde_json::Value; | |
21 | use tracing::{info, trace}; | |
21 | ||
22 | use tracing::{trace, warn}; | |
22 | 23 | |
23 | 24 | use crate::handler::HandlerTree; |
24 | 25 | use crate::provider::MetadataProvider; |
@@ -30,7 +31,7 @@ use crate::{ | ||
30 | 31 | |
31 | 32 | pub type OperationHandler = HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure>; |
32 | 33 | |
33 | pub type ValueGetter = HandlerWrapper<(AnyObject,), AnyValue, AnyFailure>; | |
34 | pub type ValueGetter = HandlerWrapper<(AnyObject, String), AnyValue, AnyFailure>; | |
34 | 35 | |
35 | 36 | pub type SettingGetter = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure>; |
36 | 37 | |
@@ -102,13 +103,50 @@ impl GiteratedStack { | ||
102 | 103 | trace!("value updated {}::{}", O::object_name(), V::value_name()); |
103 | 104 | let target = ObjectValuePair::from_types::<O, V>(); |
104 | 105 | |
106 | let object = AnyObject::new(object); | |
107 | let value = AnyValue::new(new_value); | |
108 | ||
109 | // First, resolve a handler for the exact object value pair | |
105 | 110 | if let Some(handler) = self.value_change.get(&target) { |
106 | 111 | // TODO |
107 | 112 | let _ = handler |
108 | .handle( | |
109 | (AnyObject(Arc::new(object)), AnyValue(Arc::new(new_value))), | |
110 | operation_state.clone(), | |
111 | ) | |
113 | .handle((object.clone(), value.clone()), operation_state.clone()) | |
114 | .await; | |
115 | } | |
116 | ||
117 | // We need to resolve for `any` object and `any` value combination | |
118 | let target = ObjectValuePair { | |
119 | object_kind: "any", | |
120 | value_kind: V::value_name(), | |
121 | }; | |
122 | if let Some(handler) = self.value_change.get(&target) { | |
123 | // TODO | |
124 | let _ = handler | |
125 | .handle((object.clone(), value.clone()), operation_state.clone()) | |
126 | .await; | |
127 | } | |
128 | ||
129 | let target = ObjectValuePair { | |
130 | object_kind: O::object_name(), | |
131 | value_kind: "any", | |
132 | }; | |
133 | if let Some(handler) = self.value_change.get(&target) { | |
134 | // TODO | |
135 | let _ = handler | |
136 | .handle((object.clone(), value.clone()), operation_state.clone()) | |
137 | .await; | |
138 | } | |
139 | ||
140 | // Now resolve for both `any` | |
141 | ||
142 | let target = ObjectValuePair { | |
143 | object_kind: "any", | |
144 | value_kind: "any", | |
145 | }; | |
146 | if let Some(handler) = self.value_change.get(&target) { | |
147 | // TODO | |
148 | let _ = handler | |
149 | .handle((object.clone(), value.clone()), operation_state.clone()) | |
112 | 150 | .await; |
113 | 151 | } |
114 | 152 | } |
@@ -128,10 +166,7 @@ impl GiteratedStack { | ||
128 | 166 | if let Some(handler) = self.setting_change.get(&target) { |
129 | 167 | let _ = handler |
130 | 168 | .handle( |
131 | ( | |
132 | AnyObject(Arc::new(object)), | |
133 | AnySetting(Arc::new(new_setting)), | |
134 | ), | |
169 | (AnyObject::new(object), AnySetting::new::<O, S>(new_setting)), | |
135 | 170 | operation_state.clone(), |
136 | 171 | ) |
137 | 172 | .await; |
@@ -171,9 +206,9 @@ impl GiteratedStack { | ||
171 | 206 | |
172 | 207 | let result = provider |
173 | 208 | .write( |
174 | AnyObject(Arc::new(object.clone())), | |
209 | AnyObject::new(object.clone()), | |
175 | 210 | object_meta, |
176 | AnySetting(Arc::new(setting)), | |
211 | AnySetting::new::<O, S>(setting), | |
177 | 212 | setting_meta, |
178 | 213 | ) |
179 | 214 | .await |
@@ -213,11 +248,7 @@ impl GiteratedStack { | ||
213 | 248 | .ok_or_else(|| OperationError::Unhandled)?; |
214 | 249 | |
215 | 250 | let value = provider |
216 | .read( | |
217 | AnyObject(Arc::new(object.clone())), | |
218 | object_meta, | |
219 | setting_meta, | |
220 | ) | |
251 | .read(AnyObject::new(object.clone()), object_meta, setting_meta) | |
221 | 252 | .await |
222 | 253 | .as_internal_error_with_context(format!("getting setting {}", S::name()))?; |
223 | 254 | |
@@ -367,7 +398,13 @@ impl GiteratedStack { | ||
367 | 398 | setting_name: &operation.setting_name, |
368 | 399 | }) |
369 | 400 | // TODO: Check this |
370 | .ok_or(OperationError::Operation(serde_json::to_vec(&SetSettingError::InvalidSetting(operation.setting_name.clone(), object_type.clone())).as_internal_error()?))?; | |
401 | .ok_or(OperationError::Operation( | |
402 | serde_json::to_vec(&SetSettingError::InvalidSetting( | |
403 | operation.setting_name.clone(), | |
404 | object_type.clone(), | |
405 | )) | |
406 | .as_internal_error()?, | |
407 | ))?; | |
371 | 408 | |
372 | 409 | let setting = (setting_meta.deserialize)(operation.value) |
373 | 410 | .as_internal_error_with_context(format!( |
@@ -382,7 +419,7 @@ impl GiteratedStack { | ||
382 | 419 | ); |
383 | 420 | |
384 | 421 | for provider in self.metadata_providers.iter() { |
385 | if provider.provides_for(object.0.as_ref()) { | |
422 | if provider.provides_for(object.deref()) { | |
386 | 423 | trace!( |
387 | 424 | "Resolved setting provider for setting {} for object {}", |
388 | 425 | operation.setting_name, |
@@ -506,45 +543,175 @@ impl GiteratedStack { | ||
506 | 543 | ) -> Result<Vec<u8>, OperationError<Vec<u8>>> { |
507 | 544 | trace!("Handling network get_value for {}", operation.value_name); |
508 | 545 | |
509 | let value_meta = self | |
510 | .metadata | |
511 | .values | |
512 | .get(&ObjectValuePair { | |
513 | object_kind: &object_kind, | |
514 | value_kind: &operation.value_name, | |
515 | }) | |
516 | .ok_or_else(|| OperationError::Unhandled)?; | |
546 | // We first attempt generic handlers | |
547 | if let Some(handler) = self.value_getters.get(&ObjectValuePair { | |
548 | object_kind: "any", | |
549 | value_kind: &operation.value_name, | |
550 | }) { | |
551 | match handler | |
552 | .handle( | |
553 | (object.clone(), operation.value_name.clone()), | |
554 | operation_state.clone(), | |
555 | ) | |
556 | .await | |
557 | { | |
558 | Ok(success) => { | |
559 | // Resolve the metadata to serialize | |
560 | let value_meta = self | |
561 | .metadata | |
562 | .values | |
563 | .get(&success.kind()) | |
564 | .ok_or_else(|| OperationError::Unhandled)?; | |
565 | ||
566 | return Ok((value_meta.serialize)(success).as_internal_error()?); | |
567 | } | |
568 | Err(err) => { | |
569 | match err { | |
570 | OperationError::Operation(operation_error) => { | |
571 | // This DOES result in an early return, because it was handled | |
572 | let error: &GetValueError = operation_error.0.downcast_ref().unwrap(); | |
573 | ||
574 | return Err(OperationError::Operation( | |
575 | serde_json::to_vec(&error).as_internal_error()?, | |
576 | )); | |
577 | } | |
578 | OperationError::Internal(internal) => { | |
579 | // This DOES NOT result in an early return | |
580 | warn!("An internal error occurred during a failable handler operation. {:?}", internal); | |
581 | } | |
582 | OperationError::Unhandled => { | |
583 | // This DOES NOT result in an early return | |
584 | } | |
585 | } | |
586 | } | |
587 | } | |
588 | } | |
589 | if let Some(handler) = self.value_getters.get(&ObjectValuePair { | |
590 | object_kind: &object_kind, | |
591 | value_kind: "any", | |
592 | }) { | |
593 | match handler | |
594 | .handle( | |
595 | (object.clone(), operation.value_name.clone()), | |
596 | operation_state.clone(), | |
597 | ) | |
598 | .await | |
599 | { | |
600 | Ok(success) => { | |
601 | // Resolve the metadata to serialize | |
602 | let value_meta = self | |
603 | .metadata | |
604 | .values | |
605 | .get(&success.kind()) | |
606 | .ok_or_else(|| OperationError::Unhandled)?; | |
517 | 607 | |
518 | for (target, getter) in self.value_getters.iter() { | |
519 | if target.object_kind != object_kind { | |
520 | continue; | |
608 | return Ok((value_meta.serialize)(success).as_internal_error()?); | |
609 | } | |
610 | Err(err) => { | |
611 | match err { | |
612 | OperationError::Operation(operation_error) => { | |
613 | // This DOES result in an early return, because it was handled | |
614 | let error: &GetValueError = operation_error.0.downcast_ref().unwrap(); | |
615 | ||
616 | return Err(OperationError::Operation( | |
617 | serde_json::to_vec(&error).as_internal_error()?, | |
618 | )); | |
619 | } | |
620 | OperationError::Internal(internal) => { | |
621 | // This DOES NOT result in an early return | |
622 | warn!("An internal error occurred during a failable handler operation. {:?}", internal); | |
623 | } | |
624 | OperationError::Unhandled => { | |
625 | // This DOES NOT result in an early return | |
626 | } | |
627 | } | |
628 | } | |
521 | 629 | } |
630 | } | |
631 | if let Some(handler) = self.value_getters.get(&ObjectValuePair { | |
632 | object_kind: "any", | |
633 | value_kind: "any", | |
634 | }) { | |
635 | match handler | |
636 | .handle( | |
637 | (object.clone(), operation.value_name.clone()), | |
638 | operation_state.clone(), | |
639 | ) | |
640 | .await | |
641 | { | |
642 | Ok(success) => { | |
643 | // Resolve the metadata to serialize | |
644 | let value_meta = self | |
645 | .metadata | |
646 | .values | |
647 | .get(&success.kind()) | |
648 | .ok_or_else(|| OperationError::Unhandled)?; | |
522 | 649 | |
523 | if target.value_kind != operation.value_name { | |
524 | continue; | |
650 | return Ok((value_meta.serialize)(success).as_internal_error()?); | |
651 | } | |
652 | Err(err) => { | |
653 | match err { | |
654 | OperationError::Operation(operation_error) => { | |
655 | // This DOES result in an early return, because it was handled | |
656 | let error: &GetValueError = operation_error.0.downcast_ref().unwrap(); | |
657 | ||
658 | return Err(OperationError::Operation( | |
659 | serde_json::to_vec(&error).as_internal_error()?, | |
660 | )); | |
661 | } | |
662 | OperationError::Internal(internal) => { | |
663 | // This DOES NOT result in an early return | |
664 | warn!("An internal error occurred during a failable handler operation. {:?}", internal); | |
665 | } | |
666 | OperationError::Unhandled => { | |
667 | // This DOES NOT result in an early return | |
668 | } | |
669 | } | |
670 | } | |
525 | 671 | } |
672 | } | |
526 | 673 | |
527 | return match getter | |
528 | .handle((object.clone(),), operation_state.clone()) | |
674 | if let Some(handler) = self.value_getters.get(&ObjectValuePair { | |
675 | object_kind: &object_kind, | |
676 | value_kind: &operation.value_name, | |
677 | }) { | |
678 | match handler | |
679 | .handle( | |
680 | (object.clone(), operation.value_name.clone()), | |
681 | operation_state.clone(), | |
682 | ) | |
529 | 683 | .await |
530 | 684 | { |
531 | 685 | Ok(success) => { |
532 | // Serialize success, which is the value type itself | |
533 | let serialized = (value_meta.serialize)(success).as_internal_error()?; | |
686 | // Resolve the metadata to serialize | |
687 | let value_meta = self | |
688 | .metadata | |
689 | .values | |
690 | .get(&success.kind()) | |
691 | .ok_or_else(|| OperationError::Unhandled)?; | |
534 | 692 | |
535 | Ok(serialized) | |
693 | return Ok((value_meta.serialize)(success).as_internal_error()?); | |
536 | 694 | } |
537 | Err(err) => Err(match err { | |
538 | OperationError::Operation(failure) => { | |
539 | // Failure is sourced from GetValue operation, but this is hardcoded for now | |
540 | let failure: &GetValueError = failure.0.downcast_ref().unwrap(); | |
541 | ||
542 | OperationError::Operation(serde_json::to_vec(&failure).as_internal_error()?) | |
695 | Err(err) => { | |
696 | match err { | |
697 | OperationError::Operation(operation_error) => { | |
698 | // This DOES result in an early return, because it was handled | |
699 | let error: &GetValueError = operation_error.0.downcast_ref().unwrap(); | |
700 | ||
701 | return Err(OperationError::Operation( | |
702 | serde_json::to_vec(&error).as_internal_error()?, | |
703 | )); | |
704 | } | |
705 | OperationError::Internal(internal) => { | |
706 | // This DOES NOT result in an early return | |
707 | warn!("An internal error occurred during a failable handler operation. {:?}", internal); | |
708 | } | |
709 | OperationError::Unhandled => { | |
710 | // This DOES NOT result in an early return | |
711 | } | |
543 | 712 | } |
544 | OperationError::Internal(internal) => OperationError::Internal(internal), | |
545 | OperationError::Unhandled => OperationError::Unhandled, | |
546 | }), | |
547 | }; | |
713 | } | |
714 | } | |
548 | 715 | } |
549 | 716 | |
550 | 717 | Err(OperationError::Unhandled) |
@@ -564,7 +731,7 @@ impl GiteratedStack { | ||
564 | 731 | ); |
565 | 732 | |
566 | 733 | for provider in self.metadata_providers.iter() { |
567 | if provider.provides_for(object.0.as_ref()) { | |
734 | if provider.provides_for(object.deref()) { | |
568 | 735 | let setting_meta = self |
569 | 736 | .metadata |
570 | 737 | .settings |
@@ -671,13 +838,12 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
671 | 838 | D::Failure: Clone, |
672 | 839 | { |
673 | 840 | // Erase object and operation types. |
674 | let object = AnyObject(Arc::new(in_object.clone()) as Arc<dyn Any + Send + Sync>); | |
675 | let operation = AnyOperation(Arc::new(payload) as Arc<dyn Any + Send + Sync>); | |
841 | let object = AnyObject::new(in_object.clone()); | |
842 | let operation = AnyOperation::new(payload); | |
676 | 843 | |
677 | 844 | // We need to hijack get_value, set_setting, and get_setting. |
678 | 845 | if operation_name == "get_value" { |
679 | 846 | let get_value = operation |
680 | .0 | |
681 | 847 | .downcast_ref::<GetValue>() |
682 | 848 | .ok_or_else(|| OperationError::Unhandled)?; |
683 | 849 | |
@@ -713,7 +879,10 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
713 | 879 | ); |
714 | 880 | |
715 | 881 | return match getter |
716 | .handle((object.clone(),), operation_state.clone()) | |
882 | .handle( | |
883 | (object.clone(), get_value.value_name.clone()), | |
884 | operation_state.clone(), | |
885 | ) | |
717 | 886 | .await |
718 | 887 | { |
719 | 888 | Ok(success) => Ok(*(Box::new((value_meta.serialize)(success).unwrap()) |
@@ -735,8 +904,8 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
735 | 904 | }), |
736 | 905 | }; |
737 | 906 | } |
738 | } else if operation.0.is::<GetSetting>() { | |
739 | let get_setting: &GetSetting = operation.0.downcast_ref().unwrap(); | |
907 | } else if operation.is::<GetSetting>() { | |
908 | let get_setting: &GetSetting = operation.downcast_ref().unwrap(); | |
740 | 909 | let setting_name = get_setting.setting_name.clone(); |
741 | 910 | |
742 | 911 | let raw_result = self |
@@ -754,7 +923,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
754 | 923 | // let serialized = (setting_meta.serialize)(success).unwrap(); |
755 | 924 | |
756 | 925 | // Ok(serde_json::to_vec(&serialized).unwrap()) |
757 | Ok(success.0.downcast_ref::<D::Success>().unwrap().clone()) | |
926 | Ok(success.downcast_ref::<D::Success>().unwrap().clone()) | |
758 | 927 | } |
759 | 928 | Err(err) => Err(match err { |
760 | 929 | OperationError::Operation(failure) => { |
@@ -771,9 +940,9 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
771 | 940 | OperationError::Unhandled => OperationError::Unhandled, |
772 | 941 | }), |
773 | 942 | }; |
774 | } else if operation.0.is::<SetSetting>() { | |
943 | } else if operation.is::<SetSetting>() { | |
775 | 944 | todo!() |
776 | } else if operation.0.is::<ObjectRequest>() { | |
945 | } else if operation.is::<ObjectRequest>() { | |
777 | 946 | todo!() |
778 | 947 | } |
779 | 948 | |
@@ -841,10 +1010,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> { | ||
841 | 1010 | for (_object_name, object_meta) in self.metadata.objects.iter() { |
842 | 1011 | if let Ok(object) = (object_meta.from_str)(object_str) { |
843 | 1012 | return Ok(unsafe { |
844 | Object::new_unchecked( | |
845 | object.0.downcast_ref::<O>().unwrap().clone(), | |
846 | self.clone(), | |
847 | ) | |
1013 | Object::new_unchecked(object.downcast_ref::<O>().unwrap().clone(), self.clone()) | |
848 | 1014 | }); |
849 | 1015 | } |
850 | 1016 | } |
giterated-stack/src/substack.rs
@@ -14,8 +14,9 @@ use tracing::{info, trace}; | ||
14 | 14 | use crate::{ |
15 | 15 | handler::HandlerWrapper, provider::MetadataProvider, AnyFailure, AnyObject, AnyOperation, |
16 | 16 | AnySetting, AnySuccess, AnyValue, GiteratedStack, GiteratedStackState, IntoGiteratedHandler, |
17 | ObjectOperationPair, ObjectSettingPair, ObjectValuePair, OperationHandler, RuntimeMetadata, | |
18 | SettingChange, SettingGetter, StackOperationState, ValueChange, ValueGetter, | |
17 | MaybeDynamicObject, MaybeDynamicValue, ObjectOperationPair, ObjectSettingPair, ObjectValuePair, | |
18 | OperationHandler, RuntimeMetadata, SettingChange, SettingGetter, StackOperationState, | |
19 | ValueChange, ValueGetter, | |
19 | 20 | }; |
20 | 21 | |
21 | 22 | pub struct SubstackBuilder<S: GiteratedStackState> { |
@@ -75,8 +76,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
75 | 76 | |(any_object, any_operation): &(AnyObject, AnyOperation), |
76 | 77 | _state: &StackOperationState| { |
77 | 78 | Ok(( |
78 | any_object.0.downcast_ref::<O>().unwrap().clone(), | |
79 | any_operation.0.downcast_ref::<D>().unwrap().clone(), | |
79 | any_object.downcast_ref::<O>().unwrap().clone(), | |
80 | any_operation.downcast_ref::<D>().unwrap().clone(), | |
80 | 81 | )) |
81 | 82 | }, |
82 | 83 | ); |
@@ -172,8 +173,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
172 | 173 | ); |
173 | 174 | let object = object.clone(); |
174 | 175 | async move { |
175 | let object = object.0.downcast_ref::<O>().unwrap(); | |
176 | let setting = setting.0.downcast_ref::<T>().unwrap(); | |
176 | let object = object.downcast_ref::<O>().unwrap(); | |
177 | let setting = setting.downcast_ref::<T>().unwrap(); | |
177 | 178 | stack |
178 | 179 | .value_update(object.clone(), setting.clone(), &operation_state) |
179 | 180 | .await; |
@@ -187,6 +188,7 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
187 | 188 | let wrapped = HandlerWrapper::new( |
188 | 189 | self.state.clone(), |
189 | 190 | |object: AnyObject, |
191 | _name: String, | |
190 | 192 | _state: _, |
191 | 193 | _operation_state: StackOperationState, |
192 | 194 | stack: Arc<GiteratedStack>| { |
@@ -194,10 +196,10 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
194 | 196 | let object = object.clone(); |
195 | 197 | async move { |
196 | 198 | match stack |
197 | .new_get_setting::<O, T>(object.0.downcast_ref().unwrap()) | |
199 | .new_get_setting::<O, T>(object.downcast_ref().unwrap()) | |
198 | 200 | .await |
199 | 201 | { |
200 | Ok(setting) => Ok(AnyValue(Arc::new(setting))), | |
202 | Ok(setting) => Ok(AnyValue::new(setting)), | |
201 | 203 | Err(err) => { |
202 | 204 | panic!("Error: {:?}", err); |
203 | 205 | } |
@@ -219,30 +221,29 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
219 | 221 | /// # Type Registration |
220 | 222 | /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified |
221 | 223 | /// object type. It will **not** register the object type automatically. |
222 | pub fn value<O, V, A, F, E>(&mut self, handler: F) -> &mut Self | |
224 | pub fn dynamic_value<O, A, F>(&mut self, handler: F) -> &mut Self | |
223 | 225 | where |
224 | O: GiteratedObject + 'static, | |
225 | V: GiteratedObjectValue<Object = O> + 'static + Clone, | |
226 | F: IntoGiteratedHandler<(O,), A, S, StackOperationState, Result<V, OperationError<E>>> | |
227 | + Send | |
226 | O: MaybeDynamicObject + 'static, | |
227 | F: IntoGiteratedHandler< | |
228 | (O, String), | |
229 | A, | |
230 | S, | |
231 | StackOperationState, | |
232 | Result<AnyValue, OperationError<anyhow::Error>>, | |
233 | > + Send | |
228 | 234 | + Sync, |
229 | E: Into<anyhow::Error> + 'static + std::fmt::Debug + Clone, | |
230 | 235 | F: 'static, |
231 | 236 | { |
232 | 237 | let wrapped = HandlerWrapper::new(self.state.clone(), handler); |
233 | 238 | |
234 | 239 | let wrapped = wrapped.map( |
235 | |(any_object,): &(AnyObject,), _state: &StackOperationState| { | |
236 | Ok((any_object | |
237 | .0 | |
238 | .downcast_ref::<O>() | |
239 | .ok_or_else(|| OperationError::Internal(DowncastError.into()))? | |
240 | .clone(),)) | |
240 | |(any_object, name): &(AnyObject, String), _state: &StackOperationState| { | |
241 | Ok((O::from_any(any_object), name.clone())) | |
241 | 242 | }, |
242 | 243 | ); |
243 | 244 | |
244 | 245 | let wrapped = wrapped.map_return(|ret_val, _state| match ret_val { |
245 | Ok(success) => Ok(AnyValue(Arc::new(success))), | |
246 | Ok(success) => Ok(success.into_any()), | |
246 | 247 | Err(err) => Err(match err { |
247 | 248 | OperationError::Operation(failure) => OperationError::Internal(failure.into()), |
248 | 249 | OperationError::Internal(err) => OperationError::Internal(err), |
@@ -252,17 +253,20 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
252 | 253 | |
253 | 254 | assert!(self |
254 | 255 | .value_getters |
255 | .insert(ObjectValuePair::from_types::<O, V>(), wrapped) | |
256 | .insert( | |
257 | ObjectValuePair { | |
258 | object_kind: O::object_name(), | |
259 | value_kind: "any" | |
260 | }, | |
261 | wrapped | |
262 | ) | |
256 | 263 | .is_none()); |
257 | 264 | |
258 | self.metadata.register_value::<O, V>(); | |
259 | ||
260 | 265 | self |
261 | 266 | } |
262 | 267 | |
263 | 268 | pub fn value_change<O, A, F, V>(&mut self, handler: F) -> &mut Self |
264 | 269 | where |
265 | O: GiteratedObject + 'static, | |
266 | 270 | F: IntoGiteratedHandler< |
267 | 271 | (O, V), |
268 | 272 | A, |
@@ -271,8 +275,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
271 | 275 | Result<(), OperationError<anyhow::Error>>, |
272 | 276 | > + Send |
273 | 277 | + Sync, |
274 | V: GiteratedObjectValue<Object = O> + Clone + 'static, | |
275 | O: 'static, | |
278 | V: MaybeDynamicValue + Clone + 'static, | |
279 | O: 'static + MaybeDynamicObject, | |
276 | 280 | V: 'static, |
277 | 281 | F: 'static, |
278 | 282 | { |
@@ -280,24 +284,19 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> { | ||
280 | 284 | |
281 | 285 | let wrapped = wrapped.map( |
282 | 286 | |(any_object, any_value): &(AnyObject, AnyValue), _state: &StackOperationState| { |
283 | Ok(( | |
284 | any_object | |
285 | .0 | |
286 | .downcast_ref::<O>() | |
287 | .ok_or_else(|| OperationError::Internal(DowncastError.into()))? | |
288 | .clone(), | |
289 | any_value | |
290 | .0 | |
291 | .downcast_ref::<V>() | |
292 | .ok_or_else(|| OperationError::Internal(DowncastError.into()))? | |
293 | .clone(), | |
294 | )) | |
287 | Ok((O::from_any(any_object), V::from_any(any_value))) | |
295 | 288 | }, |
296 | 289 | ); |
297 | 290 | |
298 | 291 | assert!(self |
299 | 292 | .value_change |
300 | .insert(ObjectValuePair::from_types::<O, V>(), wrapped) | |
293 | .insert( | |
294 | ObjectValuePair { | |
295 | object_kind: O::object_name(), | |
296 | value_kind: V::value_name() | |
297 | }, | |
298 | wrapped | |
299 | ) | |
301 | 300 | .is_none()); |
302 | 301 | |
303 | 302 | self |