Commit fdd8e84b authored by James Sedgwick's avatar James Sedgwick Committed by Praveen Kumar Ramakrishnan

use inbound/outbound handlers in a few more places

Summary: Also, instead of throwing on finalize() if there's no inbound/outbound handler in the pipeline, log a warning and throw when the operations are attempted. This was necessary for CodecTest which doesn't use outbound handlers.

Test Plan: unit

Reviewed By: davejwatson@fb.com

Subscribers: trunkagent, fugalh, folly-diffs@, jsedgwick, yfeldblum, chalfant

FB internal diff: D2028176

Tasks: 6836580

Signature: t1:2028176:1430346333:fdd645a535e8158d780cfd1119e27803995b663f
parent 555213ca
...@@ -28,7 +28,7 @@ namespace folly { ...@@ -28,7 +28,7 @@ namespace folly {
template <typename Pipeline> template <typename Pipeline>
class ServerAcceptor class ServerAcceptor
: public Acceptor : public Acceptor
, public folly::wangle::HandlerAdapter<void*, std::exception> { , public folly::wangle::InboundHandler<void*> {
typedef std::unique_ptr<Pipeline, typedef std::unique_ptr<Pipeline,
folly::DelayedDestruction::Destructor> PipelinePtr; folly::DelayedDestruction::Destructor> PipelinePtr;
...@@ -86,10 +86,6 @@ class ServerAcceptor ...@@ -86,10 +86,6 @@ class ServerAcceptor
Acceptor::addConnection(connection); Acceptor::addConnection(connection);
} }
folly::Future<void> write(Context* ctx, std::exception e) {
return ctx->fireWrite(e);
}
/* See Acceptor::onNewConnection for details */ /* See Acceptor::onNewConnection for details */
void onNewConnection( void onNewConnection(
AsyncSocket::UniquePtr transport, const SocketAddress* address, AsyncSocket::UniquePtr transport, const SocketAddress* address,
......
...@@ -159,7 +159,7 @@ class HandlerAdapter : public Handler<R, R, W, W> { ...@@ -159,7 +159,7 @@ class HandlerAdapter : public Handler<R, R, W, W> {
typedef HandlerAdapter<IOBufQueue&, std::unique_ptr<IOBuf>> typedef HandlerAdapter<IOBufQueue&, std::unique_ptr<IOBuf>>
BytesToBytesHandler; BytesToBytesHandler;
typedef InboundHandler<IOBufQueue&> typedef InboundHandler<IOBufQueue&, std::unique_ptr<IOBuf>>
InboundBytesToBytesHandler; InboundBytesToBytesHandler;
typedef OutboundHandler<std::unique_ptr<IOBuf>> typedef OutboundHandler<std::unique_ptr<IOBuf>>
......
...@@ -62,22 +62,38 @@ class Pipeline : public DelayedDestruction { ...@@ -62,22 +62,38 @@ class Pipeline : public DelayedDestruction {
} }
void read(R msg) { void read(R msg) {
if (!front_) {
throw std::invalid_argument("read(): no inbound handler in Pipeline");
}
front_->read(std::forward<R>(msg)); front_->read(std::forward<R>(msg));
} }
void readEOF() { void readEOF() {
if (!front_) {
throw std::invalid_argument("readEOF(): no inbound handler in Pipeline");
}
front_->readEOF(); front_->readEOF();
} }
void readException(exception_wrapper e) { void readException(exception_wrapper e) {
if (!front_) {
throw std::invalid_argument(
"readException(): no inbound handler in Pipeline");
}
front_->readException(std::move(e)); front_->readException(std::move(e));
} }
Future<void> write(W msg) { Future<void> write(W msg) {
if (!back_) {
throw std::invalid_argument("write(): no outbound handler in Pipeline");
}
return back_->write(std::forward<W>(msg)); return back_->write(std::forward<W>(msg));
} }
Future<void> close() { Future<void> close() {
if (!back_) {
throw std::invalid_argument("close(): no outbound handler in Pipeline");
}
return back_->close(); return back_->close();
} }
...@@ -138,10 +154,12 @@ class Pipeline : public DelayedDestruction { ...@@ -138,10 +154,12 @@ class Pipeline : public DelayedDestruction {
} }
if (!front_) { if (!front_) {
throw std::invalid_argument("no inbound handler in Pipeline"); LOG(WARNING) << "No inbound handler in Pipeline, "
"inbound operations will throw std::invalid_argument";
} }
if (!back_) { if (!back_) {
throw std::invalid_argument("no outbound handler in Pipeline"); LOG(WARNING) << "No outbound handler in Pipeline, "
"outbound operations will throw std::invalid_argument";
} }
for (auto it = ctxs_.rbegin(); it != ctxs_.rend(); it++) { for (auto it = ctxs_.rbegin(); it != ctxs_.rend(); it++) {
......
...@@ -250,6 +250,13 @@ TEST(PipelineTest, HandlerInPipelineTwice) { ...@@ -250,6 +250,13 @@ TEST(PipelineTest, HandlerInPipelineTwice) {
EXPECT_CALL(handler, detachPipeline(_)).Times(2); EXPECT_CALL(handler, detachPipeline(_)).Times(2);
} }
TEST(PipelineTest, NoDetachOnOwner) {
IntHandler handler;
EXPECT_CALL(handler, attachPipeline(_));
StaticPipeline<int, int, IntHandler> pipeline(&handler);
pipeline.setOwner(&handler);
}
template <class Rin, class Rout = Rin, class Win = Rout, class Wout = Rin> template <class Rin, class Rout = Rin, class Win = Rout, class Wout = Rin>
class ConcreteHandler : public Handler<Rin, Rout, Win, Wout> { class ConcreteHandler : public Handler<Rin, Rout, Win, Wout> {
typedef typename Handler<Rin, Rout, Win, Wout>::Context Context; typedef typename Handler<Rin, Rout, Win, Wout>::Context Context;
...@@ -262,22 +269,21 @@ typedef HandlerAdapter<std::string, std::string> StringHandler; ...@@ -262,22 +269,21 @@ typedef HandlerAdapter<std::string, std::string> StringHandler;
typedef ConcreteHandler<int, std::string> IntToStringHandler; typedef ConcreteHandler<int, std::string> IntToStringHandler;
typedef ConcreteHandler<std::string, int> StringToIntHandler; typedef ConcreteHandler<std::string, int> StringToIntHandler;
TEST(Pipeline, DynamicConstruction) { TEST(Pipeline, MissingInboundOrOutbound) {
{
Pipeline<int, int> pipeline; Pipeline<int, int> pipeline;
EXPECT_THROW(
pipeline pipeline
.addBack(HandlerAdapter<std::string, std::string>{}) .addBack(HandlerAdapter<std::string, std::string>{})
.finalize(), std::invalid_argument); .finalize();
} EXPECT_THROW(pipeline.read(0), std::invalid_argument);
{ EXPECT_THROW(pipeline.readEOF(), std::invalid_argument);
Pipeline<int, int> pipeline;
EXPECT_THROW( EXPECT_THROW(
pipeline pipeline.readException(exception_wrapper(std::runtime_error("blah"))),
.addFront(HandlerAdapter<std::string, std::string>{})
.finalize(),
std::invalid_argument); std::invalid_argument);
} EXPECT_THROW(pipeline.write(0), std::invalid_argument);
EXPECT_THROW(pipeline.close(), std::invalid_argument);
}
TEST(Pipeline, DynamicConstruction) {
{ {
StaticPipeline<std::string, std::string, StringHandler, StringHandler> StaticPipeline<std::string, std::string, StringHandler, StringHandler>
pipeline{StringHandler(), StringHandler()}; pipeline{StringHandler(), StringHandler()};
......
...@@ -23,8 +23,7 @@ void ByteToMessageCodec::read(Context* ctx, IOBufQueue& q) { ...@@ -23,8 +23,7 @@ void ByteToMessageCodec::read(Context* ctx, IOBufQueue& q) {
while (true) { while (true) {
result = decode(ctx, q, needed); result = decode(ctx, q, needed);
if (result) { if (result) {
q_.append(std::move(result)); ctx->fireRead(std::move(result));
ctx->fireRead(q_);
} else { } else {
break; break;
} }
......
...@@ -47,9 +47,6 @@ class ByteToMessageCodec ...@@ -47,9 +47,6 @@ class ByteToMessageCodec
Context* ctx, IOBufQueue& buf, size_t&) = 0; Context* ctx, IOBufQueue& buf, size_t&) = 0;
void read(Context* ctx, IOBufQueue& q); void read(Context* ctx, IOBufQueue& q);
private:
IOBufQueue q_;
}; };
}} }}
...@@ -25,13 +25,13 @@ using namespace folly::wangle; ...@@ -25,13 +25,13 @@ using namespace folly::wangle;
using namespace folly::io; using namespace folly::io;
class FrameTester class FrameTester
: public BytesToBytesHandler { : public InboundHandler<std::unique_ptr<IOBuf>> {
public: public:
FrameTester(std::function<void(std::unique_ptr<IOBuf>)> test) explicit FrameTester(std::function<void(std::unique_ptr<IOBuf>)> test)
: test_(test) {} : test_(test) {}
void read(Context* ctx, IOBufQueue& q) { void read(Context* ctx, std::unique_ptr<IOBuf> buf) {
test_(q.move()); test_(std::move(buf));
} }
void readException(Context* ctx, exception_wrapper w) { void readException(Context* ctx, exception_wrapper w) {
......
...@@ -26,11 +26,11 @@ namespace folly { namespace wangle { ...@@ -26,11 +26,11 @@ namespace folly { namespace wangle {
* only one request is allowed at a time. * only one request is allowed at a time.
*/ */
template <typename Pipeline, typename Req, typename Resp = Req> template <typename Pipeline, typename Req, typename Resp = Req>
class SerialClientDispatcher : public HandlerAdapter<Req, Resp> class SerialClientDispatcher : public InboundHandler<Req>
, public Service<Req, Resp> { , public Service<Req, Resp> {
public: public:
typedef typename HandlerAdapter<Req, Resp>::Context Context; typedef typename InboundHandler<Req>::Context Context;
void setPipeline(Pipeline* pipeline) { void setPipeline(Pipeline* pipeline) {
pipeline_ = pipeline; pipeline_ = pipeline;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment