reactive_graph_reactive_service_impl/
reactive_instance_event_manager_impl.rs1use 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}