00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00037 #include <config.h>
00038 #include <drizzled/replication_services.h>
00039 #include <drizzled/plugin/transaction_replicator.h>
00040 #include <drizzled/plugin/transaction_applier.h>
00041 #include <drizzled/message/transaction.pb.h>
00042 #include <drizzled/gettext.h>
00043 #include <drizzled/session.h>
00044 #include <drizzled/error.h>
00045 #include <drizzled/errmsg_print.h>
00046
00047 #include <string>
00048 #include <vector>
00049 #include <algorithm>
00050
00051 using namespace std;
00052
00053 namespace drizzled {
00054
00055 typedef std::vector<plugin::TransactionReplicator*> Replicators;
00056 typedef std::vector<std::pair<std::string, plugin::TransactionApplier*> > Appliers;
00057
00062 static bool is_active= false;
00067 static atomic<uint64_t> last_applied_timestamp;
00069 static Replicators replicators;
00071 static Appliers appliers;
00073 static ReplicationServices::ReplicationStreams replication_streams;
00074
00079 static void normalizeReplicatorName(string &name)
00080 {
00081 boost::to_lower(name);
00082 if (name.find("replicator") == string::npos)
00083 name.append("replicator");
00084 {
00085 size_t found_underscore= name.find('_');
00086 while (found_underscore != string::npos)
00087 {
00088 name.erase(found_underscore, 1);
00089 found_underscore= name.find('_');
00090 }
00091 }
00092 }
00093
00094 bool ReplicationServices::evaluateRegisteredPlugins()
00095 {
00096
00097
00098
00099
00100
00101
00102
00103
00104 if (appliers.empty())
00105 return true;
00106
00107 if (replicators.empty() && not appliers.empty())
00108 {
00109 errmsg_printf(error::ERROR,
00110 N_("You registered a TransactionApplier plugin but no "
00111 "TransactionReplicator plugins were registered.\n"));
00112 return false;
00113 }
00114
00115 BOOST_FOREACH(Appliers::reference appl_iter, appliers)
00116 {
00117 plugin::TransactionApplier *applier= appl_iter.second;
00118 string requested_replicator_name= appl_iter.first;
00119 normalizeReplicatorName(requested_replicator_name);
00120
00121 bool found= false;
00122 Replicators::iterator repl_iter;
00123 for (repl_iter= replicators.begin(); repl_iter != replicators.end(); ++repl_iter)
00124 {
00125 string replicator_name= (*repl_iter)->getName();
00126 normalizeReplicatorName(replicator_name);
00127
00128 if (requested_replicator_name.compare(replicator_name) == 0)
00129 {
00130 found= true;
00131 break;
00132 }
00133 }
00134 if (not found)
00135 {
00136 errmsg_printf(error::ERROR,
00137 N_("You registered a TransactionApplier plugin but no "
00138 "TransactionReplicator plugins were registered that match the "
00139 "requested replicator name of '%s'.\n"
00140 "We have deactivated the TransactionApplier '%s'.\n"),
00141 requested_replicator_name.c_str(),
00142 applier->getName().c_str());
00143 applier->deactivate();
00144 return false;
00145 }
00146 else
00147 {
00148 replication_streams.push_back(make_pair(*repl_iter, applier));
00149 }
00150 }
00151 is_active= true;
00152 return true;
00153 }
00154
00155 void ReplicationServices::attachReplicator(plugin::TransactionReplicator *in_replicator)
00156 {
00157 replicators.push_back(in_replicator);
00158 }
00159
00160 void ReplicationServices::detachReplicator(plugin::TransactionReplicator *in_replicator)
00161 {
00162 replicators.erase(std::find(replicators.begin(), replicators.end(), in_replicator));
00163 }
00164
00165 void ReplicationServices::attachApplier(plugin::TransactionApplier *in_applier, const string &requested_replicator_name)
00166 {
00167 appliers.push_back(make_pair(requested_replicator_name, in_applier));
00168 }
00169
00170 void ReplicationServices::detachApplier(plugin::TransactionApplier *)
00171 {
00172 }
00173
00174 bool ReplicationServices::isActive()
00175 {
00176 return is_active;
00177 }
00178
00179 plugin::ReplicationReturnCode ReplicationServices::pushTransactionMessage(Session &in_session,
00180 message::Transaction &to_push)
00181 {
00182 plugin::ReplicationReturnCode result= plugin::SUCCESS;
00183
00184 BOOST_FOREACH(ReplicationStreams::reference iter, replication_streams)
00185 {
00186 plugin::TransactionReplicator *cur_repl= iter.first;
00187 plugin::TransactionApplier *cur_appl= iter.second;
00188
00189 result= cur_repl->replicate(cur_appl, in_session, to_push);
00190
00191 if (result == plugin::SUCCESS)
00192 {
00193
00194
00195
00196
00197
00198
00199 last_applied_timestamp.fetch_and_store(to_push.transaction_context().end_timestamp());
00200 }
00201 else
00202 return result;
00203 }
00204 return result;
00205 }
00206
00207 ReplicationServices::ReplicationStreams &ReplicationServices::getReplicationStreams()
00208 {
00209 return replication_streams;
00210 }
00211
00212 }