Skip to content

Commit

Permalink
Refactor providers to have the HTTP client injected (#11)
Browse files Browse the repository at this point in the history
Instead of adapters creating their own HTTP client, create the clients when assembling tasks from the config.
  • Loading branch information
lstrojny authored Jan 12, 2023
1 parent f00c587 commit a3ec6e2
Show file tree
Hide file tree
Showing 11 changed files with 42 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use figment::{
Figment,
};
use log::{debug, info, warn, Level};
use reqwest::blocking::Client;
use rocket::config::Ident;
use rocket::figment::providers::Serialized;
use rocket::serde::Serialize;
Expand Down Expand Up @@ -103,6 +104,7 @@ pub type ProviderTasks = Vec<Task>;
pub struct Task {
pub provider: Arc<dyn WeatherProvider + Send + Sync>,
pub request: WeatherRequest<Coordinates>,
pub client: Client,
pub cache: HttpRequestBodyCache,
}

Expand Down Expand Up @@ -136,6 +138,7 @@ pub fn get_provider_tasks(config: Config) -> anyhow::Result<ProviderTasks> {
name: location.name.unwrap_or(name),
query: location.coordinates,
},
client: Client::new(),
cache: cache.clone(),
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ async fn serve_metrics(unscheduled_tasks: &State<ProviderTasks>) -> (Status, Str
task.provider.id(),
task.request.query,
);
task.provider.for_coordinates(&task.cache, &task.request)
task.provider
.for_coordinates(&task.client, &task.cache, &task.request)
}));
}

Expand Down
18 changes: 13 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use log::error;
use rocket::{launch, routes};
use std::path::PathBuf;
use std::process::exit;
use tokio::task;

mod config;
mod http;
Expand Down Expand Up @@ -49,7 +50,7 @@ struct Args {
}

