summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorMatthieuCoder <matthieu@matthieu-dev.xyz>2023-01-02 18:59:03 +0400
committerMatthieuCoder <matthieu@matthieu-dev.xyz>2023-01-02 18:59:03 +0400
commitf8c2a144e2f3e47371f5e8352e7a7a0b6707bf88 (patch)
tree8c1e6bd157ac599429c806f9aa9bc9dbc28140ed /libs
parent46fd26962ef55f8b557f7e36d3aee915a819c88c (diff)
restructure project
Diffstat (limited to 'libs')
-rw-r--r--libs/leash/Cargo.toml13
-rw-r--r--libs/leash/src/lib.rs70
-rw-r--r--libs/proto/Cargo.toml6
-rw-r--r--libs/proto/build.rs11
-rw-r--r--libs/proto/src/lib.rs1
-rw-r--r--libs/shared/Cargo.toml1
-rw-r--r--libs/shared/src/config.rs37
-rw-r--r--libs/shared/src/nats.rs15
-rw-r--r--libs/shared/src/redis.rs19
9 files changed, 137 insertions, 36 deletions
diff --git a/libs/leash/Cargo.toml b/libs/leash/Cargo.toml
new file mode 100644
index 0000000..5cd54a5
--- /dev/null
+++ b/libs/leash/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "leash"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+shared = { path = "../shared" }
+anyhow = "1.0.68"
+tokio = { version = "1.23.0", features = ["full"] }
+
+serde = "1.0.152" \ No newline at end of file
diff --git a/libs/leash/src/lib.rs b/libs/leash/src/lib.rs
new file mode 100644
index 0000000..360db12
--- /dev/null
+++ b/libs/leash/src/lib.rs
@@ -0,0 +1,70 @@
+use anyhow::Result;
+use serde::de::DeserializeOwned;
+use shared::config::Settings;
+use std::{future::Future, pin::Pin};
+
+pub type AnyhowResultFuture<T> = Pin<Box<dyn Future<Output = Result<T>>>>;
+pub trait Component: Send + Sync + 'static + Sized {
+ type Config: Default + Clone + DeserializeOwned;
+
+ const SERVICE_NAME: &'static str;
+ fn start(&self, settings: Settings<Self::Config>) -> AnyhowResultFuture<()>;
+ fn new() -> Self;
+
+ fn _internal_start(self) -> AnyhowResultFuture<()> {
+ Box::pin(async move {
+ let settings = Settings::<Self::Config>::new(Self::SERVICE_NAME);
+
+ // Start the grpc healthcheck
+ tokio::spawn(async move {});
+
+ // Start the prometheus monitoring job
+ tokio::spawn(async move {});
+
+ self.start(settings?).await
+ })
+ }
+}
+
+#[macro_export]
+macro_rules! ignite {
+ ($c:ty) => {
+ #[allow(dead_code)]
+ fn main() -> anyhow::Result<()> {
+ let rt = tokio::runtime::Runtime::new()?;
+ rt.block_on(Box::new(<$c as Component>::new())._internal_start())?;
+ Ok(())
+ }
+ };
+}
+
+#[cfg(test)]
+mod test {
+ use serde::Deserialize;
+
+ use crate::Component;
+
+ #[derive(Clone, Copy)]
+ struct TestComponent {}
+
+ #[derive(Default, Clone, Deserialize, Copy)]
+ struct TestComponentConfig {}
+
+ impl Component for TestComponent {
+ type Config = TestComponentConfig;
+ const SERVICE_NAME: &'static str = "test_component";
+
+ fn start(
+ &self,
+ _settings: shared::config::Settings<Self::Config>,
+ ) -> crate::AnyhowResultFuture<()> {
+ Box::pin(async move { Ok(()) })
+ }
+
+ fn new() -> Self {
+ Self {}
+ }
+ }
+
+ ignite!(TestComponent);
+}
diff --git a/libs/proto/Cargo.toml b/libs/proto/Cargo.toml
index c4f2f2a..2556dfe 100644
--- a/libs/proto/Cargo.toml
+++ b/libs/proto/Cargo.toml
@@ -4,3 +4,9 @@ version = "0.1.0"
edition = "2018"
[dependencies]
+tonic = "0.8.3"
+prost = "0.11.5"
+
+[build-dependencies]
+tonic-build = "0.8.4"
+glob = "0.3.0" \ No newline at end of file
diff --git a/libs/proto/build.rs b/libs/proto/build.rs
new file mode 100644
index 0000000..80c3a55
--- /dev/null
+++ b/libs/proto/build.rs
@@ -0,0 +1,11 @@
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let paths: Vec<String> = glob::glob("../../proto/nova/**/*.proto")?
+ .map(|f| f.unwrap().to_str().unwrap().to_string())
+ .collect();
+
+ tonic_build::configure()
+ .include_file("genproto.rs")
+ .compile(&paths, &["../../proto"])?;
+
+ Ok(())
+}
diff --git a/libs/proto/src/lib.rs b/libs/proto/src/lib.rs
index e69de29..01dc7bc 100644
--- a/libs/proto/src/lib.rs
+++ b/libs/proto/src/lib.rs
@@ -0,0 +1 @@
+include!(concat!(env!("OUT_DIR"), concat!("/", "genproto.rs")));
diff --git a/libs/shared/Cargo.toml b/libs/shared/Cargo.toml
index 6d6b6f6..ab19ce8 100644
--- a/libs/shared/Cargo.toml
+++ b/libs/shared/Cargo.toml
@@ -19,6 +19,7 @@ twilight-model = "0.14"
serde_json = { version = "1.0" }
thiserror = "1.0.38"
inner = "0.1.1"
+anyhow = "1.0.68"
[dependencies.redis]
version = "*"
diff --git a/libs/shared/src/config.rs b/libs/shared/src/config.rs
index 52137a3..4387dfb 100644
--- a/libs/shared/src/config.rs
+++ b/libs/shared/src/config.rs
@@ -1,17 +1,11 @@
-use std::env;
+use std::{env, ops::Deref};
use config::{Config, Environment, File};
use log::info;
-use serde::Deserialize;
+use serde::{Deserialize, de::DeserializeOwned};
use crate::error::GenericError;
-
-/// Settings<T> is the base structure for all the nova's component config
-/// you can specify a type T and the name of the component. the "config"
-/// field will be equals to the key named after the given component name
-/// and will be of type T
#[derive(Debug, Deserialize, Clone)]
-#[serde(bound(deserialize = "T: Deserialize<'de> + std::default::Default + Clone"))]
-pub struct Settings<T> {
+pub struct Settings<T: Clone + DeserializeOwned + Default> {
#[serde(skip_deserializing)]
pub config: T,
pub monitoring: crate::monitoring::MonitoringConfiguration,
@@ -19,20 +13,11 @@ pub struct Settings<T> {
pub redis: crate::redis::RedisConfiguration,
}
-///
-impl<T> Settings<T>
-where
- T: Deserialize<'static> + std::default::Default + Clone,
+impl<'de, T: Clone + DeserializeOwned + Default> Settings<T>
{
-
- /// Initializes a new configuration like the other components of nova
- /// And starts the prometheus metrics server if needed.
pub fn new(service_name: &str) -> Result<Settings<T>, GenericError> {
- pretty_env_logger::init();
-
let mut builder = Config::builder();
- // this file my be shared with all the components
builder = builder.add_source(File::with_name("config/default"));
let mode = env::var("ENV").unwrap_or_else(|_| "development".into());
info!("Configuration Environment: {}", mode);
@@ -49,13 +34,15 @@ where
// try to load the config
settings.config = config.get::<T>(service_name)?;
-
- // start the monitoring system if needed
- crate::monitoring::start_monitoring(&settings.monitoring);
+
Ok(settings)
}
}
-pub fn test_init() {
- pretty_env_logger::init();
-}
+impl<T: Clone + DeserializeOwned + Default> Deref for Settings<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.config
+ }
+} \ No newline at end of file
diff --git a/libs/shared/src/nats.rs b/libs/shared/src/nats.rs
index 05953cc..dc922d5 100644
--- a/libs/shared/src/nats.rs
+++ b/libs/shared/src/nats.rs
@@ -1,8 +1,7 @@
+use std::{future::Future, pin::Pin};
+
use async_nats::Client;
use serde::Deserialize;
-use std::future::Future;
-
-use crate::error::GenericError;
#[derive(Clone, Debug, Deserialize)]
pub struct NatsConfigurationClientCert {
@@ -20,10 +19,8 @@ pub struct NatsConfiguration {
pub host: String,
}
-// todo: Prefer From since it automatically gives a free Into implementation
-// Allows the configuration to directly create a nats connection
-impl NatsConfiguration {
- pub async fn to_client(self) -> Result<Client, GenericError> {
- Ok(async_nats::connect(self.host).await?)
+impl From<NatsConfiguration> for Pin<Box<dyn Future<Output = anyhow::Result<Client>>>> {
+ fn from(value: NatsConfiguration) -> Self {
+ Box::pin(async move { Ok(async_nats::connect(value.host).await?) })
}
-} \ No newline at end of file
+}
diff --git a/libs/shared/src/redis.rs b/libs/shared/src/redis.rs
index a196f8d..5753fb6 100644
--- a/libs/shared/src/redis.rs
+++ b/libs/shared/src/redis.rs
@@ -1,6 +1,6 @@
-use redis::Client;
+use redis::{aio::MultiplexedConnection, Client};
use serde::Deserialize;
-
+use std::{future::Future, pin::Pin};
#[derive(Clone, Debug, Deserialize)]
pub struct RedisConfiguration {
@@ -13,3 +13,18 @@ impl Into<Client> for RedisConfiguration {
redis::Client::open(self.url).unwrap()
}
}
+
+impl From<RedisConfiguration>
+ for Pin<Box<dyn Future<Output = anyhow::Result<MultiplexedConnection>>>>
+{
+ fn from(value: RedisConfiguration) -> Self {
+ Box::pin(async move {
+ let con = Client::open(value.url)?;
+ let (multiplex, ready) = con.create_multiplexed_tokio_connection().await?;
+
+ tokio::spawn(ready);
+
+ Ok(multiplex)
+ })
+ }
+}