reactive_graph_behaviour_service_impl/
relation_behaviour_manager_impl.rs1use async_trait::async_trait;
2use log::trace;
3use std::sync::Arc;
4
5use reactive_graph_behaviour_model_api::BehaviourConnectFailed;
6use reactive_graph_behaviour_model_api::BehaviourDisconnectFailed;
7use reactive_graph_behaviour_model_api::BehaviourState;
8use reactive_graph_behaviour_model_api::BehaviourTransitionError;
9use reactive_graph_behaviour_model_api::BehaviourTypeId;
10use reactive_graph_behaviour_model_impl::RelationBehaviourStorage;
11use reactive_graph_behaviour_service_api::RelationBehaviourManager;
12use reactive_graph_behaviour_service_api::RelationBehaviourRegistry;
13use reactive_graph_graph::RelationInstanceId;
14use reactive_graph_lifecycle::Lifecycle;
15use reactive_graph_reactive_model_api::ReactiveInstance;
16use reactive_graph_reactive_model_impl::ReactiveRelation;
17use springtime_di::Component;
18use springtime_di::component_alias;
19
20#[derive(Component)]
21pub struct RelationBehaviourManagerImpl {
22 relation_behaviour_registry: Arc<dyn RelationBehaviourRegistry + Send + Sync>,
23
24 #[component(default = "RelationBehaviourStorage::new")]
25 relation_behaviour_storage: RelationBehaviourStorage,
26}
27
28#[async_trait]
29#[component_alias]
30impl RelationBehaviourManager for RelationBehaviourManagerImpl {
31 fn add_behaviours(&self, relation_instance: ReactiveRelation) {
32 let id = relation_instance.id();
33 let relation_ty = relation_instance.relation_type_id();
34 for factory in self.relation_behaviour_registry.get(&relation_ty) {
35 if let Ok(behaviour) = factory.create(relation_instance.clone()) {
36 self.relation_behaviour_storage.insert(id.clone(), behaviour.ty().clone(), behaviour.clone());
37 trace!("Added relation behaviour {}", behaviour.ty());
38 }
39 }
40 }
41
42 fn add_behaviour(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) {
43 if let Some(factory) = self.relation_behaviour_registry.get_factory_by_behaviour_type(behaviour_ty) {
44 let id = relation_instance.id();
45 if let Ok(behaviour) = factory.create(relation_instance) {
46 let behaviour_ty = behaviour.ty().clone();
47 self.relation_behaviour_storage.insert(id, behaviour_ty.clone(), behaviour);
48 trace!("Added relation behaviour {}", &behaviour_ty);
49 }
50 }
51 }
52
53 fn remove_behaviour(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) {
54 let id = relation_instance.id();
55 let _ = self.disconnect(relation_instance, behaviour_ty);
56 self.relation_behaviour_storage.remove(&id, behaviour_ty);
57 trace!("Removed relation behaviour {}", &behaviour_ty);
58 }
59
60 fn remove_behaviours(&self, relation_instance: ReactiveRelation) {
61 self.relation_behaviour_storage.remove_all(&relation_instance.id());
62 }
63
64 fn remove_behaviours_by_key(&self, relation_instance_id: &RelationInstanceId) {
65 self.relation_behaviour_storage.remove_all(relation_instance_id);
66 }
67
68 fn remove_behaviours_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) {
69 self.relation_behaviour_storage.remove_by_behaviour(behaviour_ty);
70 trace!("Removed all relation behaviours of type {}", &behaviour_ty);
71 }
72
73 fn has(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> bool {
74 self.relation_behaviour_storage.has(&relation_instance.id(), behaviour_ty)
75 }
76
77 fn get_all(&self, relation_instance: ReactiveRelation) -> Vec<BehaviourTypeId> {
78 self.relation_behaviour_storage.get_behaviours_by_instance(&relation_instance.id())
79 }
80
81 fn get_instances_by_behaviour(&self, ty: &BehaviourTypeId) -> Vec<ReactiveRelation> {
82 self.relation_behaviour_storage.get_instances_by_behaviour(ty)
83 }
84
85 fn connect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
86 if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
87 return fsm.transition(BehaviourState::Connected);
88 }
89 Err(BehaviourTransitionError::BehaviourConnectFailed(BehaviourConnectFailed {}))
90 }
91
92 fn disconnect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
93 if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
94 return fsm.transition(BehaviourState::Ready);
95 }
96 Err(BehaviourTransitionError::BehaviourDisconnectFailed(BehaviourDisconnectFailed {}))
97 }
98
99 fn reconnect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
100 if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
101 return fsm.transition(BehaviourState::Ready).and_then(|_| fsm.transition(BehaviourState::Connected));
102 }
103 Err(BehaviourTransitionError::InvalidTransition)
104 }
105}
106
107#[async_trait]
108impl Lifecycle for RelationBehaviourManagerImpl {}