reactive_graph_behaviour_service_impl/
relation_behaviour_manager_impl.rs

1use 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 {}