diff options
-rw-r--r-- | src/mongo/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/transport/SConscript | 13 | ||||
-rw-r--r-- | src/mongo/transport/ingress_header_test.cpp | 43 | ||||
-rw-r--r-- | src/mongo/transport/service_entry_point.h | 61 | ||||
-rw-r--r-- | src/mongo/transport/session.h | 84 | ||||
-rw-r--r-- | src/mongo/transport/ticket.h | 72 | ||||
-rw-r--r-- | src/mongo/transport/ticket_impl.h | 65 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer.h | 152 |
8 files changed, 491 insertions, 0 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 19bb5577f93..a06466d0f6c 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -36,6 +36,7 @@ env.SConscript( 'scripting', 'shell', 'tools', + 'transport', 'unittest', 'util', ], diff --git a/src/mongo/transport/SConscript b/src/mongo/transport/SConscript new file mode 100644 index 00000000000..04d780779fc --- /dev/null +++ b/src/mongo/transport/SConscript @@ -0,0 +1,13 @@ +# -*- mode: python -*- + +Import('env') + +env.CppUnitTest( + target='ingress_header_test', + source=[ + 'ingress_header_test.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/util/foundation', + ], +) diff --git a/src/mongo/transport/ingress_header_test.cpp b/src/mongo/transport/ingress_header_test.cpp new file mode 100644 index 00000000000..fae28ea3a77 --- /dev/null +++ b/src/mongo/transport/ingress_header_test.cpp @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/transport/service_entry_point.h" +#include "mongo/transport/session.h" +#include "mongo/transport/ticket.h" +#include "mongo/transport/transport_layer.h" +#include "mongo/unittest/unittest.h" + +namespace { + +TEST(IngressHeaderTest, TestHeaders) { + // No-op. +} + +} // namespace diff --git a/src/mongo/transport/service_entry_point.h b/src/mongo/transport/service_entry_point.h new file mode 100644 index 00000000000..a1c031c5e3e --- /dev/null +++ b/src/mongo/transport/service_entry_point.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/base/disallow_copying.h" + +namespace mongo { + +namespace transport { +class Session; +} // namespace transport + +/** + * This is the entrypoint from the transport layer into mongod or mongos. + * + * The ServiceEntryPoint accepts new Sessions from the TransportLayer, and is + * responsible for running these Sessions in a get-Message, run-Message, + * reply-with-Message loop. It may not do this on the TransportLayer’s thread. + */ +class ServiceEntryPoint { + MONGO_DISALLOW_COPYING(ServiceEntryPoint); + +public: + virtual ~ServiceEntryPoint() = default; + + /** + * Begin running a new Session. This method returns immediately. + */ + virtual void startSession(transport::Session&& session) = 0; + +protected: + ServiceEntryPoint() = default; +}; + +} // namespace mongo diff --git a/src/mongo/transport/session.h b/src/mongo/transport/session.h new file mode 100644 index 00000000000..bb3a8ce3ee4 --- /dev/null +++ b/src/mongo/transport/session.h @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/util/net/hostandport.h" + +namespace mongo { +namespace transport { + +class TransportLayer; + +/** + * This type contains data needed to associate Messages with connections + * (on the transport side) and Messages with Client objects (on the database side). + */ +class Session { +public: + /** + * Type to indicate the internal id for this session. + */ + using SessionId = uint64_t; + + /** + * Construct a new session. + */ + Session(HostAndPort remote, HostAndPort local, TransportLayer* tl); + + /** + * Destroys a session, calling end() for this session in its TransportLayer. + */ + ~Session(); + + /** + * Return the id for this session. + */ + SessionId id() const; + + /** + * Return the remote host for this session. + */ + const HostAndPort& remote() const; + + /** + * Return the local host information for this session. + */ + const HostAndPort& local() const; + +private: + SessionId _id; + + HostAndPort _remote; + HostAndPort _local; + + TransportLayer* _tl; +}; + +} // namespace transport +} // namespace mongo diff --git a/src/mongo/transport/ticket.h b/src/mongo/transport/ticket.h new file mode 100644 index 00000000000..68345f46b83 --- /dev/null +++ b/src/mongo/transport/ticket.h @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/transport/session.h" +#include "mongo/util/time_support.h" + +namespace mongo { +namespace transport { + +class TicketImpl; + +/** + * A Ticket represents some work to be done within the TransportLayer. + * Run Tickets by passing them in a call to either TransportLayer::wait() + * or TransportLayer::asyncWait(). + */ +class Ticket { + MONGO_DISALLOW_COPYING(Ticket); + +public: + using SessionId = Session::SessionId; + + /** + * Indicates that there is no expiration time by when a ticket needs to complete. + */ + static const Date_t kNoExpirationDate; + + Ticket(std::unique_ptr<TicketImpl> ticket); + + /** + * Return this ticket's session id. + */ + SessionId sessionId() const; + + /** + * Return this ticket's expiration date. + */ + Date_t expiration() const; + +private: + std::unique_ptr<TicketImpl> _ticket; +}; + +} // namespace transport +} // namespace mongo diff --git a/src/mongo/transport/ticket_impl.h b/src/mongo/transport/ticket_impl.h new file mode 100644 index 00000000000..bd3c9306ac3 --- /dev/null +++ b/src/mongo/transport/ticket_impl.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/transport/session.h" +#include "mongo/util/time_support.h" + +namespace mongo { +namespace transport { + +/** + * Interface representing implementations of Ticket. + * + * Ticket implementations are specific to a TransportLayer implementation. + */ +class TicketImpl { + MONGO_DISALLOW_COPYING(TicketImpl); + +public: + using SessionId = Session::SessionId; + + virtual ~Ticket() = default; + + /** + * Return this ticket's session id. + */ + virtual SessionId sessionId() const = 0; + + /** + * Return this ticket's expiration date. + */ + virtual Date_t expiration() const = 0; + +protected: + TicketImpl() = default; +}; + +} // namespace transport +} // namespace mongo diff --git a/src/mongo/transport/transport_layer.h b/src/mongo/transport/transport_layer.h new file mode 100644 index 00000000000..0cd3745240a --- /dev/null +++ b/src/mongo/transport/transport_layer.h @@ -0,0 +1,152 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/base/status.h" +#include "mongo/stdx/functional.h" +#include "mongo/transport/session.h" +#include "mongo/transport/ticket.h" +#include "mongo/util/net/message.h" +#include "mongo/util/time_support.h" + +namespace mongo { +namespace transport { + +/** + * The TransportLayer moves Messages between transport::Endpoints and the database. + * This class owns an Acceptor that generates new endpoints from which it can + * source Messages. + * + * The TransportLayer creates Session objects and maps them internally to + * endpoints. New Sessions are passed to the database (via a ServiceEntryPoint) + * to be run. The database must then call additional methods on the TransportLayer + * to manage the Session in a get-Message, handle-Message, return-Message cycle. + * It must do this on its own thread(s). + * + * References to the TransportLayer should be stored on service context objects. + */ +class TransportLayer { + MONGO_DISALLOW_COPYING(TransportLayer); + +public: + virtual ~TransportLayer() = default; + + /** + * Source (receive) a new Message for this Session. + * + * This method returns a work Ticket. The caller must complete the Ticket by + * passing it to either TransportLayer::wait() or TransportLayer::asyncWait(). + * + * If an expiration date is given, the returned Ticket will expire at that time. + * + * When run, the returned Ticket will be exchanged for a Status. If the + * TransportLayer is unable to source a Message, this will be a failed status, + * and the passed-in Message buffer may be left in an invalid state. + */ + virtual Ticket sourceMessage(const Session& session, + Message* message, + Date_t expiration = Ticket::kNoExpirationDate) = 0; + + /** + * Sink (send) a new Message for this Session. This method should be used + * to send replies to a given host. + * + * This method returns a work Ticket. The caller must complete the Ticket by + * passing it to either TransportLayer::wait() or TransportLayer::asyncWait(). + * + * If an expiration date is given, the returned Ticket will expire at that time. + * + * When run, the returned Ticket will be exchanged for a Status. If the + * TransportLayer is unable to sink the Message, this will be a failed status. + * + * This method does NOT take ownership of the sunk Message, which must be cleaned + * up by the caller. + */ + virtual Ticket sinkMessage(const Session& session, + const Message& message, + Date_t expiration = Ticket::kNoExpirationDate) = 0; + + /** + * Perform a synchronous wait on the given work Ticket. When this call returns, + * the Ticket will have been completed. A call to wait() consumes the Ticket. + * + * This thread may be used by the TransportLayer to run other Tickets that were + * enqueued prior to this call. + */ + virtual Status wait(Ticket ticket) = 0; + + /** + * Callback for Tickets that are run via asyncWait(). + */ + using TicketCallback = stdx::function<void(Status)>; + + /** + * Perform an asynchronous wait on the given work Ticket. Once the Ticket has been + * completed, the passed-in callback will be invoked. + * + * This thread will not be used by the TransportLayer to perform work. The callback + * passed to asyncWait() may be run on any thread. + */ + virtual void asyncWait(Ticket ticket, TicketCallback callback) = 0; + + /** + * End the given Session. Tickets for this Session that have already been + * started via wait() or asyncWait() will complete, but may return a failed Status. + * Future calls to wait() or asyncWait() for this Session will fail. If this + * TransportLayer implementation is networked, any connections for this Session will + * be closed. + * + * ~Session() will automatically call end() with itself. + * + * This method is idempotent and synchronous. + */ + virtual void end(const Session& session) = 0; + + /** + * End all active sessions in the TransportLayer. Tickets that have already been + * started via wait() or asyncWait() will complete, but may return a failed Status. + * This method is synchronous and will not return until all sessions have ended. + */ + virtual void endAllSessions() = 0; + + /** + * Shut the TransportLayer down. After this point, the TransportLayer will + * end all active sessions and won't accept new transport::Endpoints. Any + * future calls to wait() or asyncWait() will fail. This method is synchronous and + * will not return until all sessions have ended and any network connections have been + * closed. + */ + virtual void shutdown() = 0; + +protected: + TransportLayer() = default; +}; + +} // namespace transport +} // namespace mongo |