-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathBedrockCore.h
56 lines (49 loc) · 3.28 KB
/
BedrockCore.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#pragma once
#include <sqlitecluster/SQLiteCore.h>
#include <BedrockCommand.h>
class BedrockServer;
class BedrockCore : public SQLiteCore {
public:
BedrockCore(SQLite& db, const BedrockServer& server);
// Automatic timing class that records an entry corresponding to its lifespan.
class AutoTimer {
public:
AutoTimer(BedrockCommand& command, BedrockCommand::TIMING_INFO type) :
_command(command), _type(type), _start(STimeNow()) { }
~AutoTimer() {
_command.timingInfo.emplace_back(make_tuple(_type, _start, STimeNow()));
}
private:
BedrockCommand& _command;
BedrockCommand::TIMING_INFO _type;
uint64_t _start;
};
// Peek lets you pre-process a command. It will be called on each command before `process` is called on the same
// command, and it *may be called multiple times*. Preventing duplicate actions on calling peek multiple times is
// up to the implementer, and may happen *across multiple servers*. I.e., a slave server may call `peek`, and on
// its returning false, the command will be escalated to the master server, where `peek` will be called again. It
// should be considered an error to modify the DB from inside `peek`.
// Returns a boolean value of `true` if the command is complete and its `response` field can be returned to the
// caller. Returns `false` if the command will need to be passed to `process` to complete handling the command.
bool peekCommand(BedrockCommand& command);
// Process is the follow-up to `peek` if `peek` was insufficient to handle the command. It will only ever be called
// on the master node, and should always be able to resolve the command completely. When a command is passed to
// `process`, the caller will *usually* have already begun a database transaction with either `BEGIN TRANSACTION`
// or `BEGIN CONCURRENT`, and it's up to `process` to add the rest of the transaction, without performing a
// `ROLLBACK` or `COMMIT`, which will be handled by the caller. It returns `true` if it has modified the database
// and requires the caller to perform a `commit`, and `false` if no changes requiring a `commit` have been made.
// Upon being returned `false`, the caller will perform a `ROLLBACK` of the empty transaction, and will not
// replicate the transaction to slave nodes. Upon being returned `true`, the caller will attempt to perform a
// `COMMIT` and replicate the transaction to slave nodes. It's allowable for this `COMMIT` to fail, in which case
// this command *will be passed to process again in the future to retry*.
bool processCommand(BedrockCommand& command);
private:
// When called in the context of handling an exception, returns the demangled (if possible) name of the exception.
string _getExceptionName();
// Gets the amount of time remaining until this command times out. This is the difference between the command's
// 'timeout' value (or the default timeout, if not set) and the time the command was initially scheduled to run. If
// this time is already expired, this throws `555 Timeout`
uint64_t _getRemainingTime(const BedrockCommand& command);
void _handleCommandException(BedrockCommand& command, const SException& e);
const BedrockServer& _server;
};