#[launch]
fn rocket() -> _ {
async fn rocket() -> _ {
let args = Args::parse();

let log_level = args
Expand All @@ -64,10 +65,17 @@ fn rocket() -> _ {
exit(1);
});

let tasks = get_provider_tasks(config.clone()).unwrap_or_else(|e| {
error!("Fatal error: {e}");
exit(1);
});
let config_clone = config.clone();
let tasks = task::spawn_blocking(move || get_provider_tasks(config_clone))
.await
.unwrap_or_else(|e| {
error!("Fatal error: {e}");
exit(1);
})
.unwrap_or_else(|e| {
error!("Fatal error: {e}");
exit(1);
});

rocket::custom(config.http)
.manage(tasks)
Expand Down
6 changes: 3 additions & 3 deletions src/providers/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn reqwest_cached_body_json<T: DeserializeOwned + std::fmt::Debug>(
cache: &HttpRequestBodyCache,
client: &Client,
method: Method,
url: Url,
url: &Url,
charset: Option<&str>,
) -> anyhow::Result<T> {
let body = reqwest_cached_body(source, cache, client, method, url, charset)?;
Expand All @@ -44,7 +44,7 @@ pub fn reqwest_cached_body(
cache: &HttpRequestBodyCache,
client: &Client,
method: Method,
url: Url,
url: &Url,
charset: Option<&str>,
) -> anyhow::Result<String> {
let key = (method.clone(), url.clone());
Expand All @@ -66,7 +66,7 @@ pub fn reqwest_cached_body(
debug!("No cache item found for \"{method:#} {url:#}\". Requesting");

let body = client
.request(method, url)
.request(method, url.clone())
.send()?
.text_with_charset(charset.unwrap_or("utf-8"))?;
cache.insert(key, body.clone());
Expand Down
9 changes: 4 additions & 5 deletions src/providers/deutscher_wetterdienst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,25 +212,24 @@ impl WeatherProvider for DeutscherWetterdienst {

fn for_coordinates(
&self,
client: &Client,
cache: &HttpRequestBodyCache,
request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather> {
let client = Client::new();

let station_csv = reqwest_cached_body(
SOURCE_URI,
cache,
&client,
client,
Method::GET,
Url::parse(STATION_LIST_URL)?,
&Url::parse(STATION_LIST_URL)?,
Some("iso-8859-15"),
)?;

let stations = parse_weather_station_list_csv(&station_csv);
let closest_station = find_closest_weather_station(&request.query, &stations)?;
trace!("Found closest weather station {:?}", closest_station);
let measurement_csv =
reqwest_cached_measurement_csv(cache, &client, &closest_station.station_id)?;
reqwest_cached_measurement_csv(cache, client, &closest_station.station_id)?;
let measurements = parse_measurement_data_csv(&measurement_csv);
let latest_measurement = measurements.last().expect("Taking last measurement info");

Expand Down
7 changes: 4 additions & 3 deletions src/providers/meteoblue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::providers::units::{Celsius, Coordinates};
use crate::providers::{HttpRequestBodyCache, Weather, WeatherProvider, WeatherRequest};
use anyhow::Context;
use hmac::{Hmac, Mac};
use reqwest::blocking::Client;
use reqwest::{Method, Url};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
Expand Down Expand Up @@ -45,6 +46,7 @@ impl WeatherProvider for Meteoblue {

fn for_coordinates(
&self,
client: &Client,
cache: &HttpRequestBodyCache,
request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather> {
Expand Down Expand Up @@ -73,13 +75,12 @@ impl WeatherProvider for Meteoblue {

let signed_url = Url::parse_with_params(url.as_str(), &[("sig", sig)])?;

let client = reqwest::blocking::Client::new();
let response: MeteoblueResponse = reqwest_cached_body_json::<MeteoblueResponse>(
SOURCE_URI,
cache,
&client,
client,
Method::GET,
signed_url,
&signed_url,
None,
)?;

Expand Down
2 changes: 2 additions & 0 deletions src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::providers::nogoodnik::Nogoodnik;
use crate::providers::open_weather::OpenWeather;
use crate::providers::tomorrow::Tomorrow;
use crate::providers::units::{Celsius, Ratio};
use reqwest::blocking::Client;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::Duration;
Expand Down Expand Up @@ -79,6 +80,7 @@ pub trait WeatherProvider: std::fmt::Debug {

fn for_coordinates(
&self,
client: &Client,
cache: &HttpRequestBodyCache,
request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather>;
Expand Down
2 changes: 2 additions & 0 deletions src/providers/nogoodnik.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::providers::units::Coordinates;
use crate::providers::HttpRequestBodyCache;
use crate::providers::{Weather, WeatherProvider, WeatherRequest};
use anyhow::format_err;
use reqwest::blocking::Client;
use rocket::serde::Serialize;
use serde::Deserialize;
use std::time::Duration;
Expand All @@ -18,6 +19,7 @@ impl WeatherProvider for Nogoodnik {

fn for_coordinates(
&self,
_client: &Client,
_cache: &HttpRequestBodyCache,
_request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather> {
Expand Down
8 changes: 4 additions & 4 deletions src/providers/open_weather.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::providers::cache::{reqwest_cached_body_json, Configuration};
use crate::providers::units::{Coordinates, Kelvin, Ratio, ToCelsius};
use crate::providers::{HttpRequestBodyCache, Weather, WeatherProvider, WeatherRequest};
use reqwest::blocking::Client;
use reqwest::{Method, Url};
use rocket::serde::Deserialize;
use serde::Serialize;
Expand Down Expand Up @@ -37,6 +38,7 @@ impl WeatherProvider for OpenWeather {

fn for_coordinates(
&self,
client: &Client,
cache: &HttpRequestBodyCache,
request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather> {
Expand All @@ -49,14 +51,12 @@ impl WeatherProvider for OpenWeather {
],
)?;

let client = reqwest::blocking::Client::new();

let response = reqwest_cached_body_json::<OpenWeatherResponse>(
SOURCE_URI,
cache,
&client,
client,
Method::GET,
url,
&url,
None,
)?;

Expand Down
8 changes: 4 additions & 4 deletions src/providers/tomorrow.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::providers::cache::{reqwest_cached_body_json, Configuration};
use crate::providers::units::{Celsius, Coordinates, Ratio};
use crate::providers::{HttpRequestBodyCache, Weather, WeatherProvider, WeatherRequest};
use reqwest::blocking::Client;
use reqwest::{Method, Url};
use serde::{Deserialize, Serialize};
use std::time::Duration;
Expand Down Expand Up @@ -48,6 +49,7 @@ impl WeatherProvider for Tomorrow {

fn for_coordinates(
&self,
client: &Client,
cache: &HttpRequestBodyCache,
request: &WeatherRequest<Coordinates>,
) -> anyhow::Result<Weather> {
Expand All @@ -67,14 +69,12 @@ impl WeatherProvider for Tomorrow {
],
)?;

let client = reqwest::blocking::Client::new();

let response = reqwest_cached_body_json::<TomorrowResponse>(
SOURCE_URI,
cache,
&client,
client,
Method::GET,
url,
&url,
None,
)?;

Expand Down

0 comments on commit a3ec6e2

Please sign in to comment.