reactive_graph_reactive_service_impl/
reactive_instance_event_manager_impl.rs

1use std::ops::Deref;
2
3use async_trait::async_trait;
4use dashmap::DashMap;
5use serde_json::json;
6use springtime_di::Component;
7use springtime_di::component_alias;
8
9use reactive_graph_graph::EntityInstance;
10use reactive_graph_graph::PropertyInstanceSetter;
11use reactive_graph_graph::PropertyInstances;
12use reactive_graph_graph::PropertyTypeDefinition;
13use reactive_graph_lifecycle::Lifecycle;
14use reactive_graph_reactive_model_impl::ReactiveEntity;
15use reactive_graph_reactive_service_api::REACTIVE_INSTANCE_EVENT_PROPERTY_LABEL;
16use reactive_graph_reactive_service_api::ReactiveInstanceEvent;
17use reactive_graph_reactive_service_api::ReactiveInstanceEventManager;
18use reactive_graph_reactive_service_api::ReactiveInstanceEventTypes;
19use reactive_graph_runtime_model::ENTITY_TYPE_SYSTEM_EVENT;
20use reactive_graph_runtime_model::EventProperties::EVENT;
21
22#[derive(Component)]
23pub struct ReactiveInstanceEventManagerImpl {
24    #[component(default = "DashMap::new")]
25    event_instances: DashMap<ReactiveInstanceEventTypes, ReactiveEntity>,
26}
27
28#[async_trait]
29#[component_alias]
30impl ReactiveInstanceEventManager for ReactiveInstanceEventManagerImpl {
31    fn emit_event(&self, event: ReactiveInstanceEvent) {
32        let Some(entity_instance) = self.get_reactive_instance_event_instance((&event).into()) else {
33            return;
34        };
35        match event {
36            ReactiveInstanceEvent::EntityInstanceCreated(id)
37            | ReactiveInstanceEvent::EntityInstanceDeleted(id)
38            | ReactiveInstanceEvent::FlowInstanceCreated(id)
39            | ReactiveInstanceEvent::FlowInstanceDeleted(id) => entity_instance.set(EVENT.property_name(), json!(id)),
40            ReactiveInstanceEvent::RelationInstanceCreated(relation_instance_id) | ReactiveInstanceEvent::RelationInstanceDeleted(relation_instance_id) => {
41                entity_instance.set(EVENT.property_name(), json!(relation_instance_id))
42            }
43        }
44    }
45
46    fn get_reactive_instance_event_instances(&self) -> Vec<ReactiveEntity> {
47        self.event_instances.iter().map(|reactive_entity| reactive_entity.value().clone()).collect()
48    }
49
50    fn get_reactive_instance_event_instance(&self, event_type: ReactiveInstanceEventTypes) -> Option<ReactiveEntity> {
51        self.event_instances.get(&event_type).map(|reactive_entity| reactive_entity.value().clone())
52    }
53}
54
55impl ReactiveInstanceEventManagerImpl {
56    pub(crate) fn create_event_instances(&self) {
57        self.event_instances.insert(
58            ReactiveInstanceEventTypes::EntityInstanceCreated,
59            self.create_event_instance("/io/reactive-graph/event/instance/entity/created"),
60        );
61        self.event_instances.insert(
62            ReactiveInstanceEventTypes::EntityInstanceDeleted,
63            self.create_event_instance("/io/reactive-graph/event/instance/entity/deleted"),
64        );
65        self.event_instances.insert(
66            ReactiveInstanceEventTypes::RelationInstanceCreated,
67            self.create_event_instance("/io/reactive-graph/event/instance/relation/created"),
68        );
69        self.event_instances.insert(
70            ReactiveInstanceEventTypes::RelationInstanceDeleted,
71            self.create_event_instance("/io/reactive-graph/event/instance/relation/deleted"),
72        );
73        self.event_instances.insert(
74            ReactiveInstanceEventTypes::FlowInstanceCreated,
75            self.create_event_instance("/io/reactive-graph/event/instance/flow/created"),
76        );
77        self.event_instances.insert(
78            ReactiveInstanceEventTypes::FlowInstanceDeleted,
79            self.create_event_instance("/io/reactive-graph/event/instance/flow/deleted"),
80        );
81    }
82
83    pub(crate) fn create_event_instance<S: Into<String>>(&self, label: S) -> ReactiveEntity {
84        EntityInstance::builder()
85            .ty(ENTITY_TYPE_SYSTEM_EVENT.deref())
86            .properties(
87                PropertyInstances::new()
88                    .property(REACTIVE_INSTANCE_EVENT_PROPERTY_LABEL, json!(label.into()))
89                    .property(EVENT.property_name(), json!(false)),
90            )
91            .build()
92            .into()
93    }
94
95    pub(crate) fn delete_event_instances(&self) {}
96}
97
98#[async_trait]
99impl Lifecycle for ReactiveInstanceEventManagerImpl {
100    async fn post_init(&self) {
101        self.create_event_instances();
102    }
103
104    async fn pre_shutdown(&self) {
105        self.delete_event_instances();
106    }
107}