0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SystemState.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
22 #include <Common/Compat.h>
23 
24 #include "MetaLogEntityTypes.h"
25 #include "SystemState.h"
26 
27 #include <Common/Config.h>
28 #include <Common/Serialization.h>
29 
30 using namespace Hypertable;
31 using namespace std;
32 
33 SystemState::SystemState() : MetaLog::Entity(MetaLog::EntityType::SYSTEM_STATE),
34  m_generation(1) {
36  for (int i=0; i<SystemVariable::COUNT; i++) {
37  spec.code = i;
39  m_admin_specified.push_back(spec);
40  m_auto_specified.push_back(spec);
41  }
42  m_admin_last_notification.resize(SystemVariable::COUNT, 0);
43  m_auto_last_notification.resize(SystemVariable::COUNT, 0);
45  = Config::properties->get_i32("Hypertable.Master.NotificationInterval");
46 }
47 
49  : MetaLog::Entity(header_) {
51  = Config::properties->get_i32("Hypertable.Master.NotificationInterval");
52 }
53 
54 bool SystemState::admin_set(const std::vector<SystemVariable::Spec> &specs) {
55  lock_guard<mutex> lock(m_mutex);
56  bool changed = false;
57  int32_t now = (int32_t)time(0);
58  for (auto &spec : specs) {
59  HT_ASSERT(spec.code < (int)m_admin_specified.size());
60  String msg = format("System state %s=%s set administratively.",
62  spec.value ? "true" : "false");
63  if (spec.value != m_admin_specified[spec.code].value) {
64  m_notifications.push_back(NotificationMessage("System State Change", msg));
65  m_admin_last_notification[spec.code] = now;
66  m_admin_specified[spec.code].value = spec.value;
67  changed = true;
68  }
69  else if (SystemVariable::default_value(spec.code) != spec.value &&
70  now - m_admin_last_notification[spec.code] >
72  m_notifications.push_back(NotificationMessage("System State Alert", msg));
73  m_admin_last_notification[spec.code] = now;
74  }
75  }
76  if (changed)
77  m_generation++;
78  return changed;
79 }
80 
81 bool SystemState::admin_set(int code, bool value) {
82  lock_guard<mutex> lock(m_mutex);
83  int32_t now = (int32_t)time(0);
84  HT_ASSERT(code < (int)m_admin_specified.size());
85  String msg = format("System state %s=%s set administratively.",
87  value ? "true" : "false");
88  if (value != m_admin_specified[code].value) {
89  m_notifications.push_back(NotificationMessage("System State Change", msg));
90  m_admin_last_notification[code] = now;
91  m_admin_specified[code].value = value;
92  m_generation++;
93  return true;
94  }
95 
96  if (SystemVariable::default_value(code) != value &&
98  m_notifications.push_back(NotificationMessage("System State Alert", msg));
99  m_admin_last_notification[code] = now;
100  }
101 
102  return false;
103 }
104 
105 bool SystemState::auto_set(int code, bool value, const String &reason) {
106  lock_guard<mutex> lock(m_mutex);
107  String body = format("System state %s=%s %s.",
109  value ? "true" : "false", reason.c_str());
110  int32_t now = (int32_t)time(0);
111  HT_ASSERT(code < (int)m_auto_specified.size());
112  if (value != m_auto_specified[code].value) {
113  m_notifications.push_back(NotificationMessage("System State Change", body));
114  m_auto_last_notification[code] = now;
115  m_auto_specified[code].value = value;
116  m_generation++;
117  return true;
118  }
119 
120  if (SystemVariable::default_value(code) != value &&
122  m_notifications.push_back(NotificationMessage("System State Alert", body));
123  m_auto_last_notification[code] = now;
124  }
125 
126  return false;
127 }
128 
129 void SystemState::get(std::vector<SystemVariable::Spec> &specs,
130  uint64_t *generation) {
131  lock_guard<mutex> lock(m_mutex);
133  bool default_value;
134  HT_ASSERT(m_admin_specified.size() == m_auto_specified.size());
135  specs.clear();
136  for (int i=0; i<(int)m_admin_specified.size(); i++) {
137  spec.code = i;
138  default_value = SystemVariable::default_value(i);
139  if (m_admin_specified[i].value == default_value &&
140  m_auto_specified[i].value == default_value)
141  spec.value = default_value;
142  else
143  spec.value = !default_value;
144  specs.push_back(spec);
145  }
146  *generation = m_generation;
147 }
148 
149 bool SystemState::get_notifications(std::vector<NotificationMessage> &notifications) {
150  lock_guard<mutex> lock(m_mutex);
151  notifications = m_notifications;
152  m_notifications.clear();
153  return !notifications.empty();
154 }
155 
156 
157 void SystemState::get_non_default(std::vector<SystemVariable::Spec> &specs,
158  uint64_t *generation) {
159  lock_guard<mutex> lock(m_mutex);
161  bool default_value;
162  HT_ASSERT(m_admin_specified.size() == m_auto_specified.size());
163  specs.clear();
164  for (int i=0; i<(int)m_admin_specified.size(); i++) {
165  spec.code = i;
166  default_value = SystemVariable::default_value(i);
167  if (m_admin_specified[i].value != default_value ||
168  m_auto_specified[i].value != default_value) {
169  spec.value = !default_value;
170  specs.push_back(spec);
171  }
172  }
173  if (generation)
174  *generation = m_generation;
175 }
176 
177 
178 void SystemState::display(std::ostream &os) {
179  lock_guard<mutex> lock(m_mutex);
180  os << " generation=" << m_generation << " admin{";
183  os << "} auto{";
185  os << "} ";
186 }
187 
188 void SystemState::decode(const uint8_t **bufp, size_t *remainp,
189  uint16_t definition_version) {
190  if (definition_version < 4) {
191  decode_old(bufp, remainp);
192  return;
193  }
194  Entity::decode(bufp, remainp);
195 }
196 
197 
199  return 1;
200 }
201 
203  size_t length = 8;
204  length += 4;
205  for (auto &spec : m_admin_specified)
206  length += spec.encoded_length() + 4;
207  length += 4;
208  for (auto &spec : m_auto_specified)
209  length += spec.encoded_length() + 4;
210  return length;
211 }
212 
213 void SystemState::encode_internal(uint8_t **bufp) const {
216  for (size_t i=0; i<m_admin_specified.size(); i++) {
217  m_admin_specified[i].encode(bufp);
219  }
221  for (size_t i=0; i<m_auto_specified.size(); i++) {
222  m_auto_specified[i].encode(bufp);
224  }
225 }
226 
227 void SystemState::decode_internal(uint8_t version, const uint8_t **bufp,
228  size_t *remainp) {
230  m_generation = Serialization::decode_i64(bufp, remainp);
231  // Admin set
232  int count = Serialization::decode_i32(bufp, remainp);
233  for (int i=0; i<count; i++) {
234  spec.decode(bufp, remainp);
235  m_admin_specified.push_back(spec);
236  int32_t timestamp = Serialization::decode_i32(bufp, remainp);
237  m_admin_last_notification.push_back(timestamp);
238  }
239  // Add entries for newly added variables
240  for (int i=count; i<SystemVariable::COUNT; i++) {
241  spec.code = i;
242  spec.value = false;
243  m_admin_specified.push_back(spec);
244  m_admin_last_notification.push_back(0);
245  }
246  // Auto set
247  count = Serialization::decode_i32(bufp, remainp);
248  for (int i=0; i<count; i++) {
249  spec.decode(bufp, remainp);
250  m_auto_specified.push_back(spec);
251  int32_t timestamp = Serialization::decode_i32(bufp, remainp);
252  m_auto_last_notification.push_back(timestamp);
253  }
254  // Add entries for newly added variables
255  for (int i=count; i<SystemVariable::COUNT; i++) {
256  spec.code = i;
257  spec.value = false;
258  m_auto_specified.push_back(spec);
259  m_auto_last_notification.push_back(0);
260  }
261 }
262 
263 void SystemState::decode_old(const uint8_t **bufp, size_t *remainp) {
264  int32_t timestamp;
266  Serialization::decode_i32(bufp, remainp); // skip version
267  m_generation = Serialization::decode_i64(bufp, remainp);
268  // Admin set
269  int count = Serialization::decode_i32(bufp, remainp);
270  for (int i=0; i<count; i++) {
271  spec.code = Serialization::decode_i32(bufp, remainp);
272  spec.value = Serialization::decode_bool(bufp, remainp);
273  m_admin_specified.push_back(spec);
274  timestamp = Serialization::decode_i32(bufp, remainp);
275  m_admin_last_notification.push_back(timestamp);
276  }
277  // Add entries for newly added variables
278  for (int i=count; i<SystemVariable::COUNT; i++) {
279  spec.code = i;
280  spec.value = false;
281  m_admin_specified.push_back(spec);
282  m_admin_last_notification.push_back(0);
283  }
284  // Auto set
285  count = Serialization::decode_i32(bufp, remainp);
286  for (int i=0; i<count; i++) {
287  spec.code = Serialization::decode_i32(bufp, remainp);
288  spec.value = Serialization::decode_bool(bufp, remainp);
289  m_auto_specified.push_back(spec);
290  timestamp = Serialization::decode_i32(bufp, remainp);
291  m_auto_last_notification.push_back(timestamp);
292  }
293  // Add entries for newly added variables
294  for (int i=count; i<SystemVariable::COUNT; i++) {
295  spec.code = i;
296  spec.value = false;
297  m_auto_specified.push_back(spec);
298  m_auto_last_notification.push_back(0);
299  }
300 }
void display(std::ostream &os) override
Return textual representation of entity state.
Definition: SystemState.cc:178
void get(std::vector< SystemVariable::Spec > &specs, uint64_t *generation)
Get system variables and generation number.
Definition: SystemState.cc:129
std::vector< int32_t > m_auto_last_notification
Last notification times for auto set variables.
Definition: SystemState.h:181
void decode(const uint8_t **bufp, size_t *remainp, uint16_t definition_version) override
Decodes system state.
Definition: SystemState.cc:188
Master MetaLog entity type constants.
Holds a notification message to be deliverd to the administrator.
PropertiesPtr properties
This singleton map stores all options.
Definition: Config.cc:47
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
void decode_internal(uint8_t version, const uint8_t **bufp, size_t *remainp) override
Reads serialized representation of object from a buffer.
Definition: SystemState.cc:227
bool admin_set(const std::vector< SystemVariable::Spec > &specs)
Set a vector of variables by administrator.
Definition: SystemState.cc:54
int32_t code
Variable code.
bool default_value(int var_code)
Returns default value for given variable.
std::mutex m_mutex
Mutex for serializing access to members
STL namespace.
std::string specs_to_string(const std::vector< Spec > &specs)
Returns a textual representation of variable specifications.
std::vector< NotificationMessage > m_notifications
Pending notification messages.
Definition: SystemState.h:184
uint32_t decode_i32(const uint8_t **bufp, size_t *remainp)
Decode a 32-bit integer in little-endian order.
#define HT_ASSERT(_e_)
Definition: Logger.h:396
uint64_t decode_i64(const uint8_t **bufp, size_t *remainp)
Decode a 64-bit integer in little-endian order.
Declarations for SystemState.
uint64_t m_generation
Generation number incremented with each state change.
Definition: SystemState.h:169
void get_non_default(std::vector< SystemVariable::Spec > &specs, uint64_t *generation=0)
Get system state variables that are not set to their default value.
Definition: SystemState.cc:157
size_t encoded_length_internal() const override
Returns internal serialized length.
Definition: SystemState.cc:202
bool decode_bool(const uint8_t **bufp, size_t *remainp)
Decodes a boolean value from the given buffer.
Definition: Serialization.h:96
void encode_i32(uint8_t **bufp, uint32_t val)
Encode a 32-bit integer in little-endian order.
Compatibility Macros for C/C++.
void encode_i64(uint8_t **bufp, uint64_t val)
Encode a 64-bit integer in little-endian order.
Functions to serialize/deserialize primitives to/from a memory buffer.
Holds a variable code and boolean value.
std::vector< int32_t > m_admin_last_notification
Last notification times for admin set variables.
Definition: SystemState.h:175
virtual void decode(const uint8_t **bufp, size_t *remainp)
Reads serialized representation of object from a buffer.
Definition: Serializable.cc:70
void decode_old(const uint8_t **bufp, size_t *remainp)
Definition: SystemState.cc:263
void lock()
Locks the entity's mutex.
Definition: MetaLogEntity.h:97
Hypertable definitions
std::vector< SystemVariable::Spec > m_auto_specified
Automatically set state variables.
Definition: SystemState.h:178
bool auto_set(int code, bool value, const String &reason)
Set a variable by automated condition.
Definition: SystemState.cc:105
SystemState()
Constructor.
Definition: SystemState.cc:33
void encode_internal(uint8_t **bufp) const override
Writes serialized representation of object to a buffer.
Definition: SystemState.cc:213
int32_t m_notification_interval
Notification interval in seconds.
Definition: SystemState.h:187
Configuration settings.
std::vector< SystemVariable::Spec > m_admin_specified
Administratively set state variables.
Definition: SystemState.h:172
uint8_t encoding_version() const override
Returns encoding version.
Definition: SystemState.cc:198
bool get_notifications(std::vector< NotificationMessage > &notifications)
Get pending notifications.
Definition: SystemState.cc:149
const char * code_to_string(int var_code)
Converts variable code to variable string.