2017-05-14 23:48:46 +02:00
/* -------------------------------------------------------------------------- */
2024-07-29 14:25:20 +02:00
/* Copyright 2002-2024, OpenNebula Project, OpenNebula Systems */
2017-05-14 23:48:46 +02:00
/* */
/* 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 REPLICA_THREAD_H_
# define REPLICA_THREAD_H_
2020-09-10 13:32:52 +02:00
# include <mutex>
# include <condition_variable>
2017-05-14 23:48:46 +02:00
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Replication thread class. This is a generic replicaton thread, it is used
// to send information to a given server (follower). This class needs to be
// specialized to implement the specific replication logic.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class ReplicaThread
{
public :
2020-09-10 13:32:52 +02:00
ReplicaThread ( int _follower_id )
: follower_id ( _follower_id )
, _finalize ( false )
, _pending_requests ( false )
, retry_timeout ( 1e8 )
2017-05-14 23:48:46 +02:00
{
2020-09-10 13:32:52 +02:00
}
2017-05-14 23:48:46 +02:00
2020-09-10 13:32:52 +02:00
virtual ~ ReplicaThread ( ) = default ;
2017-05-14 23:48:46 +02:00
/**
* Notify this replica thread that are new records in the log to replicate
*/
void add_request ( ) ;
/**
* Exists the replication thread
*/
void finalize ( ) ;
protected :
/**
* Specific logic for the replicate process
*/
virtual int replicate ( ) = 0 ;
/**
* ID of follower to replicate state to
*/
int follower_id ;
private :
/**
* Wrapper function to handle the replication loop and timeouts . It makes
* use of the virtual function to replicate to actually start the replica -
* tion process .
*/
void do_replication ( ) ;
2020-09-10 13:32:52 +02:00
friend class ReplicaManager ;
2017-05-14 23:48:46 +02:00
// -------------------------------------------------------------------------
// pthread synchronization variables
// -------------------------------------------------------------------------
2020-09-10 13:32:52 +02:00
std : : mutex _mutex ;
2017-05-14 23:48:46 +02:00
2020-09-10 13:32:52 +02:00
std : : condition_variable cond ;
2017-05-14 23:48:46 +02:00
bool _finalize ;
bool _pending_requests ;
time_t retry_timeout ;
static const time_t max_retry_timeout ;
} ;
// -----------------------------------------------------------------------------
// Raft replication thread, it implements the Ratf replication algorithm on
// followers
// -----------------------------------------------------------------------------
class LogDB ;
class RaftManager ;
class RaftReplicaThread : public ReplicaThread
{
public :
RaftReplicaThread ( int follower_id ) ;
2024-06-03 11:40:24 +02:00
virtual ~ RaftReplicaThread ( ) { } ;
2017-05-14 23:48:46 +02:00
private :
/**
* Specific logic for the replicate process
*/
2023-02-07 08:50:30 +01:00
int replicate ( ) override ;
2017-05-14 23:48:46 +02:00
/**
* Pointers to other components
*/
LogDB * logdb ;
RaftManager * raftm ;
} ;
2017-05-19 20:08:45 +02:00
// -----------------------------------------------------------------------------
// Federation replica thread. It replicates SQL commands on zone slaves for
// federated pools
// -----------------------------------------------------------------------------
class FedReplicaManager ;
2017-05-16 17:08:24 +02:00
class FedReplicaThread : public ReplicaThread
{
public :
2017-05-19 20:08:45 +02:00
FedReplicaThread ( int zone_id ) ;
2017-05-16 17:08:24 +02:00
2024-06-03 11:40:24 +02:00
virtual ~ FedReplicaThread ( ) { } ;
2017-05-16 17:08:24 +02:00
private :
/**
* Specific logic for the replicate process
*/
2023-02-07 08:50:30 +01:00
int replicate ( ) override ;
2017-05-19 20:08:45 +02:00
/**
* Pointers to other components
*/
FedReplicaManager * frm ;
2017-05-16 17:08:24 +02:00
} ;
2017-06-03 19:24:19 +02:00
// -----------------------------------------------------------------------------
// Thread to send hearbeats to each follower
// -----------------------------------------------------------------------------
class HeartBeatThread : public ReplicaThread
{
public :
HeartBeatThread ( int follower_id ) ;
2024-06-03 11:40:24 +02:00
virtual ~ HeartBeatThread ( ) { } ;
2017-06-03 19:24:19 +02:00
private :
/**
* Error statistics for follower
*/
time_t last_error ;
int num_errors ;
/**
* Specific logic for the replicate process
*/
2023-02-07 08:50:30 +01:00
int replicate ( ) override ;
2017-06-03 19:24:19 +02:00
/**
* Pointers to other components
*/
RaftManager * raftm ;
} ;
2017-05-14 23:48:46 +02:00
# endif