Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
0c96ecef
Commit
0c96ecef
authored
Nov 21, 2019
by
zhujiashun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
redis_server_protocol: rename RedisReply to RedisMessage
parent
978814fe
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
192 additions
and
191 deletions
+192
-191
redis_protocol.cpp
src/brpc/policy/redis_protocol.cpp
+4
-4
redis.cpp
src/brpc/redis.cpp
+7
-7
redis.h
src/brpc/redis.h
+7
-7
redis_message.cpp
src/brpc/redis_message.cpp
+51
-50
redis_message.h
src/brpc/redis_message.h
+70
-70
brpc_redis_unittest.cpp
test/brpc_redis_unittest.cpp
+53
-53
No files found.
src/brpc/policy/redis_protocol.cpp
View file @
0c96ecef
...
...
@@ -54,7 +54,7 @@ struct InputResponse : public InputMessageBase {
};
struct
ExecutionQueueContext
{
Redis
Reply
message
;
Redis
Message
message
;
SocketId
socket_id
;
butil
::
Arena
arena
;
};
...
...
@@ -72,7 +72,7 @@ int Consume(void* meta, bthread::TaskIterator<ExecutionQueueContext*>& iter) {
LOG
(
WARNING
)
<<
"Fail to address redis socket"
;
continue
;
}
Redis
Reply
output
;
Redis
Message
output
;
conn
->
OnRedisMessage
(
ctx
->
message
,
&
output
,
&
ctx
->
arena
);
butil
::
IOBuf
sendbuf
;
output
.
SerializeToIOBuf
(
&
sendbuf
);
...
...
@@ -132,7 +132,7 @@ ParseResult ParseRedisMessage(butil::IOBuf* source, Socket* socket,
socket
->
reset_parsing_context
(
ctx
);
}
std
::
unique_ptr
<
ExecutionQueueContext
>
task
(
new
ExecutionQueueContext
);
Redis
Reply
message
;
Redis
Message
message
;
ParseError
err
=
message
.
ConsumePartialIOBuf
(
*
source
,
&
task
->
arena
);
if
(
err
!=
PARSE_OK
)
{
return
MakeParseError
(
err
);
...
...
@@ -178,7 +178,7 @@ ParseResult ParseRedisMessage(butil::IOBuf* source, Socket* socket,
if
(
pi
.
with_auth
)
{
if
(
msg
->
response
.
reply_size
()
!=
1
||
!
(
msg
->
response
.
reply
(
0
).
type
()
==
brpc
::
REDIS_
REPLY
_STATUS
&&
!
(
msg
->
response
.
reply
(
0
).
type
()
==
brpc
::
REDIS_
MESSAGE
_STATUS
&&
msg
->
response
.
reply
(
0
).
data
().
compare
(
"OK"
)
==
0
))
{
LOG
(
ERROR
)
<<
"Redis Auth failed: "
<<
msg
->
response
;
return
MakeParseError
(
PARSE_ERROR_NO_RESOURCE
,
...
...
src/brpc/redis.cpp
View file @
0c96ecef
...
...
@@ -322,10 +322,10 @@ void RedisResponse::MergeFrom(const RedisResponse& from) {
_nreply
=
new_nreply
;
return
;
}
Redis
Reply
*
new_others
=
(
Redis
Reply
*
)
_arena
.
allocate
(
sizeof
(
RedisReply
)
*
(
new_nreply
-
1
));
Redis
Message
*
new_others
=
(
Redis
Message
*
)
_arena
.
allocate
(
sizeof
(
RedisMessage
)
*
(
new_nreply
-
1
));
for
(
int
i
=
0
;
i
<
new_nreply
-
1
;
++
i
)
{
new
(
new_others
+
i
)
Redis
Reply
;
new
(
new_others
+
i
)
Redis
Message
;
}
int
new_other_index
=
0
;
for
(
int
i
=
1
;
i
<
_nreply
;
++
i
)
{
...
...
@@ -394,14 +394,14 @@ ParseError RedisResponse::ConsumePartialIOBuf(butil::IOBuf& buf, int reply_count
}
if
(
reply_count
>
1
)
{
if
(
_other_replies
==
NULL
)
{
_other_replies
=
(
Redis
Reply
*
)
_arena
.
allocate
(
sizeof
(
Redis
Reply
)
*
(
reply_count
-
1
));
_other_replies
=
(
Redis
Message
*
)
_arena
.
allocate
(
sizeof
(
Redis
Message
)
*
(
reply_count
-
1
));
if
(
_other_replies
==
NULL
)
{
LOG
(
ERROR
)
<<
"Fail to allocate Redis
Reply
["
<<
reply_count
-
1
<<
"]"
;
LOG
(
ERROR
)
<<
"Fail to allocate Redis
Message
["
<<
reply_count
-
1
<<
"]"
;
return
PARSE_ERROR_ABSOLUTELY_WRONG
;
}
for
(
int
i
=
0
;
i
<
reply_count
-
1
;
++
i
)
{
new
(
&
_other_replies
[
i
])
Redis
Reply
;
new
(
&
_other_replies
[
i
])
Redis
Message
;
}
}
for
(
int
i
=
reply_size
();
i
<
reply_count
;
++
i
)
{
...
...
src/brpc/redis.h
View file @
0c96ecef
...
...
@@ -25,7 +25,7 @@
#include "butil/strings/string_piece.h"
#include "butil/arena.h"
#include "brpc/proto_base.pb.h"
#include "brpc/redis_
reply
.h"
#include "brpc/redis_
message
.h"
#include "brpc/parse_result.h"
namespace
brpc
{
...
...
@@ -157,11 +157,11 @@ public:
int
reply_size
()
const
{
return
_nreply
;
}
// Get index-th reply. If index is out-of-bound, nil reply is returned.
const
Redis
Reply
&
reply
(
int
index
)
const
{
const
Redis
Message
&
reply
(
int
index
)
const
{
if
(
index
<
reply_size
())
{
return
(
index
==
0
?
_first_reply
:
_other_replies
[
index
-
1
]);
}
static
Redis
Reply
redis_nil
;
static
Redis
Message
redis_nil
;
return
redis_nil
;
}
...
...
@@ -199,8 +199,8 @@ private:
void
SharedDtor
();
void
SetCachedSize
(
int
size
)
const
;
Redis
Reply
_first_reply
;
Redis
Reply
*
_other_replies
;
Redis
Message
_first_reply
;
Redis
Message
*
_other_replies
;
butil
::
Arena
_arena
;
int
_nreply
;
mutable
int
_cached_size_
;
...
...
@@ -212,8 +212,8 @@ std::ostream& operator<<(std::ostream& os, const RedisResponse&);
class
RedisConnection
{
public
:
virtual
~
RedisConnection
()
{}
virtual
void
OnRedisMessage
(
const
Redis
Reply
&
message
,
Redis
Reply
*
output
,
butil
::
Arena
*
arena
)
=
0
;
virtual
void
OnRedisMessage
(
const
Redis
Message
&
message
,
Redis
Message
*
output
,
butil
::
Arena
*
arena
)
=
0
;
};
class
RedisService
{
...
...
src/brpc/redis_
reply
.cpp
→
src/brpc/redis_
message
.cpp
View file @
0c96ecef
...
...
@@ -19,31 +19,32 @@
#include <limits>
#include "butil/logging.h"
#include "brpc/redis_
reply
.h"
#include "brpc/redis_
message
.h"
namespace
brpc
{
//BAIDU_CASSERT(sizeof(Redis
Reply
) == 24, size_match);
const
uint32_t
Redis
Reply
::
npos
=
(
uint32_t
)
-
1
;
//BAIDU_CASSERT(sizeof(Redis
Message
) == 24, size_match);
const
uint32_t
Redis
Message
::
npos
=
(
uint32_t
)
-
1
;
const
char
*
Redis
ReplyTypeToString
(
RedisReply
Type
type
)
{
const
char
*
Redis
MessageTypeToString
(
RedisMessage
Type
type
)
{
switch
(
type
)
{
case
REDIS_
REPLY
_STRING
:
return
"string"
;
case
REDIS_
REPLY
_ARRAY
:
return
"array"
;
case
REDIS_
REPLY
_INTEGER
:
return
"integer"
;
case
REDIS_
REPLY
_NIL
:
return
"nil"
;
case
REDIS_
REPLY
_STATUS
:
return
"status"
;
case
REDIS_
REPLY
_ERROR
:
return
"error"
;
case
REDIS_
MESSAGE
_STRING
:
return
"string"
;
case
REDIS_
MESSAGE
_ARRAY
:
return
"array"
;
case
REDIS_
MESSAGE
_INTEGER
:
return
"integer"
;
case
REDIS_
MESSAGE
_NIL
:
return
"nil"
;
case
REDIS_
MESSAGE
_STATUS
:
return
"status"
;
case
REDIS_
MESSAGE
_ERROR
:
return
"error"
;
default:
return
"unknown redis type"
;
}
}
bool
Redis
Reply
::
SerializeToIOBuf
(
butil
::
IOBuf
*
buf
)
{
bool
Redis
Message
::
SerializeToIOBuf
(
butil
::
IOBuf
*
buf
)
{
butil
::
IOBufBuilder
builder
;
switch
(
_type
)
{
case
REDIS_REPLY_ERROR
:
case
REDIS_REPLY_STATUS
:
buf
->
push_back
((
_type
==
REDIS_REPLY_ERROR
)
?
'-'
:
'+'
);
case
REDIS_MESSAGE_ERROR
:
// fall through
case
REDIS_MESSAGE_STATUS
:
buf
->
push_back
((
_type
==
REDIS_MESSAGE_ERROR
)
?
'-'
:
'+'
);
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
buf
->
append
(
_data
.
short_str
,
_length
);
}
else
{
...
...
@@ -51,11 +52,11 @@ bool RedisReply::SerializeToIOBuf(butil::IOBuf* buf) {
}
buf
->
append
(
"
\r\n
"
);
break
;
case
REDIS_
REPLY
_INTEGER
:
case
REDIS_
MESSAGE
_INTEGER
:
builder
<<
':'
<<
_data
.
integer
<<
"
\r\n
"
;
buf
->
append
(
builder
.
buf
());
break
;
case
REDIS_
REPLY
_STRING
:
case
REDIS_
MESSAGE
_STRING
:
// Since _length is unsigned, we have to int casting _length to
// represent nil string
builder
<<
'$'
<<
(
int
)
_length
<<
"
\r\n
"
;
...
...
@@ -70,7 +71,7 @@ bool RedisReply::SerializeToIOBuf(butil::IOBuf* buf) {
}
buf
->
append
(
"
\r\n
"
);
break
;
case
REDIS_
REPLY
_ARRAY
:
case
REDIS_
MESSAGE
_ARRAY
:
builder
<<
'*'
<<
(
int
)
_length
<<
"
\r\n
"
;
buf
->
append
(
builder
.
buf
());
if
(
_length
==
npos
)
{
...
...
@@ -82,7 +83,7 @@ bool RedisReply::SerializeToIOBuf(butil::IOBuf* buf) {
}
}
break
;
case
REDIS_
REPLY
_NIL
:
case
REDIS_
MESSAGE
_NIL
:
buf
->
append
(
"$-1
\r\n
"
);
break
;
default
:
...
...
@@ -92,11 +93,11 @@ bool RedisReply::SerializeToIOBuf(butil::IOBuf* buf) {
return
true
;
}
ParseError
Redis
Reply
::
ConsumePartialIOBuf
(
butil
::
IOBuf
&
buf
,
butil
::
Arena
*
arena
)
{
if
(
_type
==
REDIS_
REPLY
_ARRAY
&&
_data
.
array
.
last_index
>=
0
)
{
ParseError
Redis
Message
::
ConsumePartialIOBuf
(
butil
::
IOBuf
&
buf
,
butil
::
Arena
*
arena
)
{
if
(
_type
==
REDIS_
MESSAGE
_ARRAY
&&
_data
.
array
.
last_index
>=
0
)
{
// The parsing was suspended while parsing sub replies,
// continue the parsing.
Redis
Reply
*
subs
=
(
RedisReply
*
)
_data
.
array
.
replies
;
Redis
Message
*
subs
=
(
RedisMessage
*
)
_data
.
array
.
replies
;
for
(
uint32_t
i
=
_data
.
array
.
last_index
;
i
<
_length
;
++
i
)
{
ParseError
err
=
subs
[
i
].
ConsumePartialIOBuf
(
buf
,
arena
);
if
(
err
!=
PARSE_OK
)
{
...
...
@@ -131,7 +132,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
const
size_t
len
=
str
.
size
()
-
1
;
if
(
len
<
sizeof
(
_data
.
short_str
))
{
// SSO short strings, including empty string.
_type
=
(
fc
==
'-'
?
REDIS_
REPLY_ERROR
:
REDIS_REPLY
_STATUS
);
_type
=
(
fc
==
'-'
?
REDIS_
MESSAGE_ERROR
:
REDIS_MESSAGE
_STATUS
);
_length
=
len
;
str
.
copy_to_cstr
(
_data
.
short_str
,
(
size_t
)
-
1L
,
1
/*skip fc*/
);
return
PARSE_OK
;
...
...
@@ -142,7 +143,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
return
PARSE_ERROR_ABSOLUTELY_WRONG
;
}
CHECK_EQ
(
len
,
str
.
copy_to_cstr
(
d
,
(
size_t
)
-
1L
,
1
/*skip fc*/
));
_type
=
(
fc
==
'-'
?
REDIS_
REPLY_ERROR
:
REDIS_REPLY
_STATUS
);
_type
=
(
fc
==
'-'
?
REDIS_
MESSAGE_ERROR
:
REDIS_MESSAGE
_STATUS
);
_length
=
len
;
_data
.
long_str
=
d
;
return
PARSE_OK
;
...
...
@@ -165,7 +166,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
}
if
(
fc
==
':'
)
{
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
_type
=
REDIS_
REPLY
_INTEGER
;
_type
=
REDIS_
MESSAGE
_INTEGER
;
_length
=
0
;
_data
.
integer
=
value
;
return
PARSE_OK
;
...
...
@@ -173,7 +174,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
const
int64_t
len
=
value
;
// `value' is length of the string
if
(
len
<
0
)
{
// redis nil
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
_type
=
REDIS_
REPLY
_NIL
;
_type
=
REDIS_
MESSAGE
_NIL
;
_length
=
0
;
_data
.
integer
=
0
;
return
PARSE_OK
;
...
...
@@ -190,7 +191,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
}
if
((
size_t
)
len
<
sizeof
(
_data
.
short_str
))
{
// SSO short strings, including empty string.
_type
=
REDIS_
REPLY
_STRING
;
_type
=
REDIS_
MESSAGE
_STRING
;
_length
=
len
;
buf
.
pop_front
(
crlf_pos
+
2
);
buf
.
cutn
(
_data
.
short_str
,
len
);
...
...
@@ -204,7 +205,7 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
buf
.
cutn
(
d
,
len
);
d
[
len
]
=
'\0'
;
_type
=
REDIS_
REPLY
_STRING
;
_type
=
REDIS_
MESSAGE
_STRING
;
_length
=
len
;
_data
.
long_str
=
d
;
}
...
...
@@ -219,14 +220,14 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
const
int64_t
count
=
value
;
// `value' is count of sub replies
if
(
count
<
0
)
{
// redis nil
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
_type
=
REDIS_
REPLY
_NIL
;
_type
=
REDIS_
MESSAGE
_NIL
;
_length
=
0
;
_data
.
integer
=
0
;
return
PARSE_OK
;
}
if
(
count
==
0
)
{
// empty array
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
_type
=
REDIS_
REPLY
_ARRAY
;
_type
=
REDIS_
MESSAGE
_ARRAY
;
_length
=
0
;
_data
.
array
.
last_index
=
-
1
;
_data
.
array
.
replies
=
NULL
;
...
...
@@ -238,16 +239,16 @@ ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, butil::Arena* aren
return
PARSE_ERROR_ABSOLUTELY_WRONG
;
}
// FIXME(gejun): Call allocate_aligned instead.
Redis
Reply
*
subs
=
(
RedisReply
*
)
arena
->
allocate
(
sizeof
(
RedisReply
)
*
count
);
Redis
Message
*
subs
=
(
RedisMessage
*
)
arena
->
allocate
(
sizeof
(
RedisMessage
)
*
count
);
if
(
subs
==
NULL
)
{
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Reply
["
<<
count
<<
"]"
;
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Message
["
<<
count
<<
"]"
;
return
PARSE_ERROR_ABSOLUTELY_WRONG
;
}
for
(
int64_t
i
=
0
;
i
<
count
;
++
i
)
{
new
(
&
subs
[
i
])
Redis
Reply
;
new
(
&
subs
[
i
])
Redis
Message
;
}
buf
.
pop_front
(
crlf_pos
+
2
/*CRLF*/
);
_type
=
REDIS_
REPLY
_ARRAY
;
_type
=
REDIS_
MESSAGE
_ARRAY
;
_length
=
count
;
_data
.
array
.
replies
=
subs
;
...
...
@@ -316,9 +317,9 @@ void RedisStringPrinter::Print(std::ostream& os) const {
}
// Mimic how official redis-cli prints.
void
Redis
Reply
::
Print
(
std
::
ostream
&
os
)
const
{
void
Redis
Message
::
Print
(
std
::
ostream
&
os
)
const
{
switch
(
_type
)
{
case
REDIS_
REPLY
_STRING
:
case
REDIS_
MESSAGE
_STRING
:
os
<<
'"'
;
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
os
<<
RedisStringPrinter
(
_data
.
short_str
,
_length
);
...
...
@@ -327,7 +328,7 @@ void RedisReply::Print(std::ostream& os) const {
}
os
<<
'"'
;
break
;
case
REDIS_
REPLY
_ARRAY
:
case
REDIS_
MESSAGE
_ARRAY
:
os
<<
'['
;
for
(
uint32_t
i
=
0
;
i
<
_length
;
++
i
)
{
if
(
i
!=
0
)
{
...
...
@@ -337,16 +338,16 @@ void RedisReply::Print(std::ostream& os) const {
}
os
<<
']'
;
break
;
case
REDIS_
REPLY
_INTEGER
:
case
REDIS_
MESSAGE
_INTEGER
:
os
<<
"(integer) "
<<
_data
.
integer
;
break
;
case
REDIS_
REPLY
_NIL
:
case
REDIS_
MESSAGE
_NIL
:
os
<<
"(nil)"
;
break
;
case
REDIS_
REPLY
_ERROR
:
case
REDIS_
MESSAGE
_ERROR
:
os
<<
"(error) "
;
// fall through
case
REDIS_
REPLY
_STATUS
:
case
REDIS_
MESSAGE
_STATUS
:
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
os
<<
RedisStringPrinter
(
_data
.
short_str
,
_length
);
}
else
{
...
...
@@ -359,19 +360,19 @@ void RedisReply::Print(std::ostream& os) const {
}
}
void
Redis
Reply
::
CopyFromDifferentArena
(
const
RedisReply
&
other
,
void
Redis
Message
::
CopyFromDifferentArena
(
const
RedisMessage
&
other
,
butil
::
Arena
*
arena
)
{
_type
=
other
.
_type
;
_length
=
other
.
_length
;
switch
(
_type
)
{
case
REDIS_
REPLY
_ARRAY
:
{
Redis
Reply
*
subs
=
(
RedisReply
*
)
arena
->
allocate
(
sizeof
(
RedisReply
)
*
_length
);
case
REDIS_
MESSAGE
_ARRAY
:
{
Redis
Message
*
subs
=
(
RedisMessage
*
)
arena
->
allocate
(
sizeof
(
RedisMessage
)
*
_length
);
if
(
subs
==
NULL
)
{
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Reply
["
<<
_length
<<
"]"
;
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Message
["
<<
_length
<<
"]"
;
return
;
}
for
(
uint32_t
i
=
0
;
i
<
_length
;
++
i
)
{
new
(
&
subs
[
i
])
Redis
Reply
;
new
(
&
subs
[
i
])
Redis
Message
;
}
_data
.
array
.
last_index
=
other
.
_data
.
array
.
last_index
;
if
(
_data
.
array
.
last_index
>
0
)
{
...
...
@@ -382,16 +383,16 @@ void RedisReply::CopyFromDifferentArena(const RedisReply& other,
_data
.
array
.
replies
=
subs
;
}
break
;
case
REDIS_
REPLY
_INTEGER
:
case
REDIS_
MESSAGE
_INTEGER
:
_data
.
integer
=
other
.
_data
.
integer
;
break
;
case
REDIS_
REPLY
_NIL
:
case
REDIS_
MESSAGE
_NIL
:
break
;
case
REDIS_
REPLY
_STRING
:
case
REDIS_
MESSAGE
_STRING
:
// fall through
case
REDIS_
REPLY
_ERROR
:
case
REDIS_
MESSAGE
_ERROR
:
// fall through
case
REDIS_
REPLY
_STATUS
:
case
REDIS_
MESSAGE
_STATUS
:
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
memcpy
(
_data
.
short_str
,
other
.
_data
.
short_str
,
_length
+
1
);
}
else
{
...
...
src/brpc/redis_
reply
.h
→
src/brpc/redis_
message
.h
View file @
0c96ecef
...
...
@@ -17,8 +17,8 @@
// Authors: Ge,Jun (gejun@baidu.com)
#ifndef BRPC_REDIS_
REPLY
_H
#define BRPC_REDIS_
REPLY
_H
#ifndef BRPC_REDIS_
MESSAGE
_H
#define BRPC_REDIS_
MESSAGE
_H
#include "butil/iobuf.h" // butil::IOBuf
#include "butil/strings/string_piece.h" // butil::StringPiece
...
...
@@ -30,25 +30,25 @@
namespace
brpc
{
// Different types of replies.
enum
Redis
Reply
Type
{
REDIS_
REPLY
_STRING
=
1
,
// Bulk String
REDIS_
REPLY
_ARRAY
=
2
,
REDIS_
REPLY
_INTEGER
=
3
,
REDIS_
REPLY
_NIL
=
4
,
REDIS_
REPLY
_STATUS
=
5
,
// Simple String
REDIS_
REPLY
_ERROR
=
6
enum
Redis
Message
Type
{
REDIS_
MESSAGE
_STRING
=
1
,
// Bulk String
REDIS_
MESSAGE
_ARRAY
=
2
,
REDIS_
MESSAGE
_INTEGER
=
3
,
REDIS_
MESSAGE
_NIL
=
4
,
REDIS_
MESSAGE
_STATUS
=
5
,
// Simple String
REDIS_
MESSAGE
_ERROR
=
6
};
const
char
*
Redis
ReplyTypeToString
(
RedisReply
Type
);
const
char
*
Redis
MessageTypeToString
(
RedisMessage
Type
);
// A reply from redis-server.
class
Redis
Reply
{
class
Redis
Message
{
public
:
// A default constructed reply is a nil.
Redis
Reply
();
Redis
Message
();
// Type of the reply.
Redis
Reply
Type
type
()
const
{
return
_type
;
}
Redis
Message
Type
type
()
const
{
return
_type
;
}
bool
is_nil
()
const
;
// True if the reply is a (redis) nil.
bool
is_integer
()
const
;
// True if the reply is an integer.
...
...
@@ -86,17 +86,17 @@ public:
size_t
size
()
const
;
// Get the index-th sub reply. If this reply is not an array, a nil reply
// is returned (call stacks are not logged)
const
Redis
Reply
&
operator
[](
size_t
index
)
const
;
Redis
Reply
&
operator
[](
size_t
index
);
const
Redis
Message
&
operator
[](
size_t
index
)
const
;
Redis
Message
&
operator
[](
size_t
index
);
// Parse from `buf' which may be incomplete and allocate needed memory
// on `arena'.
// Returns PARSE_OK when an intact reply is parsed and cut off from `buf'.
// Returns PARSE_ERROR_NOT_ENOUGH_DATA if data in `buf' is not enough to parse,
// and `buf' is guaranteed to be UNCHANGED so that you can call this
// function on a Redis
Reply
object with the same buf again and again until
// function on a Redis
Message
object with the same buf again and again until
// the function returns PARSE_OK. This property makes sure the parsing of
// Redis
Reply
in the worst case is O(N) where N is size of the on-wire
// Redis
Message
in the worst case is O(N) where N is size of the on-wire
// reply. As a contrast, if the parsing needs `buf' to be intact,
// the complexity in worst case may be O(N^2).
// Returns PARSE_ERROR_ABSOLUTELY_WRONG if the parsing failed.
...
...
@@ -106,7 +106,7 @@ public:
bool
SerializeToIOBuf
(
butil
::
IOBuf
*
buf
);
// Swap internal fields with another reply.
void
Swap
(
Redis
Reply
&
other
);
void
Swap
(
Redis
Message
&
other
);
// Reset to the state that this reply was just constructed.
void
Clear
();
...
...
@@ -116,22 +116,22 @@ public:
// Copy from another reply allocating on a different Arena, and allocate
// required memory with `self_arena'.
void
CopyFromDifferentArena
(
const
Redis
Reply
&
other
,
void
CopyFromDifferentArena
(
const
Redis
Message
&
other
,
butil
::
Arena
*
self_arena
);
// Copy from another reply allocating on a same Arena.
void
CopyFromSameArena
(
const
Redis
Reply
&
other
);
void
CopyFromSameArena
(
const
Redis
Message
&
other
);
private
:
static
const
uint32_t
npos
;
// Redis
Reply
does not own the memory of fields, copying must be done
// Redis
Message
does not own the memory of fields, copying must be done
// by calling CopyFrom[Different|Same]Arena.
DISALLOW_COPY_AND_ASSIGN
(
Redis
Reply
);
DISALLOW_COPY_AND_ASSIGN
(
Redis
Message
);
bool
set_basic_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
,
Redis
Reply
Type
type
);
bool
set_basic_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
,
Redis
Message
Type
type
);
Redis
Reply
Type
_type
;
Redis
Message
Type
_type
;
uint32_t
_length
;
// length of short_str/long_str, count of replies
union
{
int64_t
integer
;
...
...
@@ -139,7 +139,7 @@ private:
const
char
*
long_str
;
struct
{
int32_t
last_index
;
// >= 0 if previous parsing suspends on replies.
Redis
Reply
*
replies
;
Redis
Message
*
replies
;
}
array
;
uint64_t
padding
[
2
];
// For swapping, must cover all bytes.
}
_data
;
...
...
@@ -147,46 +147,46 @@ private:
// =========== inline impl. ==============
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Redis
Reply
&
r
)
{
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Redis
Message
&
r
)
{
r
.
Print
(
os
);
return
os
;
}
inline
Redis
Reply
::
RedisReply
()
:
_type
(
REDIS_
REPLY
_NIL
)
inline
Redis
Message
::
RedisMessage
()
:
_type
(
REDIS_
MESSAGE
_NIL
)
,
_length
(
0
)
{
_data
.
array
.
last_index
=
-
1
;
_data
.
array
.
replies
=
NULL
;
}
inline
bool
Redis
Reply
::
is_nil
()
const
{
return
(
_type
==
REDIS_
REPLY
_NIL
)
||
((
_type
==
REDIS_
REPLY_STRING
||
_type
==
REDIS_REPLY
_ARRAY
)
&&
inline
bool
Redis
Message
::
is_nil
()
const
{
return
(
_type
==
REDIS_
MESSAGE
_NIL
)
||
((
_type
==
REDIS_
MESSAGE_STRING
||
_type
==
REDIS_MESSAGE
_ARRAY
)
&&
_length
==
uint32_t
(
-
1
));
}
inline
bool
Redis
Reply
::
is_error
()
const
{
return
_type
==
REDIS_REPLY
_ERROR
;
}
inline
bool
Redis
Reply
::
is_integer
()
const
{
return
_type
==
REDIS_REPLY
_INTEGER
;
}
inline
bool
Redis
Reply
::
is_string
()
const
{
return
_type
==
REDIS_
REPLY_STRING
||
_type
==
REDIS_REPLY
_STATUS
;
}
inline
bool
Redis
Reply
::
is_array
()
const
{
return
_type
==
REDIS_REPLY
_ARRAY
;
}
inline
bool
Redis
Message
::
is_error
()
const
{
return
_type
==
REDIS_MESSAGE
_ERROR
;
}
inline
bool
Redis
Message
::
is_integer
()
const
{
return
_type
==
REDIS_MESSAGE
_INTEGER
;
}
inline
bool
Redis
Message
::
is_string
()
const
{
return
_type
==
REDIS_
MESSAGE_STRING
||
_type
==
REDIS_MESSAGE
_STATUS
;
}
inline
bool
Redis
Message
::
is_array
()
const
{
return
_type
==
REDIS_MESSAGE
_ARRAY
;
}
inline
int64_t
Redis
Reply
::
integer
()
const
{
inline
int64_t
Redis
Message
::
integer
()
const
{
if
(
is_integer
())
{
return
_data
.
integer
;
}
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Reply
TypeToString
(
_type
)
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Message
TypeToString
(
_type
)
<<
", not an integer"
;
return
0
;
}
inline
bool
Redis
Reply
::
set_nil_string
()
{
_type
=
REDIS_
REPLY
_STRING
;
inline
bool
Redis
Message
::
set_nil_string
()
{
_type
=
REDIS_
MESSAGE
_STRING
;
_length
=
npos
;
return
true
;
}
inline
bool
Redis
Reply
::
set_array
(
int
size
,
butil
::
Arena
*
arena
)
{
_type
=
REDIS_
REPLY
_ARRAY
;
inline
bool
Redis
Message
::
set_array
(
int
size
,
butil
::
Arena
*
arena
)
{
_type
=
REDIS_
MESSAGE
_ARRAY
;
if
(
size
<
0
)
{
_length
=
npos
;
return
true
;
...
...
@@ -194,20 +194,20 @@ inline bool RedisReply::set_array(int size, butil::Arena* arena) {
_length
=
0
;
return
true
;
}
Redis
Reply
*
subs
=
(
RedisReply
*
)
arena
->
allocate
(
sizeof
(
RedisReply
)
*
size
);
Redis
Message
*
subs
=
(
RedisMessage
*
)
arena
->
allocate
(
sizeof
(
RedisMessage
)
*
size
);
if
(
!
subs
)
{
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Reply
["
<<
size
<<
"]"
;
LOG
(
FATAL
)
<<
"Fail to allocate Redis
Message
["
<<
size
<<
"]"
;
return
false
;
}
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
new
(
&
subs
[
i
])
Redis
Reply
;
new
(
&
subs
[
i
])
Redis
Message
;
}
_length
=
size
;
_data
.
array
.
replies
=
subs
;
return
true
;
}
inline
bool
Redis
Reply
::
set_basic_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
,
RedisReply
Type
type
)
{
inline
bool
Redis
Message
::
set_basic_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
,
RedisMessage
Type
type
)
{
size_t
size
=
str
.
size
();
if
(
size
<
sizeof
(
_data
.
short_str
))
{
memcpy
(
_data
.
short_str
,
str
.
c_str
(),
size
);
...
...
@@ -225,26 +225,26 @@ inline bool RedisReply::set_basic_string(const std::string& str, butil::Arena* a
return
true
;
}
inline
bool
Redis
Reply
::
set_status
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
REPLY
_STATUS
);
inline
bool
Redis
Message
::
set_status
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
MESSAGE
_STATUS
);
}
inline
bool
Redis
Reply
::
set_error
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
REPLY
_ERROR
);
inline
bool
Redis
Message
::
set_error
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
MESSAGE
_ERROR
);
}
inline
bool
Redis
Reply
::
set_integer
(
int64_t
value
)
{
_type
=
REDIS_
REPLY
_INTEGER
;
inline
bool
Redis
Message
::
set_integer
(
int64_t
value
)
{
_type
=
REDIS_
MESSAGE
_INTEGER
;
_length
=
0
;
_data
.
integer
=
value
;
return
true
;
}
inline
bool
Redis
Reply
::
set_bulk_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
REPLY
_STRING
);
inline
bool
Redis
Message
::
set_bulk_string
(
const
std
::
string
&
str
,
butil
::
Arena
*
arena
)
{
return
set_basic_string
(
str
,
arena
,
REDIS_
MESSAGE
_STRING
);
}
inline
const
char
*
Redis
Reply
::
c_str
()
const
{
inline
const
char
*
Redis
Message
::
c_str
()
const
{
if
(
is_string
())
{
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
// SSO
return
_data
.
short_str
;
...
...
@@ -252,12 +252,12 @@ inline const char* RedisReply::c_str() const {
return
_data
.
long_str
;
}
}
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Reply
TypeToString
(
_type
)
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Message
TypeToString
(
_type
)
<<
", not a string"
;
return
""
;
}
inline
butil
::
StringPiece
Redis
Reply
::
data
()
const
{
inline
butil
::
StringPiece
Redis
Message
::
data
()
const
{
if
(
is_string
())
{
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
// SSO
return
butil
::
StringPiece
(
_data
.
short_str
,
_length
);
...
...
@@ -265,12 +265,12 @@ inline butil::StringPiece RedisReply::data() const {
return
butil
::
StringPiece
(
_data
.
long_str
,
_length
);
}
}
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Reply
TypeToString
(
_type
)
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Message
TypeToString
(
_type
)
<<
", not a string"
;
return
butil
::
StringPiece
();
}
inline
const
char
*
Redis
Reply
::
error_message
()
const
{
inline
const
char
*
Redis
Message
::
error_message
()
const
{
if
(
is_error
())
{
if
(
_length
<
sizeof
(
_data
.
short_str
))
{
// SSO
return
_data
.
short_str
;
...
...
@@ -278,43 +278,43 @@ inline const char* RedisReply::error_message() const {
return
_data
.
long_str
;
}
}
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Reply
TypeToString
(
_type
)
CHECK
(
false
)
<<
"The reply is "
<<
Redis
Message
TypeToString
(
_type
)
<<
", not an error"
;
return
""
;
}
inline
size_t
Redis
Reply
::
size
()
const
{
inline
size_t
Redis
Message
::
size
()
const
{
return
(
is_array
()
?
_length
:
0
);
}
inline
Redis
Reply
&
RedisReply
::
operator
[](
size_t
index
)
{
return
const_cast
<
Redis
Reply
&>
(
const_cast
<
const
Redis
Reply
*>
(
this
)
->
operator
[](
index
));
inline
Redis
Message
&
RedisMessage
::
operator
[](
size_t
index
)
{
return
const_cast
<
Redis
Message
&>
(
const_cast
<
const
Redis
Message
*>
(
this
)
->
operator
[](
index
));
}
inline
const
Redis
Reply
&
RedisReply
::
operator
[](
size_t
index
)
const
{
inline
const
Redis
Message
&
RedisMessage
::
operator
[](
size_t
index
)
const
{
if
(
is_array
()
&&
index
<
_length
)
{
return
_data
.
array
.
replies
[
index
];
}
static
Redis
Reply
redis_nil
;
static
Redis
Message
redis_nil
;
return
redis_nil
;
}
inline
void
Redis
Reply
::
Swap
(
RedisReply
&
other
)
{
inline
void
Redis
Message
::
Swap
(
RedisMessage
&
other
)
{
std
::
swap
(
_type
,
other
.
_type
);
std
::
swap
(
_length
,
other
.
_length
);
std
::
swap
(
_data
.
padding
[
0
],
other
.
_data
.
padding
[
0
]);
std
::
swap
(
_data
.
padding
[
1
],
other
.
_data
.
padding
[
1
]);
}
inline
void
Redis
Reply
::
Clear
()
{
_type
=
REDIS_
REPLY
_NIL
;
inline
void
Redis
Message
::
Clear
()
{
_type
=
REDIS_
MESSAGE
_NIL
;
_length
=
0
;
_data
.
array
.
last_index
=
-
1
;
_data
.
array
.
replies
=
NULL
;
}
inline
void
Redis
Reply
::
CopyFromSameArena
(
const
RedisReply
&
other
)
{
inline
void
Redis
Message
::
CopyFromSameArena
(
const
RedisMessage
&
other
)
{
_type
=
other
.
_type
;
_length
=
other
.
_length
;
_data
.
padding
[
0
]
=
other
.
_data
.
padding
[
0
];
...
...
test/brpc_redis_unittest.cpp
View file @
0c96ecef
...
...
@@ -103,32 +103,32 @@ protected:
void
TearDown
()
{}
};
void
AssertReplyEqual
(
const
brpc
::
Redis
Reply
&
reply1
,
const
brpc
::
Redis
Reply
&
reply2
)
{
void
AssertReplyEqual
(
const
brpc
::
Redis
Message
&
reply1
,
const
brpc
::
Redis
Message
&
reply2
)
{
if
(
&
reply1
==
&
reply2
)
{
return
;
}
CHECK_EQ
(
reply1
.
type
(),
reply2
.
type
());
switch
(
reply1
.
type
())
{
case
brpc
:
:
REDIS_
REPLY
_ARRAY
:
case
brpc
:
:
REDIS_
MESSAGE
_ARRAY
:
ASSERT_EQ
(
reply1
.
size
(),
reply2
.
size
());
for
(
size_t
j
=
0
;
j
<
reply1
.
size
();
++
j
)
{
ASSERT_NE
(
&
reply1
[
j
],
&
reply2
[
j
]);
// from different arena
AssertReplyEqual
(
reply1
[
j
],
reply2
[
j
]);
}
break
;
case
brpc
:
:
REDIS_
REPLY
_INTEGER
:
case
brpc
:
:
REDIS_
MESSAGE
_INTEGER
:
ASSERT_EQ
(
reply1
.
integer
(),
reply2
.
integer
());
break
;
case
brpc
:
:
REDIS_
REPLY
_NIL
:
case
brpc
:
:
REDIS_
MESSAGE
_NIL
:
break
;
case
brpc
:
:
REDIS_
REPLY
_STRING
:
case
brpc
:
:
REDIS_
MESSAGE
_STRING
:
// fall through
case
brpc
:
:
REDIS_
REPLY
_STATUS
:
case
brpc
:
:
REDIS_
MESSAGE
_STATUS
:
ASSERT_NE
(
reply1
.
c_str
(),
reply2
.
c_str
());
// from different arena
ASSERT_STREQ
(
reply1
.
c_str
(),
reply2
.
c_str
());
break
;
case
brpc
:
:
REDIS_
REPLY
_ERROR
:
case
brpc
:
:
REDIS_
MESSAGE
_ERROR
:
ASSERT_NE
(
reply1
.
error_message
(),
reply2
.
error_message
());
// from different arena
ASSERT_STREQ
(
reply1
.
error_message
(),
reply2
.
error_message
());
break
;
...
...
@@ -168,7 +168,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_NIL
,
response
.
reply
(
0
).
type
())
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_NIL
,
response
.
reply
(
0
).
type
())
<<
response
;
cntl
.
Reset
();
...
...
@@ -178,7 +178,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
"OK"
,
response
.
reply
(
0
).
data
());
cntl
.
Reset
();
...
...
@@ -188,7 +188,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
());
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
"world"
,
response
.
reply
(
0
).
data
());
cntl
.
Reset
();
...
...
@@ -198,7 +198,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
"OK"
,
response
.
reply
(
0
).
data
());
cntl
.
Reset
();
...
...
@@ -208,7 +208,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
());
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
"world2"
,
response
.
reply
(
0
).
data
());
cntl
.
Reset
();
...
...
@@ -217,7 +217,7 @@ TEST_F(RedisTest, sanity) {
ASSERT_TRUE
(
request
.
AddCommand
(
"del hello"
));
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
1
,
response
.
reply
(
0
).
integer
());
cntl
.
Reset
();
...
...
@@ -227,7 +227,7 @@ TEST_F(RedisTest, sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_NIL
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_NIL
,
response
.
reply
(
0
).
type
());
}
TEST_F
(
RedisTest
,
keys_with_spaces
)
{
...
...
@@ -257,19 +257,19 @@ TEST_F(RedisTest, keys_with_spaces) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
7
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
"OK"
,
response
.
reply
(
0
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
"OK"
,
response
.
reply
(
1
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
"OK"
,
response
.
reply
(
2
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
"he1 he1 da1"
,
response
.
reply
(
3
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
4
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
4
).
type
());
ASSERT_EQ
(
"he1 he1 da1"
,
response
.
reply
(
4
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
5
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
5
).
type
());
ASSERT_EQ
(
"he2 he2 da2"
,
response
.
reply
(
5
).
data
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
6
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
6
).
type
());
ASSERT_EQ
(
"he3 he3 da3"
,
response
.
reply
(
6
).
data
());
brpc
::
RedisResponse
response2
=
response
;
...
...
@@ -298,13 +298,13 @@ TEST_F(RedisTest, incr_and_decr) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
4
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
1
,
response
.
reply
(
0
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
0
,
response
.
reply
(
1
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
10
,
response
.
reply
(
2
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
-
10
,
response
.
reply
(
3
).
integer
());
brpc
::
RedisResponse
response2
=
response
;
...
...
@@ -339,13 +339,13 @@ TEST_F(RedisTest, by_components) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
4
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
1
,
response
.
reply
(
0
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
0
,
response
.
reply
(
1
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
10
,
response
.
reply
(
2
).
integer
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_INTEGER
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_INTEGER
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
-
10
,
response
.
reply
(
3
).
integer
());
brpc
::
RedisResponse
response2
=
response
;
...
...
@@ -382,13 +382,13 @@ TEST_F(RedisTest, auth) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
4
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
0
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
0
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
1
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
2
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_STREQ
(
"my_redis"
,
response
.
reply
(
3
).
c_str
());
}
...
...
@@ -409,7 +409,7 @@ TEST_F(RedisTest, auth) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_ERROR
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_ERROR
,
response
.
reply
(
0
).
type
());
}
// Auth with RedisAuthenticator && clear auth
...
...
@@ -434,9 +434,9 @@ TEST_F(RedisTest, auth) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
2
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_STREQ
(
"my_redis"
,
response
.
reply
(
0
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
1
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
1
).
c_str
());
}
...
...
@@ -457,7 +457,7 @@ TEST_F(RedisTest, auth) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
1
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
0
).
type
());
ASSERT_STREQ
(
"my_redis"
,
response
.
reply
(
0
).
c_str
());
}
}
...
...
@@ -552,7 +552,7 @@ TEST_F(RedisTest, codec) {
butil
::
Arena
arena
;
// status
{
brpc
::
Redis
Reply
r
;
brpc
::
Redis
Message
r
;
butil
::
IOBuf
buf
;
ASSERT_TRUE
(
r
.
set_status
(
"OK"
,
&
arena
));
ASSERT_TRUE
(
r
.
SerializeToIOBuf
(
&
buf
));
...
...
@@ -565,7 +565,7 @@ TEST_F(RedisTest, codec) {
}
// error
{
brpc
::
Redis
Reply
r
;
brpc
::
Redis
Message
r
;
butil
::
IOBuf
buf
;
ASSERT_TRUE
(
r
.
set_error
(
"not exist
\'
key
\'
"
,
&
arena
));
ASSERT_TRUE
(
r
.
SerializeToIOBuf
(
&
buf
));
...
...
@@ -578,7 +578,7 @@ TEST_F(RedisTest, codec) {
}
// string
{
brpc
::
Redis
Reply
r
;
brpc
::
Redis
Message
r
;
butil
::
IOBuf
buf
;
ASSERT_TRUE
(
r
.
set_nil_string
());
ASSERT_TRUE
(
r
.
SerializeToIOBuf
(
&
buf
));
...
...
@@ -600,7 +600,7 @@ TEST_F(RedisTest, codec) {
}
// integer
{
brpc
::
Redis
Reply
r
;
brpc
::
Redis
Message
r
;
butil
::
IOBuf
buf
;
int
t
=
2
;
int
input
[]
=
{
-
1
,
1234567
};
...
...
@@ -619,10 +619,10 @@ TEST_F(RedisTest, codec) {
}
// array
{
brpc
::
Redis
Reply
r
;
brpc
::
Redis
Message
r
;
butil
::
IOBuf
buf
;
ASSERT_TRUE
(
r
.
set_array
(
3
,
&
arena
));
brpc
::
Redis
Reply
&
sub_reply
=
r
[
0
];
brpc
::
Redis
Message
&
sub_reply
=
r
[
0
];
sub_reply
.
set_array
(
2
,
&
arena
);
sub_reply
[
0
].
set_bulk_string
(
"hello, it's me"
,
&
arena
);
sub_reply
[
1
].
set_integer
(
422
);
...
...
@@ -668,12 +668,12 @@ public:
RedisConnectionImpl
(
RedisServiceImpl
*
rs
)
:
_rs
(
rs
)
{
}
void
OnRedisMessage
(
const
brpc
::
Redis
Reply
&
message
,
brpc
::
RedisReply
*
output
,
butil
::
Arena
*
arena
)
{
void
OnRedisMessage
(
const
brpc
::
Redis
Message
&
message
,
brpc
::
RedisMessage
*
output
,
butil
::
Arena
*
arena
)
{
if
(
!
message
.
is_array
()
||
message
.
size
()
==
0
)
{
output
->
set_error
(
"command not valid array"
,
arena
);
return
;
}
const
brpc
::
Redis
Reply
&
comm
=
message
[
0
];
const
brpc
::
Redis
Message
&
comm
=
message
[
0
];
if
(
!
comm
.
is_string
())
{
output
->
set_error
(
"command not string"
,
arena
);
return
;
...
...
@@ -752,17 +752,17 @@ TEST_F(RedisTest, server_sanity) {
channel
.
CallMethod
(
NULL
,
&
cntl
,
&
request
,
&
response
,
NULL
);
ASSERT_FALSE
(
cntl
.
Failed
())
<<
cntl
.
ErrorText
();
ASSERT_EQ
(
7
,
response
.
reply_size
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_NIL
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_NIL
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_NIL
,
response
.
reply
(
0
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_NIL
,
response
.
reply
(
1
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
2
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
2
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
3
).
type
());
ASSERT_STREQ
(
"value1"
,
response
.
reply
(
3
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STATUS
,
response
.
reply
(
4
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STATUS
,
response
.
reply
(
4
).
type
());
ASSERT_STREQ
(
"OK"
,
response
.
reply
(
4
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_STRING
,
response
.
reply
(
5
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_STRING
,
response
.
reply
(
5
).
type
());
ASSERT_STREQ
(
"value2"
,
response
.
reply
(
5
).
c_str
());
ASSERT_EQ
(
brpc
::
REDIS_
REPLY
_ERROR
,
response
.
reply
(
6
).
type
());
ASSERT_EQ
(
brpc
::
REDIS_
MESSAGE
_ERROR
,
response
.
reply
(
6
).
type
());
ASSERT_TRUE
(
butil
::
StringPiece
(
response
.
reply
(
6
).
error_message
()).
starts_with
(
"ERR unknown command"
));
ASSERT_EQ
(
rsimpl
->
call_count
,
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment