Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

Commit

Permalink
refactor: hide http_server from http api (#610)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wu Tao authored Sep 4, 2020
1 parent b322067 commit 84dbf0d
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 65 deletions.
13 changes: 0 additions & 13 deletions include/dsn/dist/replication/meta_service_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/*
* Description:
* What is this file about?
*
* Revision history:
* xxxx-xx-xx, author, first version
* xxxx-xx-xx, author, fix bug about xxx
*/

#pragma once

#include <dsn/cpp/service_app.h>
Expand All @@ -51,8 +41,6 @@ class test_checker;

namespace dsn {

class http_server;

namespace service {

class meta_service_app : public service_app
Expand All @@ -71,7 +59,6 @@ class meta_service_app : public service_app
private:
friend class ::dsn::replication::test::test_checker;
std::unique_ptr<dsn::replication::meta_service> _service;
std::unique_ptr<http_server> _http_server;
version_http_service *_version_http_service;
};
} // namespace service
Expand Down
2 changes: 0 additions & 2 deletions include/dsn/dist/replication/replication_service_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

namespace dsn {

class http_server;
class version_http_service;

namespace replication {
Expand Down Expand Up @@ -71,7 +70,6 @@ class replication_service_app : public ::dsn::service_app
private:
friend class ::dsn::replication::test::test_checker;
replica_stub_ptr _stub;
std::unique_ptr<http_server> _http_server;
version_http_service *_version_http_service;

static const char *replica_service_app_info(int argc, char **argv);
Expand Down
28 changes: 9 additions & 19 deletions include/dsn/http/http_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ struct http_response
http_status_code status_code{http_status_code::ok};
std::string content_type = "text/plain";
std::string location;

message_ptr to_message(message_ex *req) const;
};

typedef std::function<void(const http_request &req, http_response &resp)> http_callback;
Expand All @@ -63,6 +61,9 @@ struct http_call
http_callback callback;
};

// A suite of HTTP handlers coupled using the same prefix of the service.
// If a handler is registered with path 'app/duplication', its real path is
// "/<root_path>/app/duplication".
class http_service
{
public:
Expand All @@ -73,23 +74,12 @@ class http_service
void register_handler(std::string path, http_callback cb, std::string help);
};

class http_server : public serverlet<http_server>
{
public:
explicit http_server();

~http_server() override = default;

void add_service(http_service *service);

void serve(message_ex *msg);

private:
std::map<std::string, std::unique_ptr<http_service>> _service_map;
};
// Starts serving HTTP requests.
// The internal HTTP server will reuse the rDSN server port.
extern void start_http_server();

/// The rpc code for all the HTTP RPCs.
/// Since http is used only for system monitoring, it is restricted to lowest priority.
DEFINE_TASK_CODE_RPC(RPC_HTTP_SERVICE, TASK_PRIORITY_LOW, THREAD_POOL_DEFAULT);
// NOTE: the memory of `svc` will be transfered to the underlying registry.
// TODO(wutao): pass `svc` as a std::unique_ptr.
extern void register_http_service(http_service *svc);

} // namespace dsn
52 changes: 31 additions & 21 deletions src/http/http_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "perf_counter_http_service.h"
#include "uri_decoder.h"
#include "http_call_registry.h"
#include "http_server_impl.h"

namespace dsn {

Expand Down Expand Up @@ -63,13 +64,13 @@ http_server::http_server() : serverlet<http_server>("http_server")
tools::register_message_header_parser<http_message_parser>(NET_HDR_HTTP, {"GET ", "POST"});

// add builtin services
add_service(new root_http_service());
register_http_service(new root_http_service());

#ifdef DSN_ENABLE_GPERF
add_service(new pprof_http_service());
register_http_service(new pprof_http_service());
#endif // DSN_ENABLE_GPERF

add_service(new perf_counter_http_service());
register_http_service(new perf_counter_http_service());
}

void http_server::serve(message_ex *msg)
Expand All @@ -90,14 +91,7 @@ void http_server::serve(message_ex *msg)
}
}

message_ptr resp_msg = resp.to_message(msg);
dsn_rpc_reply(resp_msg.get());
}

void http_server::add_service(http_service *service)
{
dassert(service != nullptr, "");
_service_map.emplace(service->path(), std::unique_ptr<http_service>(service));
http_response_reply(resp, msg);
}

/*static*/ error_with<http_request> http_request::parse(message_ex *m)
Expand Down Expand Up @@ -178,25 +172,41 @@ void http_server::add_service(http_service *service)
return ret;
}

message_ptr http_response::to_message(message_ex *req) const
/*extern*/ void http_response_reply(const http_response &resp, message_ex *req)
{
message_ptr resp = req->create_response();
message_ptr resp_msg = req->create_response();

std::ostringstream os;
os << "HTTP/1.1 " << http_status_code_to_string(status_code) << "\r\n";
os << "Content-Type: " << content_type << "\r\n";
os << "Content-Length: " << body.length() << "\r\n";
if (!location.empty()) {
os << "Location: " << location << "\r\n";
os << "HTTP/1.1 " << http_status_code_to_string(resp.status_code) << "\r\n";
os << "Content-Type: " << resp.content_type << "\r\n";
os << "Content-Length: " << resp.body.length() << "\r\n";
if (!resp.location.empty()) {
os << "Location: " << resp.location << "\r\n";
}
os << "\r\n";
os << body;
os << resp.body;

rpc_write_stream writer(resp.get());
rpc_write_stream writer(resp_msg.get());
writer.write(os.str().data(), os.str().length());
writer.flush();

return resp;
dsn_rpc_reply(resp_msg.get());
}

/*extern*/ void start_http_server()
{
// starts http server as a singleton
static http_server server;
}

/*extern*/ void register_http_service(http_service *svc)
{
// simply hosting the memory of these http services.
static std::vector<std::unique_ptr<http_service>> services_holder;
static std::mutex mu;

std::lock_guard<std::mutex> guard(mu);
services_holder.push_back(std::unique_ptr<http_service>(svc));
}

} // namespace dsn
42 changes: 42 additions & 0 deletions src/http/http_server_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

#include <dsn/tool-api/rpc_message.h>
#include <dsn/cpp/serverlet.h>
#include <dsn/http/http_server.h>

namespace dsn {

class http_server : public serverlet<http_server>
{
public:
http_server();

~http_server() override = default;

void serve(message_ex *msg);
};

extern void http_response_reply(const http_response &resp, message_ex *req);

/// The rpc code for all the HTTP RPCs.
/// Since http is used only for system monitoring, it is restricted to lowest priority.
DEFINE_TASK_CODE_RPC(RPC_HTTP_SERVICE, TASK_PRIORITY_LOW, THREAD_POOL_DEFAULT);

} // namespace dsn
1 change: 1 addition & 0 deletions src/http/test/http_server_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "http/http_message_parser.h"
#include "http/root_http_service.h"
#include "http/server_info_http_services.h"
#include "http/http_server_impl.h"

namespace dsn {

Expand Down
10 changes: 5 additions & 5 deletions src/meta/meta_service_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,17 @@ void meta_service_app::register_all()
register_components();
}

meta_service_app::meta_service_app(const service_app_info *info)
: service_app(info), _http_server(new http_server())
meta_service_app::meta_service_app(const service_app_info *info) : service_app(info)
{
// create in constructor because it may be used in checker before started
_service.reset(new replication::meta_service());

// add http service
_version_http_service = new version_http_service();
_http_server->add_service(new replication::meta_http_service(_service.get()));
_http_server->add_service(new recent_start_time_http_service());
_http_server->add_service(_version_http_service);
register_http_service(new replication::meta_http_service(_service.get()));
register_http_service(new recent_start_time_http_service());
register_http_service(_version_http_service);
start_http_server();
}

meta_service_app::~meta_service_app() {}
Expand Down
9 changes: 4 additions & 5 deletions src/replica/replication_service_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ void replication_service_app::register_all()
dsn::service_app::register_factory<replication_service_app>("replica");
}

replication_service_app::replication_service_app(const service_app_info *info)
: service_app(info), _http_server(new http_server())
replication_service_app::replication_service_app(const service_app_info *info) : service_app(info)
{
_stub = new replica_stub();

// add http service
_version_http_service = new version_http_service();
_http_server->add_service(_version_http_service);
_http_server->add_service(new recent_start_time_http_service());
_http_server->add_service(new replica_http_service(_stub.get()));
register_http_service(_version_http_service);
register_http_service(new recent_start_time_http_service());
register_http_service(new replica_http_service(_stub.get()));
}

replication_service_app::~replication_service_app(void) {}
Expand Down

0 comments on commit 84dbf0d

Please sign in to comment.