Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performances of batch pathfinding and simulation 🚀 #7995

Merged
merged 2 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions editoast/src/core/v2/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub struct SimulationPath {
pub track_section_ranges: Vec<TrackRange>,
}

#[derive(Deserialize, Serialize, Clone, Debug, ToSchema)]
#[derive(Deserialize, Default, Serialize, Clone, Debug, ToSchema)]
#[schema(as = ReportTrainV2)]
pub struct ReportTrain {
/// List of positions of a train
Expand All @@ -152,7 +152,7 @@ pub struct ReportTrain {
pub scheduled_points_honored: bool,
}

#[derive(Deserialize, Serialize, Clone, Debug, ToSchema)]
#[derive(Deserialize, Default, Serialize, Clone, Debug, ToSchema)]
pub struct CompleteReportTrain {
#[serde(flatten)]
#[schema(value_type = ReportTrainV2)]
Expand Down Expand Up @@ -200,7 +200,7 @@ pub struct RoutingZoneRequirement {
pub end_time: u64,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
pub struct ElectricalProfiles {
/// List of `n` boundaries of the ranges.
/// A boundary is a distance from the beginning of the path in mm.
Expand Down Expand Up @@ -279,6 +279,18 @@ pub enum SimulationResponse {
},
}

impl Default for SimulationResponse {
fn default() -> Self {
Self::Success {
base: Default::default(),
provisional: Default::default(),
final_output: Default::default(),
mrsp: Default::default(),
electrical_profiles: Default::default(),
}
}
}

impl AsCoreRequest<Json<SimulationResponse>> for SimulationRequest {
const METHOD: reqwest::Method = reqwest::Method::POST;
const URL_PATH: &'static str = "/v2/standalone_simulation";
Expand Down
67 changes: 4 additions & 63 deletions editoast/src/redis_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use redis::cluster_async::ClusterConnection;
use redis::AsyncCommands;
use redis::Client;
use redis::ErrorKind;
use redis::Expiry;
use redis::RedisError;
use redis::RedisFuture;
use redis::RedisResult;
Expand Down Expand Up @@ -60,7 +59,7 @@ impl ConnectionLike for RedisConnection {

impl RedisConnection {
/// Get a deserializable value from redis
#[tracing::instrument(name = "cache:get", skip(self), err)]
#[tracing::instrument(name = "cache:json_get", skip(self), err)]
pub async fn json_get<T: DeserializeOwned, K: Debug + ToRedisArgs + Send + Sync>(
&mut self,
key: K,
Expand Down Expand Up @@ -102,32 +101,12 @@ impl RedisConnection {
.collect()
}

/// Get a deserializable value from redis with expiry time
#[tracing::instrument(name = "cache:get_with_expiration", skip(self), err)]
pub async fn json_get_ex<T: DeserializeOwned, K: Debug + ToRedisArgs + Send + Sync>(
&mut self,
key: K,
seconds: u64,
) -> Result<Option<T>> {
let value: Option<String> = self.get_ex(key, Expiry::EX(seconds as usize)).await?;
match value {
Some(v) => match serde_json::from_str(&v) {
Ok(value) => Ok(value),
Err(_) => {
Err(RedisError::from((ErrorKind::TypeError, "Expected valid json")).into())
}
},
None => Ok(None),
}
}

/// Set a serializable value to redis with expiry time
#[tracing::instrument(name = "cache:set_with_expiration", skip(self, value), err)]
pub async fn json_set_ex<K: Debug + ToRedisArgs + Send + Sync, T: Serialize>(
#[tracing::instrument(name = "cache:json_set", skip(self, value), err)]
pub async fn json_set<K: Debug + ToRedisArgs + Send + Sync, T: Serialize>(
&mut self,
key: K,
value: &T,
seconds: u64,
) -> Result<()> {
let str_value = match serde_json::to_string(value) {
Ok(value) => value,
Expand All @@ -139,7 +118,7 @@ impl RedisConnection {
.into())
}
};
self.set_ex(key, str_value, seconds).await?;
self.set(key, str_value).await?;
Ok(())
}

Expand Down Expand Up @@ -209,41 +188,3 @@ impl RedisClient {
}
}
}

#[cfg(test)]
mod tests {
use super::RedisClient;
use rstest::rstest;
use serde::{Deserialize, Serialize};
use tokio::time::{sleep, Duration};

/// Test get and set json values to redis
#[rstest]
async fn json_get_set() {
flomonster marked this conversation as resolved.
Show resolved Hide resolved
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestStruct {
name: String,
age: u8,
}

let redis_client = RedisClient::new(Default::default()).unwrap();
let mut redis = redis_client.get_connection().await.unwrap();

let key = "__test__.json_get_set";
let test_struct = TestStruct {
name: "John".to_string(),
age: 25,
};

redis.json_set_ex(key, &test_struct, 60).await.unwrap();
let value: TestStruct = redis.json_get_ex(key, 2).await.unwrap().unwrap();
assert_eq!(value, test_struct);

// Wait for 5 seconds
sleep(Duration::from_secs(3)).await;

// Check if the value has expired
let value = redis.json_get::<TestStruct, _>(key).await.unwrap();
assert_eq!(value, None);
}
}
6 changes: 1 addition & 5 deletions editoast/src/views/v2/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod pathfinding;
pub mod projection;
mod properties;

pub use pathfinding::pathfinding_from_train;
pub use pathfinding::pathfinding_from_train_batch;

use editoast_derive::EditoastError;
use thiserror::Error;
Expand All @@ -13,10 +13,6 @@ use crate::modelsv2::prelude::*;
use crate::modelsv2::Infra;
use editoast_models::DbConnection;

/// Expiration time for the cache of the pathfinding and path properties.
/// Note: 604800 seconds = 1 week
const CACHE_PATH_EXPIRATION: u64 = 604800;

crate::routes! {
properties::routes(),
pathfinding::routes(),
Expand Down
Loading
Loading