Skip to content

Commit

Permalink
refactor(gateway): allow stats to change in the future (#1463)
Browse files Browse the repository at this point in the history
This makes it possible for stats to change in the future by defaulting
to an empty vec if we ever fail to deserialize it.
  • Loading branch information
chesedo committed Dec 4, 2023
1 parent c0c4e14 commit 187acc5
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions gateway/src/project.rs
Expand Up @@ -22,7 +22,8 @@ use hyper::client::HttpConnector;
use hyper::{Body, Client};
use once_cell::sync::Lazy;
use rand::distributions::{Alphanumeric, DistString};
use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Deserializer, Serialize};
use shuttle_common::backends::headers::{X_SHUTTLE_ACCOUNT_NAME, X_SHUTTLE_ADMIN_SECRET};
use shuttle_common::constants::{default_idle_minutes, DEFAULT_IDLE_MINUTES};
use shuttle_common::models::project::ProjectName;
Expand Down Expand Up @@ -171,6 +172,18 @@ impl From<DockerError> for Error {
}
}

/// Allow some fields to default to their default value if deserializing them fails
/// https://users.rust-lang.org/t/solved-serde-deserialization-on-error-use-default-values/6681/2
fn ok_or_default<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: DeserializeOwned + Default,
D: Deserializer<'de>,
{
// Convert to `Value` first so that we capture the whole input in case it fails later on the specific type
let v: serde_json::Value = Deserialize::deserialize(deserializer)?;
Ok(T::deserialize(v).unwrap_or_default())
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Project {
Expand Down Expand Up @@ -1177,7 +1190,7 @@ pub struct ProjectStarted {
#[serde(default)]
start_count: usize,
// Use default for backward compatibility. Can be removed when all projects in the DB have this property set
#[serde(default)]
#[serde(default, deserialize_with = "ok_or_default")]
stats: VecDeque<Stats>,
}

Expand Down Expand Up @@ -1258,7 +1271,7 @@ pub struct ProjectReady {
container: ContainerInspectResponse,
service: Service,
// Use default for backward compatibility. Can be removed when all projects in the DB have this property set
#[serde(default)]
#[serde(default, deserialize_with = "ok_or_default")]
stats: VecDeque<Stats>,
}

Expand Down

0 comments on commit 187acc5

Please sign in to comment.