From ea62918724c4cd8a9d52ad0048718e7aecfb2ee7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pascal=20Eng=C3=A9libert?= <tuxmain@zettascript.org>
Date: Fri, 8 Nov 2024 18:13:40 +0100
Subject: [PATCH] distance-oracle: sheduler

---
 Cargo.lock                  |  3 +--
 distance-oracle/Cargo.toml  |  7 ++-----
 distance-oracle/src/api.rs  |  2 +-
 distance-oracle/src/lib.rs  |  4 ++--
 distance-oracle/src/main.rs | 29 ++++++++++++++++++++---------
 distance-oracle/src/mock.rs |  2 +-
 node/Cargo.toml             | 30 +++++++++++++++++++++---------
 node/src/cli.rs             |  2 ++
 node/src/command.rs         | 25 +++++++++++++++++--------
 9 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index d0f9a4833..c42c76d6a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2100,9 +2100,7 @@ dependencies = [
  "dubp-wot",
  "flate2",
  "fnv",
- "hex",
  "log",
- "num-traits 0.2.19",
  "parity-scale-codec",
  "rayon",
  "simple_logger",
@@ -2254,6 +2252,7 @@ dependencies = [
  "sp-trie",
  "substrate-build-script-utils",
  "substrate-frame-rpc-system",
+ "tokio",
 ]
 
 [[package]]
diff --git a/distance-oracle/Cargo.toml b/distance-oracle/Cargo.toml
index 3f7614e3e..60869ed6f 100644
--- a/distance-oracle/Cargo.toml
+++ b/distance-oracle/Cargo.toml
@@ -12,13 +12,12 @@ required-features = ["standalone"]
 
 [features]
 default = ["standalone", "std"]
+# Feature standalone is for CLI executable
 standalone = ["clap", "tokio"]
+# Feature std is needed
 std = [
 	"codec/std",
 	"fnv/std",
-	"hex/std",
-	"log/std",
-	"num-traits/std",
 	"sp-core/std",
 	"sp-distance/std",
 	"sp-runtime/std",
@@ -30,9 +29,7 @@ runtime-benchmarks = []
 clap = { workspace = true, features = ["derive"], optional = true }
 codec = { workspace = true }
 fnv = { workspace = true }
-hex = { workspace = true }
 log = { workspace = true }
-num-traits = { workspace = true }
 rayon = { workspace = true }
 simple_logger = { workspace = true }
 sp-core = { workspace = true }
diff --git a/distance-oracle/src/api.rs b/distance-oracle/src/api.rs
index 99e6b6f51..abb6e96b8 100644
--- a/distance-oracle/src/api.rs
+++ b/distance-oracle/src/api.rs
@@ -25,7 +25,7 @@ pub type Client = subxt::OnlineClient<crate::RuntimeConfig>;
 pub type AccountId = subxt::utils::AccountId32;
 pub type IdtyIndex = u32;
 
-pub async fn client(rpc_url: String) -> Client {
+pub async fn client(rpc_url: impl AsRef<str>) -> Client {
     Client::from_insecure_url(rpc_url)
         .await
         .expect("Cannot create RPC client")
diff --git a/distance-oracle/src/lib.rs b/distance-oracle/src/lib.rs
index 965ed8b20..895b5491d 100644
--- a/distance-oracle/src/lib.rs
+++ b/distance-oracle/src/lib.rs
@@ -84,9 +84,9 @@ impl Default for Settings {
 }
 
 /// Asynchronously runs a computation using the provided client and saves the result to a file.
-pub async fn run_and_save(client: &api::Client, settings: Settings) {
+pub async fn run_and_save(client: &api::Client, settings: &Settings) {
     let Some((evaluation, current_pool_index, evaluation_result_path)) =
-        run(client, &settings, true).await
+        run(client, settings, true).await
     else {
         return;
     };
diff --git a/distance-oracle/src/main.rs b/distance-oracle/src/main.rs
index 9e3644a8b..5da3aea14 100644
--- a/distance-oracle/src/main.rs
+++ b/distance-oracle/src/main.rs
@@ -1,4 +1,4 @@
-// Copyright 2023 Axiom-Team
+// Copyright 2023-2024 Axiom-Team
 //
 // This file is part of Duniter-v2S.
 //
@@ -20,6 +20,8 @@ use clap::Parser;
 struct Cli {
     #[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")]
     evaluation_result_dir: String,
+    #[clap(short = 'i', long, default_value = "None")]
+    interval: Option<u64>,
     #[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")]
     rpc_url: String,
     /// Log level (off, error, warn, info, debug, trace)
@@ -36,12 +38,21 @@ async fn main() {
         .init()
         .unwrap();
 
-    distance_oracle::run_and_save(
-        &distance_oracle::api::client(cli.rpc_url.clone()).await,
-        distance_oracle::Settings {
-            evaluation_result_dir: cli.evaluation_result_dir.into(),
-            rpc_url: cli.rpc_url,
-        },
-    )
-    .await;
+    let client = distance_oracle::api::client(&cli.rpc_url).await;
+
+    let settings = distance_oracle::Settings {
+        evaluation_result_dir: cli.evaluation_result_dir.into(),
+        rpc_url: cli.rpc_url,
+    };
+
+    if let Some(duration) = cli.interval {
+        let mut interval = tokio::time::interval(std::time::Duration::from_secs(duration));
+        interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
+        loop {
+            distance_oracle::run_and_save(&client, &settings).await;
+            interval.tick().await;
+        }
+    } else {
+        distance_oracle::run_and_save(&client, &settings).await;
+    }
 }
diff --git a/distance-oracle/src/mock.rs b/distance-oracle/src/mock.rs
index b21f4e796..f5de146c6 100644
--- a/distance-oracle/src/mock.rs
+++ b/distance-oracle/src/mock.rs
@@ -34,7 +34,7 @@ pub struct EvaluationPool<AccountId: Ord, IdtyIndex> {
     pub evaluators: BTreeSet<AccountId>,
 }
 
-pub async fn client(_rpc_url: String) -> Client {
+pub async fn client(_rpc_url: impl AsRef<str>) -> Client {
     unimplemented!()
 }
 
diff --git a/node/Cargo.toml b/node/Cargo.toml
index 784c75437..7e853ef8b 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -48,7 +48,7 @@ runtime-benchmarks = [
 	"sp-runtime/runtime-benchmarks",
 ]
 try-runtime = [
-  "runtime-benchmarks",
+	"runtime-benchmarks",
 	"common-runtime/try-runtime",
 	"dc-distance?/try-runtime",
 	"distance-oracle?/try-runtime",
@@ -106,7 +106,7 @@ std = [
 	"sp-transaction-storage-proof/std",
 	"sp-trie/std",
 ]
-standalone = ["distance-oracle?/standalone"]
+distance-oracle = ["dep:distance-oracle"]
 
 [dependencies]
 async-io = { workspace = true }
@@ -125,6 +125,7 @@ num-format = { workspace = true }
 serde = { workspace = true }
 serde_json = { workspace = true }
 serde_yaml = { workspace = true }
+tokio = { workspace = true, features = ["rt-multi-thread"] }
 
 # Local
 common-runtime = { workspace = true }
@@ -184,7 +185,7 @@ sp-transaction-storage-proof = { workspace = true, default-features = true }
 substrate-frame-rpc-system = { workspace = true, default-features = true }
 
 [build-dependencies]
-substrate-build-script-utils = { workspace = true, default-features = true}
+substrate-build-script-utils = { workspace = true, default-features = true }
 
 # Dependencies for specific targets
 [target.'cfg(any(target_arch="x86_64", target_arch="aarch64"))'.dependencies]
@@ -194,9 +195,20 @@ sp-trie = { workspace = true, default-features = true }
 
 [package.metadata.deb]
 maintainer-scripts = "../resources/debian"
-systemd-units = [ { unit-name = "duniter-mirror", enable = false },
-                  { unit-name = "duniter-smith", enable = false },
-                  { unit-name = "distance-oracle", enable = false },
-                  ]
-assets = [ ["../resources/debian/env_file", "/etc/duniter/env_file", "0640"],
-           ["../target/release/duniter", "/usr/bin/duniter2", "755"]]
+systemd-units = [
+	{ unit-name = "duniter-mirror", enable = false },
+	{ unit-name = "duniter-smith", enable = false },
+	{ unit-name = "distance-oracle", enable = false },
+]
+assets = [
+	[
+		"../resources/debian/env_file",
+		"/etc/duniter/env_file",
+		"0640",
+	],
+	[
+		"../target/release/duniter",
+		"/usr/bin/duniter2",
+		"755",
+	],
+]
diff --git a/node/src/cli.rs b/node/src/cli.rs
index a494a8727..9abf8533b 100644
--- a/node/src/cli.rs
+++ b/node/src/cli.rs
@@ -133,6 +133,8 @@ pub struct Completion {
 pub struct DistanceOracle {
     #[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")]
     pub evaluation_result_dir: String,
+    #[clap(short = 'i', long, default_value = "None")]
+    pub interval: Option<u64>,
     #[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")]
     pub rpc_url: String,
 }
diff --git a/node/src/command.rs b/node/src/command.rs
index 29af19445..9aa124d91 100644
--- a/node/src/command.rs
+++ b/node/src/command.rs
@@ -285,14 +285,23 @@ pub fn run() -> sc_cli::Result<()> {
         }
         #[cfg(feature = "distance-oracle")]
         Some(Subcommand::DistanceOracle(cmd)) => sc_cli::build_runtime()?.block_on(async move {
-            distance_oracle::run_and_save(
-                &distance_oracle::api::client(cmd.rpc_url.clone()).await,
-                distance_oracle::Settings {
-                    evaluation_result_dir: cmd.evaluation_result_dir.clone().into(),
-                    rpc_url: cmd.rpc_url.clone(),
-                },
-            )
-            .await;
+            let client = distance_oracle::api::client(&cmd.rpc_url).await;
+
+            let settings = distance_oracle::Settings {
+                evaluation_result_dir: cmd.evaluation_result_dir.clone().into(),
+                rpc_url: cmd.rpc_url.clone(),
+            };
+
+            if let Some(duration) = cmd.interval {
+                let mut interval = tokio::time::interval(std::time::Duration::from_secs(duration));
+                interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
+                loop {
+                    distance_oracle::run_and_save(&client, &settings).await;
+                    interval.tick().await;
+                }
+            } else {
+                distance_oracle::run_and_save(&client, &settings).await;
+            }
             Ok(())
         }),
         #[cfg(feature = "runtime-benchmarks")]
-- 
GitLab