2017-11-29 23:03:42 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <atomic>
|
2018-02-15 17:47:50 +08:00
|
|
|
#include <chrono>
|
2017-12-13 23:11:52 +08:00
|
|
|
#include <mutex>
|
2017-11-29 23:03:42 +08:00
|
|
|
|
2018-01-25 21:28:14 +08:00
|
|
|
#include "communication/rpc/client_pool.hpp"
|
2017-11-29 23:03:42 +08:00
|
|
|
#include "data_structures/concurrent/concurrent_map.hpp"
|
2018-01-15 21:03:07 +08:00
|
|
|
#include "io/network/endpoint.hpp"
|
2017-11-29 23:03:42 +08:00
|
|
|
#include "transactions/commit_log.hpp"
|
|
|
|
#include "transactions/engine.hpp"
|
|
|
|
#include "transactions/transaction.hpp"
|
2018-02-15 17:47:50 +08:00
|
|
|
#include "utils/scheduler.hpp"
|
2017-11-29 23:03:42 +08:00
|
|
|
|
|
|
|
namespace tx {
|
2017-12-22 21:36:25 +08:00
|
|
|
|
2018-01-10 22:10:22 +08:00
|
|
|
/** Distributed worker transaction engine. Connects to a MasterEngine (single
|
2018-02-01 17:58:56 +08:00
|
|
|
* source of truth) to obtain transactional info. Caches most info locally. Can
|
|
|
|
* begin/advance/end transactions on the master. */
|
2017-11-29 23:03:42 +08:00
|
|
|
class WorkerEngine : public Engine {
|
|
|
|
public:
|
2018-02-15 17:47:50 +08:00
|
|
|
/// The wait time between two releases of local transaction objects that have
|
|
|
|
/// expired on the master.
|
|
|
|
static constexpr std::chrono::seconds kCacheReleasePeriod{1};
|
|
|
|
|
2018-01-24 19:16:14 +08:00
|
|
|
WorkerEngine(const io::network::Endpoint &endpoint);
|
2018-02-01 17:58:56 +08:00
|
|
|
~WorkerEngine();
|
2017-11-29 23:03:42 +08:00
|
|
|
|
2018-02-01 17:58:56 +08:00
|
|
|
Transaction *Begin() override;
|
|
|
|
command_id_t Advance(transaction_id_t id) override;
|
2018-02-14 16:44:48 +08:00
|
|
|
command_id_t UpdateCommand(transaction_id_t id) override;
|
2018-02-01 17:58:56 +08:00
|
|
|
void Commit(const Transaction &t) override;
|
|
|
|
void Abort(const Transaction &t) override;
|
2017-11-29 23:03:42 +08:00
|
|
|
CommitLog::Info Info(transaction_id_t tid) const override;
|
|
|
|
Snapshot GlobalGcSnapshot() override;
|
|
|
|
Snapshot GlobalActiveTransactions() override;
|
2018-02-21 23:06:56 +08:00
|
|
|
transaction_id_t LocalLast() const override;
|
2017-11-29 23:03:42 +08:00
|
|
|
void LocalForEachActiveTransaction(
|
|
|
|
std::function<void(Transaction &)> f) override;
|
2018-02-21 23:06:56 +08:00
|
|
|
Transaction *RunningTransaction(transaction_id_t tx_id) override;
|
|
|
|
|
|
|
|
// Caches the transaction for the given info an returs a ptr to it.
|
|
|
|
Transaction *RunningTransaction(transaction_id_t tx_id,
|
|
|
|
const Snapshot &snapshot);
|
2017-11-29 23:03:42 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Local caches.
|
2018-02-14 16:44:48 +08:00
|
|
|
mutable ConcurrentMap<transaction_id_t, Transaction *> active_;
|
2017-12-06 21:12:26 +08:00
|
|
|
std::atomic<transaction_id_t> local_last_{0};
|
2017-11-29 23:03:42 +08:00
|
|
|
// Mutable because just getting info can cause a cache fill.
|
|
|
|
mutable CommitLog clog_;
|
2017-12-06 21:12:26 +08:00
|
|
|
|
|
|
|
// Communication to the transactional master.
|
2018-01-25 21:28:14 +08:00
|
|
|
mutable communication::rpc::ClientPool rpc_client_pool_;
|
2017-12-22 21:36:25 +08:00
|
|
|
|
2018-02-14 16:44:48 +08:00
|
|
|
// Removes (destructs) a Transaction that's expired. If there is no cached
|
|
|
|
// transacton for the given id, nothing is done.
|
|
|
|
void ClearCache(transaction_id_t tx_id) const;
|
2018-02-15 17:47:50 +08:00
|
|
|
|
|
|
|
// Used for clearing of caches of transactions that have expired.
|
|
|
|
// Initialize the oldest_active_ with 1 because there's never a tx with id=0
|
|
|
|
std::atomic<transaction_id_t> oldest_active_{1};
|
|
|
|
void ClearCachesBasedOnOldest(transaction_id_t oldest_active);
|
|
|
|
Scheduler cache_clearing_scheduler_;
|
2018-02-14 16:44:48 +08:00
|
|
|
};
|
2017-11-29 23:03:42 +08:00
|
|
|
} // namespace tx
|