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
0542ba7f
Commit
0542ba7f
authored
Jul 17, 2018
by
Ge Jun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
thrift code does not depend on TBase which is absent in thrift 0.9.3
parent
58551f87
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
117 additions
and
63 deletions
+117
-63
controller.h
src/brpc/controller.h
+4
-0
controller_private_accessor.h
src/brpc/details/controller_private_accessor.h
+0
-2
thrift_protocol.cpp
src/brpc/policy/thrift_protocol.cpp
+5
-5
thrift_message.cpp
src/brpc/thrift_message.cpp
+1
-42
thrift_message.h
src/brpc/thrift_message.h
+107
-14
No files found.
src/brpc/controller.h
View file @
0542ba7f
...
...
@@ -61,9 +61,11 @@ class RpcDumpMeta;
class
MongoContext
;
class
RetryPolicy
;
class
InputMessageBase
;
class
ThriftStub
;
namespace
policy
{
class
OnServerStreamCreated
;
void
ProcessMongoRequest
(
InputMessageBase
*
);
void
ProcessThriftRequest
(
InputMessageBase
*
);
}
namespace
schan
{
class
Sender
;
...
...
@@ -102,12 +104,14 @@ friend class ParallelChannelDone;
friend
class
ControllerPrivateAccessor
;
friend
class
ServerPrivateAccessor
;
friend
class
SelectiveChannel
;
friend
class
ThriftStub
;
friend
class
schan
::
Sender
;
friend
class
schan
::
SubDone
;
friend
class
policy
::
OnServerStreamCreated
;
friend
int
StreamCreate
(
StreamId
*
,
Controller
&
,
const
StreamOptions
*
);
friend
int
StreamAccept
(
StreamId
*
,
Controller
&
,
const
StreamOptions
*
);
friend
void
policy
::
ProcessMongoRequest
(
InputMessageBase
*
);
friend
void
policy
::
ProcessThriftRequest
(
InputMessageBase
*
);
// << Flags >>
static
const
uint32_t
FLAGS_IGNORE_EOVERCROWDED
=
1
;
static
const
uint32_t
FLAGS_SECURITY_MODE
=
(
1
<<
1
);
...
...
src/brpc/details/controller_private_accessor.h
View file @
0542ba7f
...
...
@@ -129,8 +129,6 @@ public:
_cntl
->
add_flag
(
Controller
::
FLAGS_REQUEST_WITH_AUTH
);
}
std
::
string
*
mutable_thrift_method_name
()
{
return
&
_cntl
->
_thrift_method_name
;
}
private
:
Controller
*
_cntl
;
};
...
...
src/brpc/policy/thrift_protocol.cpp
View file @
0542ba7f
...
...
@@ -116,7 +116,7 @@ WriteThriftMessageBegin(char* buf,
}
bool
ReadThriftStruct
(
const
butil
::
IOBuf
&
body
,
::
apache
::
thrift
::
T
Base
*
raw_msg
,
ThriftMessage
Base
*
raw_msg
,
int16_t
expected_fid
)
{
const
size_t
body_len
=
body
.
size
();
uint8_t
*
thrift_buffer
=
new
uint8_t
[
body_len
];
...
...
@@ -143,7 +143,7 @@ bool ReadThriftStruct(const butil::IOBuf& body,
}
if
(
fid
==
expected_fid
)
{
if
(
ftype
==
::
apache
::
thrift
::
protocol
::
T_STRUCT
)
{
xfer
+=
raw_msg
->
r
ead
(
&
iprot
);
xfer
+=
raw_msg
->
R
ead
(
&
iprot
);
success
=
true
;
}
else
{
xfer
+=
iprot
.
skip
(
ftype
);
...
...
@@ -299,7 +299,7 @@ void ThriftClosure::DoRun() {
xfer
+=
oprot
.
writeFieldBegin
(
"success"
,
::
apache
::
thrift
::
protocol
::
T_STRUCT
,
THRIFT_RESPONSE_FID
);
xfer
+=
_response
.
raw_instance
()
->
w
rite
(
&
oprot
);
xfer
+=
_response
.
raw_instance
()
->
W
rite
(
&
oprot
);
xfer
+=
oprot
.
writeFieldEnd
();
xfer
+=
oprot
.
writeFieldStop
();
xfer
+=
oprot
.
writeStructEnd
();
...
...
@@ -457,7 +457,7 @@ void ProcessThriftRequest(InputMessageBase* msg_base) {
uint32_t
seq_id
;
::
apache
::
thrift
::
protocol
::
TMessageType
mtype
;
butil
::
Status
st
=
ReadThriftMessageBegin
(
&
msg
->
payload
,
accessor
.
mutable_thrift_method_name
()
,
&
mtype
,
&
seq_id
);
&
msg
->
payload
,
&
cntl
->
_thrift_method_name
,
&
mtype
,
&
seq_id
);
if
(
!
st
.
ok
())
{
cntl
->
SetFailed
(
EREQUEST
,
"%s"
,
st
.
error_cstr
());
return
thrift_done
->
Run
();
...
...
@@ -680,7 +680,7 @@ void SerializeThriftRequest(butil::IOBuf* request_buf, Controller* cntl,
THRIFT_REQUEST_FID
);
// request's write
xfer
+=
req
->
raw_instance
()
->
w
rite
(
&
oprot
);
xfer
+=
req
->
raw_instance
()
->
W
rite
(
&
oprot
);
xfer
+=
oprot
.
writeFieldEnd
();
xfer
+=
oprot
.
writeFieldStop
();
...
...
src/brpc/thrift_message.cpp
View file @
0542ba7f
...
...
@@ -226,53 +226,12 @@ void ThriftFramedMessage::Swap(ThriftFramedMessage* other) {
return
metadata
;
}
// A wrapper closure to own the additional response required by ThriftStub
class
ThriftFramedMessageAndDone
:
public
::
google
::
protobuf
::
Closure
{
public
:
explicit
ThriftFramedMessageAndDone
(
::
google
::
protobuf
::
Closure
*
done
)
:
_done
(
done
)
{}
void
Run
()
override
{
_done
->
Run
();
}
ThriftFramedMessage
response
;
private
:
::
google
::
protobuf
::
Closure
*
_done
;
};
void
ThriftStub
::
CallMethod
(
const
char
*
method_name
,
Controller
*
cntl
,
const
::
apache
::
thrift
::
TBase
*
raw_request
,
::
apache
::
thrift
::
TBase
*
raw_response
,
::
google
::
protobuf
::
Closure
*
done
)
{
ControllerPrivateAccessor
(
cntl
).
mutable_thrift_method_name
()
->
assign
(
method_name
);
ThriftFramedMessage
request
;
request
.
_own_raw_instance
=
false
;
request
.
_raw_instance
=
const_cast
<::
apache
::
thrift
::
TBase
*>
(
raw_request
);
if
(
done
==
NULL
)
{
// response is guaranteed to be unused after a synchronous RPC, no
// need to allocate it on heap.
ThriftFramedMessage
response
;
response
.
_own_raw_instance
=
false
;
response
.
_raw_instance
=
raw_response
;
_channel
->
CallMethod
(
NULL
,
cntl
,
&
request
,
&
response
,
NULL
);
}
else
{
// Let the new_done own the response and release it after Run().
ThriftFramedMessageAndDone
*
new_done
=
new
ThriftFramedMessageAndDone
(
done
);
new_done
->
response
.
_own_raw_instance
=
false
;
new_done
->
response
.
_raw_instance
=
raw_response
;
_channel
->
CallMethod
(
NULL
,
cntl
,
&
request
,
&
new_done
->
response
,
new_done
);
}
}
void
ThriftStub
::
CallMethod
(
const
char
*
method_name
,
Controller
*
cntl
,
const
ThriftFramedMessage
*
req
,
ThriftFramedMessage
*
res
,
::
google
::
protobuf
::
Closure
*
done
)
{
ControllerPrivateAccessor
(
cntl
).
mutable_thrift_method_name
()
->
assign
(
method_name
);
cntl
->
_thrift_method_name
.
assign
(
method_name
);
_channel
->
CallMethod
(
NULL
,
cntl
,
req
,
res
,
done
);
}
...
...
src/brpc/thrift_message.h
View file @
0542ba7f
...
...
@@ -28,10 +28,18 @@
#include "google/protobuf/descriptor.pb.h"
#include "butil/iobuf.h"
#include "butil/class_name.h"
#include "brpc/channel_base.h"
#include "brpc/controller.h"
#include <thrift/TBase.h>
namespace
apache
{
namespace
thrift
{
class
TBase
;
namespace
protocol
{
class
TProtocol
;
}
}
}
namespace
brpc
{
...
...
@@ -46,6 +54,16 @@ static const int16_t THRIFT_INVALID_FID = -1;
static
const
int16_t
THRIFT_REQUEST_FID
=
1
;
static
const
int16_t
THRIFT_RESPONSE_FID
=
0
;
// Problem: TBase is absent in thrift 0.9.3
// Solution: Wrap native messages with templates into instances inheriting
// from ThriftMessageBase which can be stored and handled uniformly.
class
ThriftMessageBase
{
public
:
virtual
~
ThriftMessageBase
()
{};
virtual
uint32_t
Read
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
iprot
)
=
0
;
virtual
uint32_t
Write
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
oprot
)
const
=
0
;
};
// Representing a thrift framed request or response.
class
ThriftFramedMessage
:
public
::
google
::
protobuf
::
Message
{
friend
class
ThriftStub
;
...
...
@@ -55,10 +73,10 @@ public:
private
:
bool
_own_raw_instance
;
::
apache
::
thrift
::
T
Base
*
_raw_instance
;
ThriftMessage
Base
*
_raw_instance
;
public
:
::
apache
::
thrift
::
T
Base
*
raw_instance
()
const
{
return
_raw_instance
;
}
ThriftMessage
Base
*
raw_instance
()
const
{
return
_raw_instance
;
}
template
<
typename
T
>
T
*
Cast
();
...
...
@@ -111,10 +129,11 @@ class ThriftStub {
public
:
explicit
ThriftStub
(
ChannelBase
*
channel
)
:
_channel
(
channel
)
{}
template
<
typename
REQUEST
,
typename
RESPONSE
>
void
CallMethod
(
const
char
*
method_name
,
Controller
*
cntl
,
const
::
apache
::
thrift
::
TBase
*
raw_request
,
::
apache
::
thrift
::
TBase
*
raw_response
,
const
REQUEST
*
raw_request
,
RESPONSE
*
raw_response
,
::
google
::
protobuf
::
Closure
*
done
);
void
CallMethod
(
const
char
*
method_name
,
...
...
@@ -130,32 +149,106 @@ private:
namespace
policy
{
// Implemented in policy/thrift_protocol.cpp
bool
ReadThriftStruct
(
const
butil
::
IOBuf
&
body
,
::
apache
::
thrift
::
T
Base
*
raw_msg
,
ThriftMessage
Base
*
raw_msg
,
int16_t
expected_fid
);
}
namespace
details
{
template
<
typename
T
>
class
ThriftMessageWrapper
final
:
public
ThriftMessageBase
{
public
:
ThriftMessageWrapper
()
:
msg_ptr
(
NULL
)
{}
ThriftMessageWrapper
(
T
*
msg2
)
:
msg_ptr
(
msg2
)
{}
virtual
~
ThriftMessageWrapper
()
{}
// NOTE: "T::" makes the function call work around vtable
uint32_t
Read
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
iprot
)
override
final
{
return
msg_ptr
->
T
::
read
(
iprot
);
}
uint32_t
Write
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
oprot
)
const
override
final
{
return
msg_ptr
->
T
::
write
(
oprot
);
}
T
*
msg_ptr
;
};
template
<
typename
T
>
class
ThriftMessageHolder
final
:
public
ThriftMessageBase
{
public
:
virtual
~
ThriftMessageHolder
()
{}
// NOTE: "T::" makes the function call work around vtable
uint32_t
Read
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
iprot
)
override
final
{
return
msg
.
T
::
read
(
iprot
);
}
uint32_t
Write
(
::
apache
::
thrift
::
protocol
::
TProtocol
*
oprot
)
const
override
final
{
return
msg
.
T
::
write
(
oprot
);
}
T
msg
;
};
// A wrapper closure to own additional stuffs required by ThriftStub
template
<
typename
RESPONSE
>
class
ThriftDoneWrapper
:
public
::
google
::
protobuf
::
Closure
{
public
:
explicit
ThriftDoneWrapper
(
::
google
::
protobuf
::
Closure
*
done
)
:
_done
(
done
)
{}
void
Run
()
override
{
_done
->
Run
();
}
private
:
::
google
::
protobuf
::
Closure
*
_done
;
public
:
ThriftMessageWrapper
<
RESPONSE
>
raw_response_wrapper
;
ThriftFramedMessage
response
;
};
}
// namespace details
template
<
typename
T
>
T
*
ThriftFramedMessage
::
Cast
()
{
if
(
_raw_instance
)
{
T
*
p
=
dynamic_cast
<
T
*>
(
_raw_instance
);
auto
p
=
dynamic_cast
<
details
::
ThriftMessageHolder
<
T
>
*>
(
_raw_instance
);
if
(
p
)
{
return
p
;
return
&
p
->
msg
;
}
delete
p
;
delete
_raw_instance
;
}
T
*
raw_msg
=
new
T
;
_raw_instance
=
raw_msg
;
auto
raw_msg_wrapper
=
new
details
::
ThriftMessageHolder
<
T
>
;
T
*
raw_msg
=
&
raw_msg_wrapper
->
msg
;
_raw_instance
=
raw_msg_wrapper
;
_own_raw_instance
=
true
;
if
(
!
body
.
empty
())
{
if
(
!
policy
::
ReadThriftStruct
(
body
,
raw_msg
,
field_id
))
{
LOG
(
ERROR
)
<<
"Fail to
read xxx"
;
if
(
!
policy
::
ReadThriftStruct
(
body
,
_raw_instance
,
field_id
))
{
LOG
(
ERROR
)
<<
"Fail to
parse "
<<
butil
::
class_name
<
T
>
()
;
}
}
return
raw_msg
;
}
template
<
typename
REQUEST
,
typename
RESPONSE
>
void
ThriftStub
::
CallMethod
(
const
char
*
method_name
,
Controller
*
cntl
,
const
REQUEST
*
raw_request
,
RESPONSE
*
raw_response
,
::
google
::
protobuf
::
Closure
*
done
)
{
cntl
->
_thrift_method_name
.
assign
(
method_name
);
details
::
ThriftMessageWrapper
<
REQUEST
>
raw_request_wrapper
(
const_cast
<
REQUEST
*>
(
raw_request
));
ThriftFramedMessage
request
;
request
.
_raw_instance
=
&
raw_request_wrapper
;
if
(
done
==
NULL
)
{
// response is guaranteed to be unused after a synchronous RPC, no
// need to allocate it on heap.
ThriftFramedMessage
response
;
details
::
ThriftMessageWrapper
<
RESPONSE
>
raw_response_wrapper
(
raw_response
);
response
.
_raw_instance
=
&
raw_response_wrapper
;
_channel
->
CallMethod
(
NULL
,
cntl
,
&
request
,
&
response
,
NULL
);
}
else
{
// Let the new_done own the response and release it after Run().
details
::
ThriftDoneWrapper
<
RESPONSE
>*
new_done
=
new
details
::
ThriftDoneWrapper
<
RESPONSE
>
(
done
);
new_done
->
raw_response_wrapper
.
msg_ptr
=
raw_response
;
new_done
->
response
.
_raw_instance
=
&
new_done
->
raw_response_wrapper
;
_channel
->
CallMethod
(
NULL
,
cntl
,
&
request
,
&
new_done
->
response
,
new_done
);
}
}
}
// namespace brpc
#endif // BRPC_THRIFT_MESSAGE_H
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