00001 #ifndef QPID_CLUSTER_CLUSTER_H
00002 #define QPID_CLUSTER_CLUSTER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qpid/cluster/types.h"
00023 #include "qpid/cluster/Cpg.h"
00024 #include "qpid/cluster/PollableQueue.h"
00025 #include "qpid/cluster/NoOpConnectionOutputHandler.h"
00026
00027 #include "qpid/broker/Broker.h"
00028 #include "qpid/sys/Monitor.h"
00029 #include "qpid/framing/AMQP_AllOperations.h"
00030 #include "qpid/Url.h"
00031
00032 #include <boost/intrusive_ptr.hpp>
00033
00034 #include <map>
00035 #include <vector>
00036
00037 namespace qpid {
00038 namespace cluster {
00039
00040 class Connection;
00041
00046 class Cluster : public RefCounted, private Cpg::Handler
00047 {
00048 public:
00049
00055 Cluster(const std::string& name, const Url& url, broker::Broker&);
00056
00057 virtual ~Cluster();
00058
00059 void insert(const boost::intrusive_ptr<Connection>&);
00060 void erase(ConnectionId);
00061
00063 std::vector<Url> getUrls() const;
00064
00066 size_t size() const;
00067
00068 bool empty() const { return size() == 0; }
00069
00071 void send(const framing::AMQFrame&, const ConnectionId&);
00072
00074 void leave();
00075
00076 void joined(const MemberId&, const std::string& url);
00077
00078 broker::Broker& getBroker() { assert(broker); return *broker; }
00079
00080 MemberId getSelf() const { return self; }
00081
00082 private:
00083 typedef std::map<MemberId, Url> UrlMap;
00084 typedef std::map<ConnectionId, boost::intrusive_ptr<cluster::Connection> > ConnectionMap;
00085
00087 typedef std::pair<framing::AMQFrame, ConnectionId> Message;
00088 typedef PollableQueue<Message> MessageQueue;
00089
00090 boost::function<void()> shutdownNext;
00091
00093 void deliver(
00094 cpg_handle_t ,
00095 struct cpg_name *group,
00096 uint32_t ,
00097 uint32_t ,
00098 void* ,
00099 int );
00100
00102 void configChange(
00103 cpg_handle_t ,
00104 struct cpg_name *,
00105 struct cpg_address *, int ,
00106 struct cpg_address *, int ,
00107 struct cpg_address *, int
00108 );
00109
00111 void deliverQueueCb(const MessageQueue::iterator& begin,
00112 const MessageQueue::iterator& end);
00113
00115 void mcastQueueCb(const MessageQueue::iterator& begin,
00116 const MessageQueue::iterator& end);
00117
00118
00120 void dispatch(sys::DispatchHandle&);
00122 void disconnect(sys::DispatchHandle&);
00123
00124 void handleMethod(MemberId from, cluster::Connection* connection, framing::AMQMethodBody& method);
00125
00126 boost::intrusive_ptr<cluster::Connection> getConnection(const ConnectionId&);
00127
00128 mutable sys::Monitor lock;
00129 broker::Broker* broker;
00130 boost::shared_ptr<sys::Poller> poller;
00131 Cpg cpg;
00132 Cpg::Name name;
00133 Url url;
00134 UrlMap urls;
00135 MemberId self;
00136 ConnectionMap connections;
00137 NoOpConnectionOutputHandler shadowOut;
00138 sys::DispatchHandle cpgDispatchHandle;
00139 MessageQueue deliverQueue;
00140 MessageQueue mcastQueue;
00141
00142 friend std::ostream& operator <<(std::ostream&, const Cluster&);
00143 friend std::ostream& operator <<(std::ostream&, const UrlMap::value_type&);
00144 friend std::ostream& operator <<(std::ostream&, const UrlMap&);
00145 };
00146
00147 }}
00148
00149
00150
00151 #endif