mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-11 05:17:41 +03:00
374 lines
8.8 KiB
C++
374 lines
8.8 KiB
C++
/* -------------------------------------------------------------------------- */
|
|
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */
|
|
/* */
|
|
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
|
/* not use this file except in compliance with the License. You may obtain */
|
|
/* a copy of the License at */
|
|
/* */
|
|
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
|
/* */
|
|
/* Unless required by applicable law or agreed to in writing, software */
|
|
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
|
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
|
/* See the License for the specific language governing permissions and */
|
|
/* limitations under the License. */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#ifndef ZONE_SERVER_H_
|
|
#define ZONE_SERVER_H_
|
|
|
|
#include <queue>
|
|
#include <set>
|
|
|
|
#include "ExtendedAttribute.h"
|
|
|
|
class LogDBManager;
|
|
|
|
/**
|
|
* The VirtualMachine DISK attribute
|
|
*/
|
|
class ZoneServer : public ExtendedAttribute
|
|
{
|
|
public:
|
|
|
|
enum State {
|
|
OFFLINE = 0,
|
|
CANDIDATE = 1,
|
|
FOLLOWER = 2,
|
|
LEADER = 3
|
|
};
|
|
|
|
ZoneServer(VectorAttribute *va, int id):ExtendedAttribute(va, id),
|
|
state(FOLLOWER), dbm(0){};
|
|
|
|
virtual ~ZoneServer(){};
|
|
|
|
/**
|
|
* Initialized server metadata:
|
|
* - NAME
|
|
* - ENDPOINT
|
|
* @param error string if any
|
|
* @return -1 if server data could not be initialized, 0 on success
|
|
*/
|
|
int init(string& error)
|
|
{
|
|
if ( vector_value("NAME").empty() )
|
|
{
|
|
error = "Missing NAME in SERVER";
|
|
return -1;
|
|
}
|
|
|
|
if ( vector_value("ENDPOINT").empty() )
|
|
{
|
|
error = "Missing ENDPOINT in SERVER";
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Server attributes
|
|
//--------------------------------------------------------------------------
|
|
/**
|
|
* @return the ID of the server
|
|
*/
|
|
int get_id() const
|
|
{
|
|
return ExtendedAttribute::get_id();
|
|
}
|
|
|
|
int get_term() const
|
|
{
|
|
return term;
|
|
}
|
|
|
|
/**
|
|
* @return highest log known to be commited
|
|
*/
|
|
int get_commit() const
|
|
{
|
|
return commit;
|
|
}
|
|
|
|
/**
|
|
* @return highest log applied to DB
|
|
*/
|
|
int get_applied() const
|
|
{
|
|
return applied;
|
|
}
|
|
|
|
/**
|
|
* @return next log to send to this server
|
|
*/
|
|
int get_next() const
|
|
{
|
|
return next;
|
|
}
|
|
|
|
/**
|
|
* @return highest log replicated in this server
|
|
*/
|
|
int get_match() const
|
|
{
|
|
return match;
|
|
}
|
|
|
|
/**
|
|
* Initialized follower data
|
|
* @param last log index
|
|
*/
|
|
void init_follower(unsigned int last)
|
|
{
|
|
next = last + 1;
|
|
match = 0;
|
|
}
|
|
|
|
/**
|
|
* @return true if the server is offline
|
|
*/
|
|
bool is_offline()
|
|
{
|
|
return state == OFFLINE;
|
|
}
|
|
|
|
/**
|
|
* @return true if the server is the leader of the zone
|
|
*/
|
|
bool is_leader()
|
|
{
|
|
return state == LEADER;
|
|
}
|
|
|
|
/**
|
|
* Decrease the next log entry to send to this follower
|
|
*/
|
|
void dec_next()
|
|
{
|
|
next--;
|
|
}
|
|
|
|
/**
|
|
* Increase the next log entry to send to this follower
|
|
*/
|
|
void inc_next()
|
|
{
|
|
next++;
|
|
}
|
|
|
|
/**
|
|
* Set the the index of the highest log entry on this follower
|
|
*/
|
|
void set_match(unsigned int _match)
|
|
{
|
|
match = _match;
|
|
}
|
|
|
|
/**
|
|
* Set the state for this follower
|
|
*/
|
|
void set_state(State s)
|
|
{
|
|
state = s;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// LogDBManager interface
|
|
//--------------------------------------------------------------------------
|
|
/**
|
|
* Start the LogDB manager and associated replica threads for followers
|
|
* @param 0 on success
|
|
*/
|
|
int logdbm_start();
|
|
|
|
/**
|
|
* Stop the LogDB manager and threads
|
|
* @param 0 on success
|
|
*/
|
|
void logdbm_stop();
|
|
|
|
/**
|
|
* Start replica threads for new servers in zone
|
|
*/
|
|
void logdbm_addserver();
|
|
|
|
/**
|
|
* Start replication of a new log entry on followers
|
|
*/
|
|
void logdbm_replicate();
|
|
|
|
private:
|
|
State state;
|
|
|
|
/**
|
|
* Current term
|
|
*/
|
|
unsigned int term;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Volatile log index variables
|
|
// - commit, highest log known to be commited
|
|
// - applied, highest log applied to DB
|
|
//
|
|
//---------------------------- LEADER VARIABLES ----------------------------
|
|
//
|
|
// - next, next log to send to this server
|
|
// - match, highest log replicated in this server
|
|
// -------------------------------------------------------------------------
|
|
unsigned int commit;
|
|
|
|
unsigned int applied;
|
|
|
|
unsigned int next;
|
|
|
|
unsigned int match;
|
|
|
|
/**
|
|
* Replication Manager for this server (only started in self)
|
|
*/
|
|
LogDBManager * dbm;
|
|
};
|
|
|
|
|
|
/**
|
|
* Set of Zone servers
|
|
*/
|
|
class ZoneServers : public ExtendedAttributeSet
|
|
{
|
|
public:
|
|
/* ---------------------------------------------------------------------- */
|
|
/* Constructor and Initialization functions */
|
|
/* ---------------------------------------------------------------------- */
|
|
/**
|
|
* Creates the ZoneServers set from a zone template with SERVER=[...]
|
|
* attributes
|
|
* @param tmpl template with SERVER
|
|
*/
|
|
ZoneServers(Template * tmpl):ExtendedAttributeSet(false), next_id(-1)
|
|
{
|
|
std::vector<VectorAttribute *> vas;
|
|
|
|
tmpl->get(SERVER_NAME, vas);
|
|
|
|
init_attribute_map(SERVER_ID_NAME, vas);
|
|
|
|
for ( zone_iterator it = begin() ; it != end() ; ++it )
|
|
{
|
|
string error;
|
|
|
|
int i = (*it)->get_id();
|
|
|
|
if ( i > next_id )
|
|
{
|
|
next_id = i;
|
|
}
|
|
|
|
(*it)->init(error);
|
|
}
|
|
|
|
next_id += 1;
|
|
};
|
|
|
|
/**
|
|
* Creates an empty zone server set
|
|
*/
|
|
ZoneServers():ExtendedAttributeSet(false){};
|
|
|
|
virtual ~ZoneServers(){};
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
/* Iterators */
|
|
/* ---------------------------------------------------------------------- */
|
|
class ZoneIterator : public AttributeIterator
|
|
{
|
|
public:
|
|
ZoneIterator():AttributeIterator(){};
|
|
ZoneIterator(const AttributeIterator& dit):AttributeIterator(dit){};
|
|
virtual ~ZoneIterator(){};
|
|
|
|
ZoneServer * operator*() const
|
|
{
|
|
return static_cast<ZoneServer *>(map_it->second);
|
|
}
|
|
};
|
|
|
|
ZoneIterator begin()
|
|
{
|
|
ZoneIterator it(ExtendedAttributeSet::begin());
|
|
return it;
|
|
}
|
|
|
|
ZoneIterator end()
|
|
{
|
|
ZoneIterator it(ExtendedAttributeSet::end());
|
|
return it;
|
|
}
|
|
|
|
typedef class ZoneIterator zone_iterator;
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
/* ZoneServer interface */
|
|
/* ---------------------------------------------------------------------- */
|
|
/**
|
|
* Returns the SERVER attribute for a zone server
|
|
* @param disk_id of the DISK
|
|
* @return pointer to the attribute ir null if not found
|
|
*/
|
|
ZoneServer * get_server(int id) const
|
|
{
|
|
return static_cast<ZoneServer *>(get_attribute(id));
|
|
}
|
|
|
|
int add_server(VectorAttribute * va, string& error)
|
|
{
|
|
ZoneServer * server = new ZoneServer(va, next_id);
|
|
|
|
if ( server->init(error) != 0 )
|
|
{
|
|
delete server;
|
|
|
|
return -1;
|
|
}
|
|
|
|
va->replace(SERVER_ID_NAME, next_id);
|
|
|
|
add_attribute(server, next_id);
|
|
|
|
next_id += 1;
|
|
|
|
return 0;
|
|
};
|
|
|
|
ZoneServer * delete_server(int id)
|
|
{
|
|
return static_cast<ZoneServer *>(delete_attribute(id));
|
|
};
|
|
|
|
/**
|
|
* @return servers in zone
|
|
*/
|
|
unsigned int size()
|
|
{
|
|
return ExtendedAttributeSet::size();
|
|
}
|
|
|
|
protected:
|
|
ExtendedAttribute * attribute_factory(VectorAttribute * va, int id) const
|
|
{
|
|
return new ZoneServer(va, id);
|
|
};
|
|
|
|
private:
|
|
friend class Zone;
|
|
|
|
static const char * SERVER_NAME; //"SERVER"
|
|
|
|
static const char * SERVER_ID_NAME; //"ID"
|
|
|
|
int next_id;
|
|
};
|
|
|
|
#endif /*ZONE_SERVER_H_*/
|
|
|