reactive_graph_dynamic_graph_impl/object/namespace/
metrics.rs1use async_graphql::dynamic::Field;
2use async_graphql::dynamic::FieldFuture;
3use async_graphql::dynamic::FieldValue;
4use async_graphql::dynamic::Object;
5use async_graphql::dynamic::ResolverContext;
6use async_graphql::dynamic::TypeRef;
7use reactive_graph_type_system_api::ComponentManager;
8use reactive_graph_type_system_api::EntityTypeManager;
9use reactive_graph_type_system_api::FlowTypeManager;
10use reactive_graph_type_system_api::RelationTypeManager;
11use std::sync::Arc;
12
13const TYPE_METRICS: &str = "NamespaceMetrics";
14const ROOT_NAMESPACE: &str = "root";
15
16#[derive(Debug)]
17enum ResolvedNamespace {
18 Root,
19 Namespace(String),
20}
21
22impl From<Option<String>> for ResolvedNamespace {
23 fn from(value: Option<String>) -> Self {
24 match value {
25 None => ResolvedNamespace::Root,
26 Some(namespace) => {
27 if namespace.as_str() == ROOT_NAMESPACE {
28 ResolvedNamespace::Root
29 } else {
30 ResolvedNamespace::Namespace(namespace)
31 }
32 }
33 }
34 }
35}
36
37pub fn metrics_type_name() -> TypeRef {
38 TypeRef::named_nn(TYPE_METRICS)
39}
40
41pub fn metrics_object() -> Object {
42 Object::new(TYPE_METRICS)
43 .field(Field::new("components", TypeRef::named_nn(TypeRef::INT), move |ctx| {
44 let namespace = extract_namespace_from_parent_value(&ctx);
45 FieldFuture::new(async move {
46 let component_manager = ctx.data::<Arc<dyn ComponentManager + Send + Sync>>()?;
47 let count = match namespace {
48 ResolvedNamespace::Root => component_manager.count(),
49 ResolvedNamespace::Namespace(namespace) => component_manager.count_by_namespace(&namespace),
50 };
51 Ok(Some(FieldValue::value(count)))
52 })
53 }))
54 .field(Field::new("entityTypes", TypeRef::named_nn(TypeRef::INT), move |ctx| {
55 let namespace = extract_namespace_from_parent_value(&ctx);
56 FieldFuture::new(async move {
57 let entity_type_manager = ctx.data::<Arc<dyn EntityTypeManager + Send + Sync>>()?;
58 let count = match namespace {
59 ResolvedNamespace::Root => entity_type_manager.count(),
60 ResolvedNamespace::Namespace(namespace) => entity_type_manager.count_by_namespace(&namespace),
61 };
62 Ok(Some(FieldValue::value(count)))
63 })
64 }))
65 .field(Field::new("relationTypes", TypeRef::named_nn(TypeRef::INT), move |ctx| {
66 let namespace = extract_namespace_from_parent_value(&ctx);
67 FieldFuture::new(async move {
68 let relation_type_manager = ctx.data::<Arc<dyn RelationTypeManager + Send + Sync>>()?;
69 let count = match namespace {
70 ResolvedNamespace::Root => relation_type_manager.count(),
71 ResolvedNamespace::Namespace(namespace) => relation_type_manager.count_by_namespace(&namespace),
72 };
73 Ok(Some(FieldValue::value(count)))
74 })
75 }))
76 .field(Field::new("flowTypes", TypeRef::named_nn(TypeRef::INT), move |ctx| {
77 let namespace = extract_namespace_from_parent_value(&ctx);
78 FieldFuture::new(async move {
79 let flow_type_manager = ctx.data::<Arc<dyn FlowTypeManager + Send + Sync>>()?;
80 let count = match namespace {
81 ResolvedNamespace::Root => flow_type_manager.count(),
82 ResolvedNamespace::Namespace(namespace) => flow_type_manager.count_by_namespace(&namespace),
83 };
84 Ok(Some(FieldValue::value(count)))
85 })
86 }))
87}
88
89pub fn metrics_field(namespace: Option<String>) -> Field {
90 let namespace = namespace.clone().unwrap_or("root".to_string());
91 Field::new("_metrics", metrics_type_name(), move |_ctx| {
92 let namespace = namespace.clone();
93 FieldFuture::new(async move { Ok(Some(FieldValue::value(namespace))) })
94 })
95}
96
97fn extract_namespace_from_parent_value(ctx: &ResolverContext) -> ResolvedNamespace {
98 ctx.parent_value
99 .as_value()
100 .and_then(|v| v.clone().into_json().ok().and_then(|value| value.as_str().map(|s| s.to_owned())))
101 .into()
102}