GComm  0.2.3
pc_proto.hpp
1 /*
2  * Copyright (C) 2009 Codership Oy <info@codership.com>
3  */
4 
5 #ifndef GCOMM_PC_PROTO_HPP
6 #define GCOMM_PC_PROTO_HPP
7 
8 #include <list>
9 #include <ostream>
10 
11 #include "gcomm/uuid.hpp"
12 #include "gcomm/protolay.hpp"
13 #include "gcomm/conf.hpp"
14 #include "pc_message.hpp"
15 #include "defaults.hpp"
16 
17 #include "gu_uri.hpp"
18 
19 #ifndef GCOMM_PC_MAX_VERSION
20 #define GCOMM_PC_MAX_VERSION 0
21 #endif // GCOMM_PC_MAX_VERSION
22 
23 namespace gcomm
24 {
25  namespace pc
26  {
27  class Proto;
28  std::ostream& operator<<(std::ostream& os, const Proto& p);
29  }
30 }
31 
32 
33 class gcomm::pc::Proto : public Protolay
34 {
35 public:
36 
37  enum State
38  {
39  S_CLOSED,
40  S_STATES_EXCH,
41  S_INSTALL,
42  S_PRIM,
43  S_TRANS,
44  S_NON_PRIM,
45  S_MAX
46  };
47 
48  static std::string to_string(const State s)
49  {
50  switch (s)
51  {
52  case S_CLOSED: return "CLOSED";
53  case S_STATES_EXCH: return "STATES_EXCH";
54  case S_INSTALL: return "INSTALL";
55  case S_TRANS: return "TRANS";
56  case S_PRIM: return "PRIM";
57  case S_NON_PRIM: return "NON_PRIM";
58  default:
59  gu_throw_fatal << "Invalid state";
60  }
61  }
62 
63 
64  Proto(gu::Config& conf,
65  const UUID& uuid,
66  SegmentId segment,
67  const gu::URI& uri = gu::URI("pc://"))
68  :
69  Protolay(conf),
70  version_(
71  check_range(Conf::PcVersion,
72  param<int>(conf, uri, Conf::PcVersion,
73  Defaults::PcVersion),
74  0, max_version_ + 1)),
75  my_uuid_ (uuid),
76  start_prim_ (),
77  npvo_ (param<bool>(conf, uri, Conf::PcNpvo, Defaults::PcNpvo)),
78  ignore_quorum_ (param<bool>(conf, uri, Conf::PcIgnoreQuorum,
79  Defaults::PcIgnoreQuorum)),
80  ignore_sb_ (param<bool>(conf, uri, Conf::PcIgnoreSb,
81  gu::to_string(ignore_quorum_))),
82  closing_ (false),
83  state_ (S_CLOSED),
84  last_sent_seq_ (0),
85  checksum_ (param<bool>(conf, uri, Conf::PcChecksum,
86  Defaults::PcChecksum)),
87  instances_ (),
88  self_i_ (instances_.insert_unique(std::make_pair(uuid, Node()))),
89  state_msgs_ (),
90  current_view_ (V_NONE),
91  pc_view_ (V_NON_PRIM),
92  views_ (),
93  mtu_ (std::numeric_limits<int32_t>::max()),
94  weight_ (check_range(Conf::PcWeight,
95  param<int>(conf, uri, Conf::PcWeight,
96  Defaults::PcWeight),
97  0, 0xff))
98  {
99  log_info << "PC version " << version_;
100  set_weight(weight_);
101  NodeMap::value(self_i_).set_segment(segment);
102 
103  conf.set(Conf::PcVersion, gu::to_string(version_));
104  conf.set(Conf::PcNpvo, gu::to_string(npvo_));
105  conf.set(Conf::PcIgnoreQuorum, gu::to_string(ignore_quorum_));
106  conf.set(Conf::PcIgnoreSb, gu::to_string(ignore_sb_));
107  conf.set(Conf::PcChecksum, gu::to_string(checksum_));
108  conf.set(Conf::PcWeight, gu::to_string(weight_));
109  }
110 
111  ~Proto() { }
112 
113  const UUID& uuid() const { return my_uuid_; }
114 
115  bool prim() const { return NodeMap::value(self_i_).prim(); }
116 
117  void set_prim(const bool val) { NodeMap::value(self_i_).set_prim(val); }
118 
119  void mark_non_prim();
120 
121 
122  const ViewId& last_prim() const
123  { return NodeMap::value(self_i_).last_prim(); }
124 
125  void set_last_prim(const ViewId& vid)
126  {
127  gcomm_assert(vid.type() == V_PRIM);
128  NodeMap::value(self_i_).set_last_prim(vid);
129  }
130 
131  uint32_t last_seq() const
132  { return NodeMap::value(self_i_).last_seq(); }
133 
134  void set_last_seq(const uint32_t seq)
135  { NodeMap::value(self_i_).set_last_seq(seq); }
136 
137  int64_t to_seq() const
138  { return NodeMap::value(self_i_).to_seq(); }
139 
140  void set_to_seq(const int64_t seq)
141  { NodeMap::value(self_i_).set_to_seq(seq); }
142 
143  void set_weight(int weight)
144  { NodeMap::value(self_i_).set_weight(weight); }
145 
146 
147  class SMMap : public Map<const UUID, Message> { };
148 
149  const View& current_view() const { return current_view_; }
150 
151  const UUID& self_id() const { return my_uuid_; }
152 
153  State state() const { return state_; }
154 
155  void shift_to (State);
156  void send_state ();
157  void send_install(bool bootstrap, int weight = -1);
158 
159  void handle_first_trans (const View&);
160  void handle_trans (const View&);
161  void handle_reg (const View&);
162 
163  void handle_msg (const Message&, const Datagram&,
164  const ProtoUpMeta&);
165  void handle_up (const void*, const Datagram&,
166  const ProtoUpMeta&);
167  int handle_down (Datagram&, const ProtoDownMeta&);
168 
169  void connect(bool first)
170  {
171  log_debug << self_id() << " start_prim " << first;
172  start_prim_ = first;
173  closing_ = false;
174  shift_to(S_NON_PRIM);
175  }
176 
177  void close(bool force = false) { closing_ = true; }
178 
179  void handle_view (const View&);
180 
181  bool set_param(const std::string& key, const std::string& val);
182  void set_mtu(size_t mtu) { mtu_ = mtu; }
183  size_t mtu() const { return mtu_; }
184 private:
185  friend std::ostream& operator<<(std::ostream& os, const Proto& p);
186  Proto (const Proto&);
187  Proto& operator=(const Proto&);
188 
189  bool requires_rtr() const;
190  bool is_prim() const;
191  bool have_quorum(const View&, const View&) const;
192  bool have_split_brain(const View&) const;
193  void validate_state_msgs() const;
194  void cleanup_instances();
195  void handle_state(const Message&, const UUID&);
196  void handle_install(const Message&, const UUID&);
197  void handle_trans_install(const Message&, const UUID&);
198  void handle_user(const Message&, const Datagram&,
199  const ProtoUpMeta&);
200  void deliver_view(bool bootstrap = false);
201 
202  int version_;
203  static const int max_version_ = GCOMM_PC_MAX_VERSION;
204  UUID const my_uuid_; // Node uuid
205  bool start_prim_; // Is allowed to start in prim comp
206  bool npvo_; // Newer prim view overrides
207  bool ignore_quorum_; // Ignore lack of quorum
208  bool ignore_sb_; // Ignore split-brain condition
209  bool closing_; // Protocol is in closing stage
210  State state_; // State
211  uint32_t last_sent_seq_; // Msg seqno of last sent message
212  bool checksum_; // Enable message checksumming
213  NodeMap instances_; // Map of known node instances
214  NodeMap::iterator self_i_; // Iterator pointing to self node instance
215 
216  SMMap state_msgs_; // Map of received state messages
217  View current_view_; // EVS view
218  View pc_view_; // PC view
219  std::list<View> views_; // List of seen views
220  size_t mtu_; // Maximum transmission unit
221  int weight_; // Node weight in voting
222 };
223 
224 
225 #endif // PC_PROTO_HPP
Definition: view.hpp:29
static std::string const PcWeight
Node weight in prim comp voting.
Definition: conf.hpp:421
static std::string const PcVersion
PC protocol version.
Definition: conf.hpp:362
Definition: pc_message.hpp:34
static std::string const PcIgnoreSb
PC split-brain mode.
Definition: conf.hpp:370
Definition: map.hpp:210
static std::string const PcNpvo
PC newer prim view overrides.
Definition: conf.hpp:401
Configuration parameters and utility templates.
Definition: pc_proto.hpp:33
Definition: view.hpp:119
static std::string const PcIgnoreQuorum
PC quorum mode.
Definition: conf.hpp:378
static std::string const PcChecksum
PC message checksumming.
Definition: conf.hpp:386
Definition: protolay.hpp:192
Protocol layer interface definitions.
Definition: pc_proto.hpp:147
#define gcomm_assert(cond_)
Definition: exception.hpp:21
Definition: uuid.hpp:26