Files
ternfs-XTXMarkets/cpp/CDCDB.hpp
Francesco Mazzoli ac99f10f94 Add artificial packet drop to integration tests...
...and fixup many places in the code to allow for such drops to
happen somewhat smoothly.
2023-01-16 22:54:51 +00:00

114 lines
3.5 KiB
C++

#pragma once
#include <cstdint>
#include <variant>
#include "Bincode.hpp"
#include "Msgs.hpp"
#include "Env.hpp"
#include "MsgsGen.hpp"
struct CDCShardReq {
ShardId shid;
ShardReqContainer req;
void clear() {
shid = ShardId(0);
req.clear();
}
};
std::ostream& operator<<(std::ostream& out, const CDCShardReq& x);
struct CDCStep {
// If non-zero, a transaction has just finished, and here we have
// the response (whether an error or a response).
uint64_t txnFinished;
EggsError err; // if NO_ERROR, resp is contains the response.
CDCRespContainer resp;
// If non-zero, a transaction is running, but we need something
// from a shard to have it proceed.
//
// We have !((finishedTxn != 0) && (txnNeedsShard != 0)) as an invariant
// -- we can't have finished and be running a thing in the same step.
uint64_t txnNeedsShard;
CDCShardReq shardReq;
// If non-zero, there is a transaction after the current one waiting
// to be executed. Only filled in if `txnNeedsShard == 0`.
// Useful to decide when to call `startNextTransaction` (although
// calling it is safe in any case).
uint64_t nextTxn;
void clear() {
txnFinished = 0;
txnNeedsShard = 0;
nextTxn = 0;
}
};
std::ostream& operator<<(std::ostream& out, const CDCStep& x);
struct CDCDB {
private:
void* _impl;
public:
CDCDB() = delete;
CDCDB& operator=(const CDCDB&) = delete;
CDCDB(Logger& env, const std::string& path);
~CDCDB();
void close();
// Unlike with ShardDB, we don't have an explicit log preparation step here,
// because at least for now logs are simply either CDC requests, or shard
// responses.
//
// The functions below cannot be called concurrently.
//
// TODO one thing that we'd like to do (outside the deterministic state
// machine) is apply backpressure when too many txns are enqueued. It's
// not good to do it inside the state machine, because then we'd be marrying
// the deterministic state update function to such heuristics, which seems
// imprudent. So we'd like some function returning the length of the queue.
// Enqueues a cdc request, and immediately starts it if the system is currently
// idle.
uint64_t processCDCReq(
bool sync, // Whether to persist synchronously. Unneeded if log entries are persisted already.
EggsTime time,
uint64_t logIndex,
const CDCReqContainer& req,
CDCStep& step
);
// Advances the CDC state using the given shard response.
//
// This function crashes hard if the caller passes it a response it's not expecting.
void processShardResp(
bool sync, // Whether to persist synchronously. Unneeded if log entries are persisted already.
EggsTime time,
uint64_t logIndex,
// (err == NO_ERROR) == (req != nullptr)
EggsError err,
const ShardRespContainer* req,
CDCStep& step
);
// Starts the next transaction in line (if any).
//
// It's fine to call this function even if there's nothing to do -- and in fact
// you should do that when starting up the CDC, to make sure to finish
// in-flight CDC transactions.
void startNextTransaction(
bool sync, // Whether to persist synchronously. Unneeded if log entries are persisted already.
EggsTime time,
uint64_t logIndex,
CDCStep& step
);
// The index of the last log entry persisted to the DB
uint64_t lastAppliedLogEntry();
};