Skip to content

Commit 8526e5c

Browse files
authored
Merge pull request #16 from Miaxos/feat-add-client-info
Add client info
2 parents c2f80e2 + 819d74e commit 8526e5c

File tree

7 files changed

+78
-10
lines changed

7 files changed

+78
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use super::super::parse::Parse;
2+
use crate::application::server::connection::WriteConnection;
3+
use crate::application::server::context::Context;
4+
use crate::application::server::frame::Frame;
5+
6+
/// The command returns information and statistics about the current client
7+
/// connection in a mostly human readable format.
8+
///
9+
/// The reply format is identical to that of CLIENT LIST, and the content
10+
/// consists only of information about the current client.
11+
#[derive(Debug, Default)]
12+
pub struct ClientInfo {}
13+
14+
impl ClientInfo {
15+
pub fn new() -> ClientInfo {
16+
ClientInfo {}
17+
}
18+
19+
pub(crate) fn parse_frames(
20+
parse: &mut Parse,
21+
) -> anyhow::Result<ClientInfo> {
22+
parse.finish()?;
23+
24+
Ok(ClientInfo::new())
25+
}
26+
27+
pub(crate) async fn apply(
28+
self,
29+
dst: &mut WriteConnection,
30+
ctx: Context,
31+
) -> anyhow::Result<()> {
32+
let response = Frame::Simple(ctx.connection.format_conn().await);
33+
dst.write_frame(&response).await?;
34+
Ok(())
35+
}
36+
}

app/roster/src/application/server/cmd/client/list.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use anyhow::bail;
2-
use bytestring::ByteString;
32

43
use super::super::parse::Parse;
54
use crate::application::server::cmd::parse::ParseError;
@@ -107,14 +106,7 @@ impl ClientList {
107106
// TODO(@miaxos): lot of things missing here
108107
let mut conn_frames = Vec::with_capacity(connections.len());
109108
for conn in connections {
110-
conn_frames.push(Frame::Simple(ByteString::from(format!(
111-
"id={id} addr={addr} laddr={laddr} fd={fd} name={name}",
112-
id = &conn.id,
113-
addr = &conn.addr,
114-
laddr = &conn.laddr,
115-
fd = &conn.fd,
116-
name = &conn.name().await.unwrap_or(ByteString::new()),
117-
))));
109+
conn_frames.push(Frame::Simple(conn.format_conn().await));
118110
}
119111

120112
let response = Frame::Array(conn_frames);

app/roster/src/application/server/cmd/client/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::application::server::context::Context;
77
use crate::application::server::frame::Frame;
88

99
mod id;
10+
mod info;
1011
mod list;
1112
mod set_info;
1213
mod set_name;
@@ -18,6 +19,7 @@ pub enum Client {
1819
SetName(set_name::ClientSetName),
1920
List(list::ClientList),
2021
Id(id::ClientID),
22+
Info(info::ClientInfo),
2123
}
2224

2325
// TODO(@miaxos): This is a simple implementation of the HELP to have the
@@ -26,6 +28,8 @@ pub enum Client {
2628
const HELP_TEXT: &str = r#"CLIENT <subcommand> [<arg> [value] [opt] ...]. subcommands are:
2729
ID
2830
Return the ID of the current connection.
31+
INFO
32+
Return information about the current client connection.
2933
LIST [options ...]
3034
Return information about client connections. Options:
3135
* TYPE (NORMAL|MASTER|REPLICA|PUBSUB)
@@ -64,6 +68,9 @@ impl SubcommandRegistry for Client {
6468
"id" => Command::Client(Client::Id(id::ClientID::parse_frames(
6569
&mut parse,
6670
)?)),
71+
"info" => Command::Client(Client::Info(
72+
info::ClientInfo::parse_frames(&mut parse)?,
73+
)),
6774
"list" => Command::Client(Client::List(
6875
list::ClientList::parse_frames(&mut parse)?,
6976
)),
@@ -114,6 +121,7 @@ impl CommandExecution for Client {
114121
Client::SetInfo(cmd) => cmd.apply(dst, ctx).await,
115122
Client::SetName(cmd) => cmd.apply(dst, ctx).await,
116123
Client::Id(cmd) => cmd.apply(dst, ctx).await,
124+
Client::Info(cmd) => cmd.apply(dst, ctx).await,
117125
Client::List(cmd) => cmd.apply(dst, ctx).await,
118126
}
119127
}

app/roster/src/application/server/supervisor/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ impl MetadataConnection {
124124
pub async fn name(&self) -> Option<ByteString> {
125125
self.name.read().await.clone()
126126
}
127+
128+
pub async fn format_conn(&self) -> ByteString {
129+
ByteString::from(format!(
130+
"id={id} addr={addr} laddr={laddr} fd={fd} name={name}",
131+
id = &self.id,
132+
addr = &self.addr,
133+
laddr = &self.laddr,
134+
fd = &self.fd,
135+
name = &self.name().await.unwrap_or(ByteString::new()),
136+
))
137+
}
127138
}
128139

129140
impl MetadataConnection {

app/roster/tests/client.rs

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub async fn test_simple_client_help() {
3333
CLIENT <subcommand> [<arg> [value] [opt] ...]. subcommands are:
3434
ID
3535
Return the ID of the current connection.
36+
INFO
37+
Return information about the current client connection.
3638
LIST [options ...]
3739
Return information about client connections. Options:
3840
* TYPE (NORMAL|MASTER|REPLICA|PUBSUB)

app/roster/tests/client_info.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
mod utils;
2+
use redis_async::resp_array;
3+
use regex::Regex;
4+
5+
#[tokio::test]
6+
pub async fn client_info() {
7+
let test_re: Regex =
8+
Regex::new(r"^id=0 addr=.*? laddr=.*? fd=.*? name=$").unwrap();
9+
let addr = utils::start_simple_server();
10+
11+
let connection = utils::connect_without_auth(addr).await;
12+
13+
let res_f: String = connection
14+
.send(resp_array!["CLIENT", "INFO"])
15+
.await
16+
.unwrap();
17+
18+
assert!(test_re.is_match(&res_f));
19+
}

docs/cmd_list.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ the command or open an issue.
4343
- [ ] CLIENT GETREDIR
4444
- [x] CLIENT HELP
4545
- [x] CLIENT ID
46-
- [ ] CLIENT INFO
46+
- [x] CLIENT INFO
4747
- [ ] CLIENT KILL
4848
- [ ] CLIENT LIST
4949
A lot is missing right now but it's partially working, not every arguments are

0 commit comments

Comments
 (0)