Skip to content

Commit

Permalink
Revert "Revert "Calculate timeout from command scheduled execution ti…
Browse files Browse the repository at this point in the history
…me""
  • Loading branch information
coleaeason authored Oct 18, 2018
1 parent 748a96f commit 73999b2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
50 changes: 32 additions & 18 deletions BedrockCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,43 @@ class AutoScopeRewrite {
bool (*_handler)(int, const char*, string&);
};

uint64_t BedrockCore::_getTimeout(const SData& request) {
uint64_t timeout = request.isSet("timeout") ? request.calc("timeout") : DEFAULT_TIMEOUT;

// See when the command was scheduled to run. The timeout is from *this* start time, not from when the command
// starts executing.
try {
int64_t adjustedTimeout = (int64_t)timeout - (int64_t)((STimeNow() - stoull(request["commandExecuteTime"])) / 1000);

// If this is negative, we're *already* past the timeout, just return early.
if (adjustedTimeout <= 0) {
STHROW("555 Timeout");
} else {
// Otherwise, we can return.
return adjustedTimeout;
}
} catch (const invalid_argument& e) {
SWARN("Couldn't parse commandExecuteTime: " << request["commandExecuteTime"] << "'.");
} catch (const out_of_range& e) {
SWARN("Invalid commandExecuteTime: " << request["commandExecuteTime"] << "'.");
}

// This only happens if we hit the catch blocks above.
return timeout;
}
bool BedrockCore::peekCommand(BedrockCommand& command) {
AutoTimer timer(command, BedrockCommand::PEEK);
// Convenience references to commonly used properties.
SData& request = command.request;
SData& response = command.response;
STable& content = command.jsonContent;
SDEBUG("Peeking at '" << request.methodLine << "' with priority: " << command.priority);
command.peekCount++;
uint64_t timeout = command.request.isSet("timeout") ? command.request.calc("timeout") : DEFAULT_TIMEOUT;

if (timeout > 2'000'000) {
// Old microsecond timeout. Update caller to use milliseconds. Remove this line once we no longer see this.
SWARN("[TYLER] old-style timeout found for command: " << command.request.methodLine);
timeout /= 1000;
}

// We catch any exception and handle in `_handleCommandException`.
try {
SDEBUG("Peeking at '" << request.methodLine << "' with priority: " << command.priority);
uint64_t timeout = _getTimeout(request);
command.peekCount++;

_db.startTiming(timeout * 1000);
// We start a transaction in `peekCommand` because we want to support having atomic transactions from peek
// through process. This allows for consistency through this two-phase process. I.e., anything checked in
Expand Down Expand Up @@ -144,19 +163,14 @@ bool BedrockCore::processCommand(BedrockCommand& command) {
SData& request = command.request;
SData& response = command.response;
STable& content = command.jsonContent;
SDEBUG("Processing '" << request.methodLine << "'");
command.processCount++;
uint64_t timeout = command.request.isSet("timeout") ? command.request.calc("timeout") : DEFAULT_TIMEOUT;

if (timeout > 2'000'000) {
// Old microsecond timeout. Update caller to use milliseconds. Remove this line once we no longer see this.
SWARN("[TYLER] old-style timeout found for command: " << command.request.methodLine);
timeout /= 1000;
}

// Keep track of whether we've modified the database and need to perform a `commit`.
bool needsCommit = false;
try {
SDEBUG("Processing '" << request.methodLine << "'");
uint64_t timeout = _getTimeout(request);
command.processCount++;

// Time in US.
_db.startTiming(timeout * 1000);
// If a transaction was already begun in `peek`, then this is a no-op. We call it here to support the case where
Expand Down
5 changes: 5 additions & 0 deletions BedrockCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class BedrockCore : public SQLiteCore {
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 _getTimeout(const SData& request);
void _handleCommandException(BedrockCommand& command, const SException& e);
const BedrockServer& _server;
};

0 comments on commit 73999b2

Please sign in to comment.