0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
OperationToggleTableMaintenance.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 
26 
27 #include <Common/Compat.h>
29 
32 
34 #include <Hypertable/Lib/Key.h>
35 
36 #include <Hyperspace/Session.h>
37 
38 #include <Common/Error.h>
39 #include <Common/FailureInducer.h>
40 #include <Common/ScopeGuard.h>
41 #include <Common/Serialization.h>
42 
43 #include <boost/algorithm/string.hpp>
44 
45 #include <chrono>
46 #include <thread>
47 
48 using namespace Hypertable;
49 using namespace Hypertable::Lib;
50 using namespace Hyperspace;
51 using namespace std;
52 
54  const std::string &table_name,
55  bool toggle_on)
56  : Operation(context, MetaLog::EntityType::OPERATION_TOGGLE_TABLE_MAINTENANCE),
57  m_name(table_name), m_toggle_on(toggle_on) {
60 }
61 
63  const MetaLog::EntityHeader &header)
64  : Operation(context, header) {
65 }
66 
67 
125  bool is_namespace;
126  int32_t state = get_state();
127 
128  HT_INFOF("Entering ToggleTableMaintenance-%lld (table=%s %s) state=%s",
129  (Lld)header.id, m_name.c_str(), m_toggle_on ? "ON" : "OFF",
130  OperationState::get_text(state));
131 
132  switch (state) {
133 
135  if (m_context->namemap->name_to_id(m_name, m_id, &is_namespace)) {
136  if (is_namespace) {
137  complete_error(Error::TABLE_NOT_FOUND, format("%s is a namespace", m_name.c_str()));
138  break;
139  }
140  }
141  else {
143  break;
144  }
146  m_context->mml_writer->record_state(shared_from_this());
147  HT_MAYBE_FAIL("toggle-table-maintenance-INITIAL");
148 
149  // drop through ...
150 
152  try {
153  String tablefile = m_context->toplevel_dir + "/tables/" + m_id;
154  if (m_toggle_on) {
155  uint64_t handle = 0;
157  handle = m_context->hyperspace->open(tablefile, OPEN_FLAG_READ);
158  m_context->hyperspace->attr_del(handle, "maintenance_disabled");
159  }
160  else
161  m_context->hyperspace->attr_set(tablefile, "maintenance_disabled", "1", 1);
162  }
163  catch (Exception &e) {
165  HT_ERRORF("Problem %s 'maintenance_disabled' attr for %s (%s, %s)",
166  m_toggle_on ? "setting" : "deleting", m_id.c_str(),
167  Error::get_text(e.code()), e.what());
168  complete_error(e);
169  break;
170  }
171  }
172  HT_MAYBE_FAIL("toggle-table-maintenance-UPDATE_HYPERSPACE-1");
173  {
174  lock_guard<mutex> lock(m_mutex);
177  m_dependencies.insert(m_id + " move range");
179  }
180  m_context->mml_writer->record_state(shared_from_this());
181  HT_MAYBE_FAIL("toggle-table-maintenance-UPDATE_HYPERSPACE-2");
182  break;
183 
185  {
186  std::set<std::string> servers;
187 
188  // Determine servers that hold the table's ranges
189  if (!m_context->test_mode)
191  else
192  m_context->get_available_servers(servers);
193 
194  // Populate m_servers and m_dependencies
195  {
196  lock_guard<mutex> lock(m_mutex);
197  m_servers.clear();
198  for (auto &server : servers) {
199  if (m_completed.count(server))
200  m_dependencies.erase(server);
201  else {
202  m_servers.insert(server);
203  m_dependencies.insert(server);
204  }
205  }
207  }
208  }
209  m_context->mml_writer->record_state(shared_from_this());
210  HT_MAYBE_FAIL("toggle-table-maintenance-SCAN_METADATA");
211  break;
212 
214  if (!m_context->test_mode) {
215  TableIdentifier table;
216  table.id = m_id.c_str();
217  table.generation = 0;
218  DispatchHandlerOperationPtr op_handler =
219  make_shared<DispatchHandlerOperationToggleTableMaintenance>(m_context, table, m_toggle_on);
220  op_handler->start(m_servers);
221  if (!op_handler->wait_for_completion()) {
222  std::set<DispatchHandlerOperation::Result> results;
223  op_handler->get_results(results);
224  for (auto &result : results) {
225  if (result.error == Error::OK) {
226  lock_guard<mutex> lock(m_mutex);
227  m_completed.insert(result.location);
228  }
229  else
230  HT_WARNF("Error at %s - %s (%s)", result.location.c_str(),
231  Error::get_text(result.error), result.msg.c_str());
232  }
233 
234  {
235  lock_guard<mutex> lock(m_mutex);
236  for (auto s : m_servers)
237  m_dependencies.erase(s);
239  m_servers.clear();
241  }
242  this_thread::sleep_for(chrono::milliseconds(5000));
243  m_context->mml_writer->record_state(shared_from_this());
244  break;
245  }
246  }
247  HT_MAYBE_FAIL("toggle-table-maintenance-ISSUE_REQUESTS");
248  complete_ok();
249  break;
250 
251  default:
252  HT_FATALF("Unrecognized state %d", state);
253  }
254 
255  HT_INFOF("Leaving ToggleTableMaintenance-%lld (table=%s %s) state=%s",
256  (Lld)header.id, m_name.c_str(), m_toggle_on ? "ON" : "OFF",
258 }
259 
260 
262  os << " table_name=" << m_name << " table_id=" << m_id
263  << " " << (m_toggle_on ? "ON" : "OFF");
264 }
265 
267  return 1;
268 }
269 
271  size_t length = 1 + Serialization::encoded_length_vstr(m_name) +
273  length += 4;
274  for (const auto &location : m_servers)
275  length += Serialization::encoded_length_vstr(location);
276  length += 4;
277  for (const auto &location : m_completed)
278  length += Serialization::encoded_length_vstr(location);
279  return length;
280 }
281 
286  Serialization::encode_i32(bufp, m_servers.size());
287  for (const auto &location : m_servers)
288  Serialization::encode_vstr(bufp, location);
290  for (const auto &location : m_completed)
291  Serialization::encode_vstr(bufp, location);
292 }
293 
294 void OperationToggleTableMaintenance::decode_state(uint8_t version, const uint8_t **bufp, size_t *remainp) {
295  decode_state_old(version, bufp, remainp);
296 }
297 
298 void OperationToggleTableMaintenance::decode_state_old(uint8_t version, const uint8_t **bufp, size_t *remainp) {
299  m_name = Serialization::decode_vstr(bufp, remainp);
300  m_id = Serialization::decode_vstr(bufp, remainp);
301  m_toggle_on = Serialization::decode_bool(bufp, remainp);
302  size_t length = Serialization::decode_i32(bufp, remainp);
303  for (size_t i=0; i<length; i++)
304  m_servers.insert( Serialization::decode_vstr(bufp, remainp) );
305  length = Serialization::decode_i32(bufp, remainp);
306  for (size_t i=0; i<length; i++)
307  m_completed.insert( Serialization::decode_vstr(bufp, remainp) );
308 }
309 
311  return "OperationToggleTableMaintenance";
312 }
313 
315  return format("Toggle Table Maintenance (table=%s, %s)",
316  m_name.c_str(), m_toggle_on ? "ON" : "OFF");
317 }
std::set< std::string > m_servers
Set of range servers participating in toggle.
char * decode_vstr(const uint8_t **bufp, size_t *remainp)
Decode a vstr (vint64, data, null).
void execute() override
Carries out a toggle maintenance operation.
Declarations for OperationToggleTableMaintenance.
#define HT_WARNF(msg,...)
Definition: Logger.h:290
The FailureInducer simulates errors.
ContextPtr m_context
Pointer to Master context.
Definition: Operation.h:553
Declarations for Canonicalize.
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
std::set< std::string > m_completed
Set of range servers that have completed toggle.
int64_t id
Unique ID of entity.
std::mutex m_mutex
Mutex for serializing access to members
STL namespace.
void encode_state(uint8_t **bufp) const override
Writes serialized encoding of object state.
EntityHeader header
Entity header
size_t encoded_length_vstr(size_t len)
Computes the encoded length of vstr (vint64, data, null)
#define HT_ON_SCOPE_EXIT(...)
Definition: ScopeGuard.h:301
const String name() override
Returns name of operation ("OperationToggleTableMaintenance")
const char * get_text(int32_t state)
Definition: Operation.cc:609
uint32_t decode_i32(const uint8_t **bufp, size_t *remainp)
Decode a 32-bit integer in little-endian order.
std::shared_ptr< Context > ContextPtr
Smart pointer to Context.
Definition: Context.h:265
Hyperspace definitions
size_t encoded_length_state() const override
Returns serialized state length.
const String label() override
Returns descriptive label for operation.
void set_state(int32_t state)
Definition: Operation.h:473
bool decode_bool(const uint8_t **bufp, size_t *remainp)
Decodes a boolean value from the given buffer.
Definition: Serialization.h:96
const char * get_text(int error)
Returns a descriptive error message.
Definition: Error.cc:330
void add_dependency(const String &dependency)
Definition: Operation.h:462
const char * INIT
Definition: Operation.cc:45
Declarations for DispatchHandlerOperationToggleTableMaintenance.
void encode_i32(uint8_t **bufp, uint32_t val)
Encode a 32-bit integer in little-endian order.
OperationToggleTableMaintenance(ContextPtr &context, const std::string &table_name, bool toggle_on)
Constructor.
void close_handle_ptr(SessionPtr hyperspace, uint64_t *handlep)
Definition: Session.cc:1400
bool m_toggle_on
Flag indicating if maintenance is to be toggled on or off.
Compatibility Macros for C/C++.
Functions to serialize/deserialize primitives to/from a memory buffer.
void decode_state_old(uint8_t version, const uint8_t **bufp, size_t *remainp) override
const char * METADATA
Definition: Operation.cc:48
Hypertable library.
Definition: CellInterval.h:30
void decode_state(uint8_t version, const uint8_t **bufp, size_t *remainp) override
Reads serialized encoding of object state.
void lock()
Locks the entity's mutex.
Definition: MetaLogEntity.h:97
void encode_vstr(uint8_t **bufp, const void *buf, size_t len)
Encode a buffer as variable length string (vint64, data, null)
Hypertable definitions
#define HT_FATALF(msg,...)
Definition: Logger.h:343
long long int Lld
Shortcut for printf formats.
Definition: String.h:53
Declarations for general-purpose utility functions.
void encode_bool(uint8_t **bufp, bool bval)
Encodes a boolean into the given buffer.
Definition: Serialization.h:84
void display_state(std::ostream &os) override
Writes human readable representation of object to output stream.
DependencySet m_dependencies
Set of dependencies.
Definition: Operation.h:595
#define HT_INFOF(msg,...)
Definition: Logger.h:272
void get_table_server_set(ContextPtr &context, const String &id, const String &row, StringSet &servers)
Gets set of servers holding ranges for a given table.
Definition: Utility.cc:57
Abstract base class for master operations.
Definition: Operation.h:124
This is a generic exception class for Hypertable.
Definition: Error.h:314
uint8_t encoding_version_state() const override
Returns version of encoding format of state.
#define HT_ERRORF(msg,...)
Definition: Logger.h:300
#define HT_MAYBE_FAIL(_label_)
void complete_ok(std::vector< MetaLog::EntityPtr > &additional)
Definition: Operation.cc:436
Open file for reading.
Definition: Session.h:71
static void table_name(std::string &name)
Canonicalizes a table name.
Definition: Canonicalize.cc:38
Error codes, Exception handling, error logging.
void complete_error(int error, const String &msg, std::vector< MetaLog::EntityPtr > &additional)
Completes operation with error.
Definition: Operation.cc:400
std::shared_ptr< DispatchHandlerOperation > DispatchHandlerOperationPtr
Smart pointer to DispatchHandlerOperation.
int code() const
Returns the error code.
Definition: Error.h:391
Executes user-defined functions when leaving the current scope.