Skip to content

Commit

Permalink
chrono feature and time utils, dlock internal extension management fo…
Browse files Browse the repository at this point in the history
…r arbitrary futures" (#38)

* Exporting redis from bb

* Namespace added to dlock

* New chrono feature for formatting and timing utilities, dlock contains new expires_at property

* dlock new hold_for_fut on lock and on wrapper dlock_for_fut to allow internalising the extension lock when running an arbitrary future that should be locked

* omit empty zrem from batch automatically
  • Loading branch information
zakstucke authored May 7, 2024
1 parent 3117ef2 commit e3d9bfe
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 58 deletions.
25 changes: 13 additions & 12 deletions .zetch.lock

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

2 changes: 1 addition & 1 deletion opencollector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ exporters:
stream-name: default
# Writes all opentelemetry logs, traces, metrics to a file, useful for testing:
file/debug_file_writing:
path: /home/runner/work/bitbazaar/bitbazaar/logs/otlp_telemetry_out.log
path: /Users/zak/z/code/bitbazaar/logs/otlp_telemetry_out.log
rotation:
max_megabytes: 10
max_days: 3
Expand Down
11 changes: 10 additions & 1 deletion rust/Cargo.lock

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

18 changes: 11 additions & 7 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@ all-features = true

[features]
log-filter = ["dep:regex"]
timing = ['dep:comfy-table', 'dep:chrono']
cli = ['dep:normpath', 'dep:conch-parser', 'dep:homedir', 'dep:chrono', 'dep:strum']
chrono = ['dep:chrono', 'dep:chrono-humanize']
timing = ['dep:comfy-table', 'chrono']
cli = ['dep:normpath', 'dep:conch-parser', 'dep:homedir', 'chrono', 'dep:strum']
redis = [
'dep:tokio',
'dep:deadpool-redis',
'dep:redis',
"dep:redis-macros",
'dep:sha1_smol',
'dep:serde_json',
'dep:rand',
'dep:futures',
'dep:futures-timer',
'dep:chrono',
'chrono',
'dep:uuid',
]
opentelemetry-grpc = [
Expand Down Expand Up @@ -73,13 +74,16 @@ time = { version = "0.3", features = ["local-offset"] }
colored = '2'

# Not in default, but randomly useful in features:
chrono = { version = '0.4', optional = true }
strum = { version = "0.25", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
rand = { version = "0.8", optional = true }
futures = { version = "0.3", optional = true }
futures-timer = { version = "3", optional = true }
uuid = { version = "1.6", features = ["v4"], optional = true }
tokio = { version = '1', optional = true }

# FEAT: chrono: (but also sometimes enabled by other features)
chrono = { version = '0.4', optional = true }
chrono-humanize = { version = "0.2", optional = true }

# FEAT: log-filter:
regex = { version = '1', optional = true }
Expand Down Expand Up @@ -125,7 +129,7 @@ hostname = "0.3.1"
rstest = "0.18"
portpicker = '0.1.1'
tempfile = '3.8'
tokio = { version = '1.35', features = ["rt-multi-thread", "macros"] }
tokio = { version = '1', features = ["rt-multi-thread", "macros"] }
uuid = { version = "1.6", features = ["v4"] }
regex = "1"
serde_json = "1"
Expand Down
52 changes: 52 additions & 0 deletions rust/bitbazaar/chrono/chrono_formatting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/// Formats a [`chrono::Duration`]` in the present case.
/// Arguments:
/// - `td`: The duration to format.
/// - `precise`: If true, smaller units will be included.
pub fn chrono_format_td(td: chrono::Duration, precise: bool) -> String {
// The rough formatting does some funkiness with "now" when less than 10 seconds, so just handle simple seconds case manually:
if !precise && td.num_seconds() <= 59 {
let secs = td.num_seconds().max(1);
format!("{} second{}", secs, if secs > 1 { "s" } else { "" })
} else {
chrono_humanize::HumanTime::from(td).to_text_en(
if precise {
chrono_humanize::Accuracy::Precise
} else {
chrono_humanize::Accuracy::Rough
},
chrono_humanize::Tense::Present,
)
}
}

/// Convert a chrono datetime to the local timezone.
///
/// Arguments:
/// - `dt`: The datetime to convert.
pub fn chrono_dt_to_local(dt: chrono::DateTime<chrono::Utc>) -> chrono::DateTime<chrono::Local> {
dt.with_timezone(&chrono::Local)
}

/// Formats a [`chrono::DateTime`], also localising it to the user's timezone.
///
/// Arguments:
/// - `dt`: The datetime to format.
pub fn chrono_format_dt(dt: chrono::DateTime<chrono::Utc>) -> String {
let dt = chrono_dt_to_local(dt);

let date = dt.date_naive();
let today = chrono::Local::now().date_naive();
let yesterday = today.pred_opt();

// If today then: "Today, 12:34"
if date == today {
format!("Today, {}", dt.format("%H:%M"))
}
// Same for yesterday:
else if yesterday.is_some() && date == yesterday.unwrap() {
format!("Yesterday, {}", dt.format("%H:%M"))
} else {
// Otherwise e.g. 15 March 2021, 12:34
dt.format("%-e %B %Y, %H:%M").to_string()
}
}
3 changes: 3 additions & 0 deletions rust/bitbazaar/chrono/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod chrono_formatting;

pub use chrono_formatting::*;
3 changes: 3 additions & 0 deletions rust/bitbazaar/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ mod prelude;
/// Command line interface utilities.
pub mod cli;

#[cfg(feature = "chrono")]
/// Chrono utilities
pub mod chrono;
/// Error handling utilities.
pub mod errors;
/// Hashing utilities.
Expand Down
7 changes: 6 additions & 1 deletion rust/bitbazaar/redis/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,15 @@ impl<'a, 'b, 'c, ReturnType> RedisBatch<'a, 'b, 'c, ReturnType> {
set_key: &str,
values: impl IntoIterator<Item = T>,
) -> Self {
let members = values.into_iter().collect::<Vec<_>>();
// No-op if no members so skip (redis would actually error if empty anyway)
if members.is_empty() {
return self;
}
self.pipe
.zrem(
self.redis_conn.final_key(set_namespace, set_key.into()),
values.into_iter().collect::<Vec<_>>(),
members,
)
// Ignoring so it doesn't take up a space in the tuple response.
.ignore();
Expand Down
Loading

0 comments on commit e3d9bfe

Please sign in to comment.