Skip to content
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
10 changes: 5 additions & 5 deletions crates/ember-cli/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ async fn run_batch_async(
let mut conn = match Connection::connect(host, port, tls).await {
Ok(c) => c,
Err(e) => {
eprintln!("{}", format!("could not connect to {host}:{port}: {e}").red());
eprintln!(
"{}",
format!("could not connect to {host}:{port}: {e}").red()
);
return ExitCode::FAILURE;
}
};
Expand Down Expand Up @@ -80,10 +83,7 @@ async fn run_batch_async(
continue;
}

let tokens: Vec<String> = trimmed
.split_whitespace()
.map(|s| s.to_string())
.collect();
let tokens: Vec<String> = trimmed.split_whitespace().map(|s| s.to_string()).collect();

match conn.send_command(&tokens).await {
Ok(frame) => println!("{}", format_response(&frame)),
Expand Down
5 changes: 4 additions & 1 deletion crates/ember-cli/src/watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ async fn run_watch_async(
let mut conn = match Connection::connect(host, port, tls).await {
Ok(c) => c,
Err(e) => {
eprintln!("{}", format!("could not connect to {host}:{port}: {e}").red());
eprintln!(
"{}",
format!("could not connect to {host}:{port}: {e}").red()
);
return ExitCode::FAILURE;
}
};
Expand Down
30 changes: 11 additions & 19 deletions crates/ember-client/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,10 @@ impl Client {
///
/// Times out after 5 seconds if the server is unreachable.
pub async fn connect(host: &str, port: u16) -> Result<Self, ClientError> {
let tcp = tokio::time::timeout(
CONNECT_TIMEOUT,
TcpStream::connect((host, port)),
)
.await
.map_err(|_| ClientError::Timeout)?
.map_err(ClientError::Io)?;
let tcp = tokio::time::timeout(CONNECT_TIMEOUT, TcpStream::connect((host, port)))
.await
.map_err(|_| ClientError::Timeout)?
.map_err(ClientError::Io)?;

Ok(Self::from_transport(Transport::Tcp(tcp)))
}
Expand All @@ -139,13 +136,10 @@ impl Client {
port: u16,
tls: &TlsClientConfig,
) -> Result<Self, ClientError> {
let stream = tokio::time::timeout(
CONNECT_TIMEOUT,
crate::tls::connect(host, port, tls),
)
.await
.map_err(|_| ClientError::Timeout)?
.map_err(ClientError::Io)?;
let stream = tokio::time::timeout(CONNECT_TIMEOUT, crate::tls::connect(host, port, tls))
.await
.map_err(|_| ClientError::Timeout)?
.map_err(ClientError::Io)?;

Ok(Self::from_transport(stream))
}
Expand Down Expand Up @@ -248,11 +242,9 @@ impl Client {
return Err(ClientError::ResponseTooLarge);
}

let read_result = tokio::time::timeout(
READ_TIMEOUT,
self.transport.read_buf(&mut self.read_buf),
)
.await;
let read_result =
tokio::time::timeout(READ_TIMEOUT, self.transport.read_buf(&mut self.read_buf))
.await;

match read_result {
Ok(Ok(0)) => return Err(ClientError::Disconnected),
Expand Down
7 changes: 3 additions & 4 deletions crates/ember-cluster/src/raft_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,9 @@ fn recover_log_file(path: &Path) -> Result<(BTreeMap<u64, Entry<TypeConfig>>, u6

match read_record::<Entry<TypeConfig>>(&mut reader) {
Ok(Some(entry)) => {
let payload_bytes =
postcard::to_allocvec(&entry)
.map_err(|e| RaftDiskError::Postcard(e.to_string()))?
.len() as u64;
let payload_bytes = postcard::to_allocvec(&entry)
.map_err(|e| RaftDiskError::Postcard(e.to_string()))?
.len() as u64;
// record size: 4 (len) + payload + 4 (crc)
valid_pos += 4 + payload_bytes + 4;
entries.insert(entry.log_id.index, entry);
Expand Down
19 changes: 14 additions & 5 deletions crates/ember-core/src/keyspace/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ impl Keyspace {
let Some(value) = popped else {
return Ok(None);
};
self.list_push(destination, &[value.clone()], dst_left)?;
self.list_push(destination, std::slice::from_ref(&value), dst_left)?;
Ok(Some(value))
}

Expand Down Expand Up @@ -1281,12 +1281,18 @@ mod tests {
#[test]
fn lmove_left_to_right() {
let mut ks = Keyspace::new();
ks.rpush("src", &[Bytes::from("a"), Bytes::from("b"), Bytes::from("c")])
.unwrap();
ks.rpush(
"src",
&[Bytes::from("a"), Bytes::from("b"), Bytes::from("c")],
)
.unwrap();
let moved = ks.lmove("src", "dst", true, false).unwrap();
assert_eq!(moved, Some(Bytes::from("a")));
// src should now be [b, c]
assert_eq!(ks.lrange("src", 0, -1).unwrap(), vec![Bytes::from("b"), Bytes::from("c")]);
assert_eq!(
ks.lrange("src", 0, -1).unwrap(),
vec![Bytes::from("b"), Bytes::from("c")]
);
// dst should be [a]
assert_eq!(ks.lrange("dst", 0, -1).unwrap(), vec![Bytes::from("a")]);
}
Expand All @@ -1300,7 +1306,10 @@ mod tests {
let moved = ks.lmove("q", "q", true, false).unwrap();
assert_eq!(moved, Some(Bytes::from("1")));
let items = ks.lrange("q", 0, -1).unwrap();
assert_eq!(items, vec![Bytes::from("2"), Bytes::from("3"), Bytes::from("1")]);
assert_eq!(
items,
vec![Bytes::from("2"), Bytes::from("3"), Bytes::from("1")]
);
}

#[test]
Expand Down
21 changes: 17 additions & 4 deletions crates/ember-core/src/keyspace/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ impl Keyspace {
Value::String(ref b) => b.clone(),
_ => unreachable!("type checked above"),
};
self.memory
.remove_with_size(entry.cached_value_size as usize + key.len() + memory::ENTRY_OVERHEAD);
self.memory.remove_with_size(
entry.cached_value_size as usize + key.len() + memory::ENTRY_OVERHEAD,
);
self.decrement_expiry_if_set(&entry);
self.remove_version(key);
Ok(Some(bytes))
Expand Down Expand Up @@ -996,7 +997,13 @@ mod tests {
#[test]
fn getex_no_option_leaves_ttl_unchanged() {
let mut ks = Keyspace::new();
ks.set("k".into(), Bytes::from("v"), Some(Duration::from_secs(60)), false, false);
ks.set(
"k".into(),
Bytes::from("v"),
Some(Duration::from_secs(60)),
false,
false,
);
let ttl_before = ks.ttl("k");
let val = ks.getex("k", None).unwrap();
assert_eq!(val, Some(Bytes::from("v")));
Expand All @@ -1009,7 +1016,13 @@ mod tests {
#[test]
fn getex_persist_clears_ttl() {
let mut ks = Keyspace::new();
ks.set("k".into(), Bytes::from("v"), Some(Duration::from_secs(60)), false, false);
ks.set(
"k".into(),
Bytes::from("v"),
Some(Duration::from_secs(60)),
false,
false,
);
let val = ks.getex("k", Some(None)).unwrap();
assert_eq!(val, Some(Bytes::from("v")));
assert!(matches!(ks.ttl("k"), TtlResult::NoExpiry));
Expand Down
51 changes: 42 additions & 9 deletions crates/ember-core/src/keyspace/zset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,18 @@ mod tests {
#[test]
fn zdiff_returns_members_unique_to_first() {
let mut ks = Keyspace::new();
ks.zadd("a", &[(1.0, "x".into()), (2.0, "y".into()), (3.0, "z".into())], &ZAddFlags::default()).unwrap();
ks.zadd("b", &[(1.0, "y".into()), (1.0, "w".into())], &ZAddFlags::default()).unwrap();
ks.zadd(
"a",
&[(1.0, "x".into()), (2.0, "y".into()), (3.0, "z".into())],
&ZAddFlags::default(),
)
.unwrap();
ks.zadd(
"b",
&[(1.0, "y".into()), (1.0, "w".into())],
&ZAddFlags::default(),
)
.unwrap();

let keys = vec!["a".to_owned(), "b".to_owned()];
let diff = ks.zdiff(&keys).unwrap();
Expand All @@ -973,7 +983,8 @@ mod tests {
#[test]
fn zdiff_with_missing_second_key_returns_all() {
let mut ks = Keyspace::new();
ks.zadd("a", &[(1.0, "x".into())], &ZAddFlags::default()).unwrap();
ks.zadd("a", &[(1.0, "x".into())], &ZAddFlags::default())
.unwrap();
let keys = vec!["a".to_owned(), "missing".to_owned()];
let diff = ks.zdiff(&keys).unwrap();
assert_eq!(diff.len(), 1);
Expand All @@ -983,8 +994,18 @@ mod tests {
#[test]
fn zinter_returns_common_members_with_summed_scores() {
let mut ks = Keyspace::new();
ks.zadd("a", &[(1.0, "x".into()), (2.0, "y".into())], &ZAddFlags::default()).unwrap();
ks.zadd("b", &[(3.0, "x".into()), (4.0, "z".into())], &ZAddFlags::default()).unwrap();
ks.zadd(
"a",
&[(1.0, "x".into()), (2.0, "y".into())],
&ZAddFlags::default(),
)
.unwrap();
ks.zadd(
"b",
&[(3.0, "x".into()), (4.0, "z".into())],
&ZAddFlags::default(),
)
.unwrap();

let keys = vec!["a".to_owned(), "b".to_owned()];
let inter = ks.zinter(&keys).unwrap();
Expand All @@ -996,17 +1017,29 @@ mod tests {
#[test]
fn zinter_empty_when_no_common_members() {
let mut ks = Keyspace::new();
ks.zadd("a", &[(1.0, "x".into())], &ZAddFlags::default()).unwrap();
ks.zadd("b", &[(1.0, "y".into())], &ZAddFlags::default()).unwrap();
ks.zadd("a", &[(1.0, "x".into())], &ZAddFlags::default())
.unwrap();
ks.zadd("b", &[(1.0, "y".into())], &ZAddFlags::default())
.unwrap();
let keys = vec!["a".to_owned(), "b".to_owned()];
assert!(ks.zinter(&keys).unwrap().is_empty());
}

#[test]
fn zunion_combines_all_members_with_summed_scores() {
let mut ks = Keyspace::new();
ks.zadd("a", &[(1.0, "x".into()), (2.0, "y".into())], &ZAddFlags::default()).unwrap();
ks.zadd("b", &[(3.0, "x".into()), (4.0, "z".into())], &ZAddFlags::default()).unwrap();
ks.zadd(
"a",
&[(1.0, "x".into()), (2.0, "y".into())],
&ZAddFlags::default(),
)
.unwrap();
ks.zadd(
"b",
&[(3.0, "x".into()), (4.0, "z".into())],
&ZAddFlags::default(),
)
.unwrap();

let keys = vec!["a".to_owned(), "b".to_owned()];
let union = ks.zunion(&keys).unwrap();
Expand Down
5 changes: 4 additions & 1 deletion crates/ember-core/src/shard/aof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,10 @@ pub(super) fn to_aof_records(
ShardResponse::Value(Some(_)),
) => match new_expire {
Some(ms) if ms > 0 => {
smallvec![AofRecord::Pexpire { key, milliseconds: ms }]
smallvec![AofRecord::Pexpire {
key,
milliseconds: ms
}]
}
// PERSIST — expire set to 0 in the keyspace; record as pexpire 0
// so replay calls persist. We use a negative sentinel to signal
Expand Down
15 changes: 12 additions & 3 deletions crates/ember-protocol/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,24 @@ pub enum Command {

/// ZDIFF `numkeys` `key` \[key ...\] \[WITHSCORES\].
/// Returns members in the first sorted set not present in the others.
ZDiff { keys: Vec<String>, with_scores: bool },
ZDiff {
keys: Vec<String>,
with_scores: bool,
},

/// ZINTER `numkeys` `key` \[key ...\] \[WITHSCORES\].
/// Returns members present in all of the given sorted sets.
ZInter { keys: Vec<String>, with_scores: bool },
ZInter {
keys: Vec<String>,
with_scores: bool,
},

/// ZUNION `numkeys` `key` \[key ...\] \[WITHSCORES\].
/// Returns the union of all given sorted sets.
ZUnion { keys: Vec<String>, with_scores: bool },
ZUnion {
keys: Vec<String>,
with_scores: bool,
},

/// TYPE `key`. Returns the type of the value stored at key.
Type { key: String },
Expand Down
7 changes: 5 additions & 2 deletions crates/ember-server/src/connection/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub(super) async fn execute(
nx,
xx,
} => {
let duration = expire.map(|e| set_expire_to_duration(e));
let duration = expire.map(set_expire_to_duration);
let idx = engine.shard_for_key(&key);
let req = ShardRequest::Set {
key,
Expand Down Expand Up @@ -1620,7 +1620,10 @@ pub(super) async fn execute(
}
})
});
let req = ShardRequest::GetEx { key, expire: expire_ms };
let req = ShardRequest::GetEx {
key,
expire: expire_ms,
};
match engine.send_to_shard(idx, req).await {
Ok(ShardResponse::Value(Some(Value::String(data)))) => Frame::Bulk(data),
Ok(ShardResponse::Value(None)) => Frame::Null,
Expand Down
10 changes: 8 additions & 2 deletions crates/ember-server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,10 @@ pub async fn run_concurrent(
ctx_snap
.last_save_timestamp
.store(ts, std::sync::atomic::Ordering::Relaxed);
tracing::info!(interval = save_interval_secs, "automatic snapshot completed");
tracing::info!(
interval = save_interval_secs,
"automatic snapshot completed"
);
}
Err(e) => tracing::warn!("automatic snapshot failed: {e}"),
}
Expand Down Expand Up @@ -609,7 +612,10 @@ pub async fn run_threaded(
ctx_snap
.last_save_timestamp
.store(ts, std::sync::atomic::Ordering::Relaxed);
tracing::info!(interval = save_interval_secs, "automatic snapshot completed");
tracing::info!(
interval = save_interval_secs,
"automatic snapshot completed"
);
}
Err(e) => tracing::warn!("automatic snapshot failed: {e}"),
}
Expand Down
Loading