MongoDB  2.0.3
message_port.h
00001 // message_port.h
00002 
00003 /*    Copyright 2009 10gen Inc.
00004  *
00005  *    Licensed under the Apache License, Version 2.0 (the "License");
00006  *    you may not use this file except in compliance with the License.
00007  *    You may obtain a copy of the License at
00008  *
00009  *    http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  *    Unless required by applicable law or agreed to in writing, software
00012  *    distributed under the License is distributed on an "AS IS" BASIS,
00013  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *    See the License for the specific language governing permissions and
00015  *    limitations under the License.
00016  */
00017 
00018 #pragma once
00019 
00020 #include "sock.h"
00021 #include "message.h"
00022 
00023 namespace mongo {
00024 
00025     class MessagingPort;
00026     class PiggyBackData;
00027 
00028     typedef AtomicUInt MSGID;
00029 
00030     class AbstractMessagingPort : boost::noncopyable {
00031     public:
00032         AbstractMessagingPort() : tag(0) {}
00033         virtual ~AbstractMessagingPort() { }
00034         virtual void reply(Message& received, Message& response, MSGID responseTo) = 0; // like the reply below, but doesn't rely on received.data still being available
00035         virtual void reply(Message& received, Message& response) = 0;
00036 
00037         virtual HostAndPort remote() const = 0;
00038         virtual unsigned remotePort() const = 0;
00039 
00040     private:
00041 
00042     public:
00043         // TODO make this private with some helpers
00044 
00045         /* ports can be tagged with various classes.  see closeAllSockets(tag). defaults to 0. */
00046         unsigned tag;
00047 
00048     };
00049 
00050     class MessagingPort : public AbstractMessagingPort , public Socket {
00051     public:
00052         MessagingPort(int fd, const SockAddr& remote);
00053 
00054         // in some cases the timeout will actually be 2x this value - eg we do a partial send,
00055         // then the timeout fires, then we try to send again, then the timeout fires again with
00056         // no data sent, then we detect that the other side is down
00057         MessagingPort(double so_timeout = 0, int logLevel = 0 );
00058 
00059         MessagingPort(Socket& socket);
00060 
00061         virtual ~MessagingPort();
00062 
00063         void shutdown();
00064 
00065         /* it's assumed if you reuse a message object, that it doesn't cross MessagingPort's.
00066            also, the Message data will go out of scope on the subsequent recv call.
00067         */
00068         bool recv(Message& m);
00069         void reply(Message& received, Message& response, MSGID responseTo);
00070         void reply(Message& received, Message& response);
00071         bool call(Message& toSend, Message& response);
00072 
00073         void say(Message& toSend, int responseTo = -1);
00074 
00084         bool recv( const Message& sent , Message& response );
00085 
00086         void piggyBack( Message& toSend , int responseTo = -1 );
00087 
00088         unsigned remotePort() const { return Socket::remotePort(); }
00089         virtual HostAndPort remote() const;
00090 
00091 
00092     private:
00093         
00094         PiggyBackData * piggyBackData;
00095         
00096         // this is the parsed version of remote
00097         // mutable because its initialized only on call to remote()
00098         mutable HostAndPort _remoteParsed; 
00099 
00100     public:
00101         static void closeAllSockets(unsigned tagMask = 0xffffffff);
00102 
00103         friend class PiggyBackData;
00104     };
00105 
00106 
00107 } // namespace mongo