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 configurability #3

Merged
merged 3 commits into from
Aug 27, 2023
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
41 changes: 22 additions & 19 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::bookmarks::TargetBookmark;
use crate::{bookmarks::TargetBookmark, Config};
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::debug;
Expand All @@ -9,23 +9,19 @@ use std::{
};
use tokio::time::{self, Duration};

/// The request timeout in milliseconds.
const REQUEST_TIMEOUT: u64 = 60_000;

/// The throttling between requests in milliseconds.
const THROTTLING: u64 = 1_000;

pub struct Client {
client: ReqwestClient,
throttler: Option<Throttler>,
}

impl Client {
pub fn new() -> Result<Self, anyhow::Error> {
pub fn new(config: &Config) -> Result<Self, anyhow::Error> {
let request_timeout = config.settings.request_timeout;
let request_throttling = config.settings.request_throttling;
let client = ReqwestClient::builder()
.timeout(Duration::from_millis(REQUEST_TIMEOUT))
.timeout(Duration::from_millis(request_timeout))
.build()?;
let throttler = Some(Throttler::new());
let throttler = Some(Throttler::new(request_throttling));
Ok(Self { client, throttler })
}

Expand All @@ -46,12 +42,14 @@ impl Client {
#[derive(Debug)]
struct Throttler {
last_fetched: Mutex<HashMap<String, DateTime<Utc>>>,
request_throttling: u64,
}

impl Throttler {
pub fn new() -> Self {
pub fn new(request_throttling: u64) -> Self {
Self {
last_fetched: Mutex::new(HashMap::new()),
request_throttling,
}
}

Expand All @@ -63,15 +61,18 @@ impl Throttler {
if let Some(last_fetched) = self.last_fetched(bookmark, now)? {
let duration_since_last_fetched = now - last_fetched;

if duration_since_last_fetched < chrono::Duration::milliseconds(THROTTLING as i64 / 2) {
if duration_since_last_fetched
< chrono::Duration::milliseconds(self.request_throttling as i64 / 2)
{
debug!("Wait for bookmark {}", bookmark.url);
time::sleep(Duration::from_millis(THROTTLING)).await;
} else if chrono::Duration::milliseconds(THROTTLING as i64 / 2)
time::sleep(Duration::from_millis(self.request_throttling)).await;
} else if chrono::Duration::milliseconds(self.request_throttling as i64 / 2)
< duration_since_last_fetched
&& duration_since_last_fetched < chrono::Duration::milliseconds(THROTTLING as i64)
&& duration_since_last_fetched
< chrono::Duration::milliseconds(self.request_throttling as i64)
{
debug!("Wait for bookmark {}", bookmark.url);
time::sleep(Duration::from_millis(THROTTLING / 2)).await;
time::sleep(Duration::from_millis(self.request_throttling / 2)).await;
}
}

Expand Down Expand Up @@ -112,7 +113,8 @@ mod tests {
async fn test_throttle() {
tokio::time::pause();
let now = Utc::now();
let throttler = Throttler::new();
let request_throttling = 1000;
let throttler = Throttler::new(request_throttling);
let bookmark1 = TargetBookmark::new(
"https://en.wikipedia.org/wiki/Applicative_functor",
now,
Expand All @@ -132,14 +134,15 @@ mod tests {
throttler.throttle(&bookmark2).await.unwrap();
assert_eq!(
Instant::now().duration_since(start_instant).as_millis(),
(THROTTLING + 1) as u128
(request_throttling + 1) as u128
);
}

#[test]
fn test_last_fetched() {
let now = Utc::now();
let throttler = Throttler::new();
let request_throttling = 1000;
let throttler = Throttler::new(request_throttling);
let bookmark1 = TargetBookmark::new(
"https://en.wikipedia.org/wiki/Applicative_functor",
now,
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/configure.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{Config, ConfigArgs, SourceFile};
use log::info;
use log::{debug, info};
use std::path::PathBuf;

/// Configure the source files to import the bookmarks.
Expand All @@ -11,13 +11,15 @@ pub fn configure(mut config: Config, args: ConfigArgs) -> Result<(), anyhow::Err
let settings_path = config.settings_path;

if let Some(source) = args.set_source.source {
debug!("Set source");
let source = PathBuf::from(source);
let source_file = SourceFile::new(source, args.set_source.folders);
config.settings.source_bookmark_files.push(source_file);
config.settings.write(&settings_path)?;
}

if let Some(set_cache_mode) = args.set_cache_mode {
debug!("Set cache mode");
config.settings.cache_mode = set_cache_mode;
config.settings.write(&settings_path)?;
}
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::path::Path;
pub async fn fetch(config: &Config, args: &FetchArgs) -> Result<(), anyhow::Error> {
let mut bookmarks = TargetBookmarks::read(config)?;
let cache = Cache::init(config, &args.mode).await?;
let client = Client::new()?;
let client = Client::new(config)?;

if args.all {
fetch_and_replace_all(config, &client, &cache, &mut bookmarks).await?;
Expand Down Expand Up @@ -151,7 +151,7 @@ pub async fn fetch_diff(config: &Config, args: FetchArgs) -> Result<(), anyhow::
debug!("Diff content for urls: {:#?}", args.urls);
let target_bookmarks = TargetBookmarks::read(config)?;
let cache = Cache::new(&config.cache_path, &args.mode)?;
let client = Client::new()?;
let client = Client::new(config)?;

for url in args.urls {
let bookmark = target_bookmarks.find(&url);
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{Cache, Client, Config, InitArgs, TargetBookmarks};
pub async fn init(config: &Config, args: &InitArgs) -> Result<(), anyhow::Error> {
let bookmarks = TargetBookmarks::init(config)?;
let cache = Cache::init(config, &args.mode).await?;
let client = Client::new()?;
let client = Client::new(config)?;
fetch_and_add_all(config, &client, &cache, &bookmarks).await?;
Ok(())
}
2 changes: 1 addition & 1 deletion src/cmd/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use log::info;
/// new bookmarks; delete cache for removed bookmarks.
pub async fn update(config: &Config, args: &UpdateArgs) -> Result<(), anyhow::Error> {
let cache = Cache::new(&config.cache_path, &args.mode)?;
let client = Client::new()?;
let client = Client::new(config)?;

let mut source_bookmarks = SourceBookmarks::new();
source_bookmarks.read(config)?;
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use env_logger::{Builder, Env};
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Default to INFO level logs if RUST_LOG is not set.
Builder::from_env(Env::default().default_filter_or("info")).init();
Builder::from_env(Env::default().default_filter_or("bogrep=info")).init();

let args = Args::parse();
let config = Config::init(&args)?;
Expand Down
18 changes: 17 additions & 1 deletion src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ use std::{
path::{Path, PathBuf},
};

/// The maximal number of concurrent requests.
/// The default `Settungs::max_concurrent_requests`.
const MAX_CONCURRENT_REQUESTS_DEFAULT: usize = 100;

/// The default for `Settings::request_timeout`.
const REQUEST_TIMEOUT_DEFAULT: u64 = 60_000;

/// The default for `Settings::request_throttling`.
const REQUEST_THROTTLING_DEFAULT: u64 = 1_000;

#[derive(Debug, Serialize, Deserialize)]
pub struct Settings {
/// The paths to the configured bookmark files.
Expand All @@ -21,6 +27,10 @@ pub struct Settings {
pub cache_mode: CacheMode,
/// The maximal number of concurrent requests.
pub max_concurrent_requests: usize,
/// The request timeout in milliseconds.
pub request_timeout: u64,
/// The throttling between requests in milliseconds.
pub request_throttling: u64,
}

impl Default for Settings {
Expand All @@ -29,6 +39,8 @@ impl Default for Settings {
source_bookmark_files: Vec::new(),
cache_mode: CacheMode::default(),
max_concurrent_requests: MAX_CONCURRENT_REQUESTS_DEFAULT,
request_timeout: REQUEST_TIMEOUT_DEFAULT,
request_throttling: REQUEST_THROTTLING_DEFAULT,
}
}
}
Expand All @@ -38,11 +50,15 @@ impl Settings {
source_bookmark_files: Vec<SourceFile>,
cache_mode: CacheMode,
max_concurrent_requests: usize,
request_timeout: u64,
request_throttling: u64,
) -> Self {
Self {
source_bookmark_files,
cache_mode,
max_concurrent_requests,
request_timeout,
request_throttling,
}
}

Expand Down