Commit c926cd46 authored by Georgios Bitzes's avatar Georgios Bitzes
Browse files

Implement utility function to timestamp client-issued lease requests

parent 06beeab0
Pipeline #428939 passed with stages
in 60 minutes and 46 seconds
......@@ -60,6 +60,7 @@ add_library(XrdQuarkDB SHARED
redis/ArrayResponseBuilder.cc redis/ArrayResponseBuilder.hh
redis/Authenticator.cc redis/Authenticator.hh
redis/CommandMonitor.cc redis/CommandMonitor.hh
redis/LeaseFilter.cc redis/LeaseFilter.hh
redis/MultiHandler.cc redis/MultiHandler.hh
redis/RedisEncodedResponse.hh
redis/Transaction.cc redis/Transaction.hh
......
......@@ -89,6 +89,10 @@ struct cmdMapInit {
redis_cmd_map["lhdel_with_fallback"] = {RedisCommand::LHDEL_WITH_FALLBACK, CommandType::WRITE};
redis_cmd_map["lhset_and_del_fallback"] = {RedisCommand::LHSET_AND_DEL_FALLBACK, CommandType::WRITE};
redis_cmd_map["convert_hash_field_to_lhash"] = {RedisCommand::CONVERT_HASH_FIELD_TO_LHASH, CommandType::WRITE};
redis_cmd_map["lease_acquire"] = {RedisCommand::LEASE_ACQUIRE, CommandType::WRITE};
redis_cmd_map["lease_get"] = {RedisCommand::LEASE_GET, CommandType::WRITE};
redis_cmd_map["timestamped_lease_acquire"] = {RedisCommand::TIMESTAMPED_LEASE_ACQUIRE, CommandType::WRITE};
redis_cmd_map["timestamped_lease_get"] = {RedisCommand::TIMESTAMPED_LEASE_GET, CommandType::WRITE};
redis_cmd_map["exec"] = {RedisCommand::EXEC, CommandType::CONTROL};
redis_cmd_map["discard"] = {RedisCommand::DISCARD, CommandType::CONTROL};
......
......@@ -100,6 +100,12 @@ enum class RedisCommand {
CLOCK_GET,
LEASE_GET,
LEASE_ACQUIRE,
TIMESTAMPED_LEASE_GET,
TIMESTAMPED_LEASE_ACQUIRE,
CONFIG_GET,
CONFIG_SET,
CONFIG_GETALL,
......
// ----------------------------------------------------------------------
// File: LeaseFilter.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "../RedisRequest.hh"
#include "LeaseFilter.hh"
#include "../Commands.hh"
#include "../utils/Macros.hh"
#include "../utils/IntToBinaryString.hh"
#include "../Formatter.hh"
using namespace quarkdb;
bool LeaseFilter::transform(RedisRequest &req, ClockValue timestamp, RedisEncodedResponse &err) {
qdb_assert(req.getCommand() == RedisCommand::LEASE_GET || req.getCommand() == RedisCommand::LEASE_ACQUIRE);
if(req.getCommand() == RedisCommand::LEASE_GET) {
if(req.size() != 2) {
err = Formatter::errArgs(req[0]);
return false;
}
req[0] = "TIMESTAMPED_LEASE_GET";
req.emplace_back(unsignedIntToBinaryString(timestamp));
req.parseCommand();
return true;
}
else if(req.getCommand() == RedisCommand::LEASE_ACQUIRE) {
if(req.size() != 4) {
err = Formatter::errArgs(req[0]);
return false;
}
req[0] = "TIMESTAMPED_LEASE_ACQUIRE";
req.emplace_back(unsignedIntToBinaryString(timestamp));
req.parseCommand();
return true;
}
qdb_throw("should never reach here");
}
// ----------------------------------------------------------------------
// File: LeaseFilter.hh
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#ifndef QUARKDB_REDIS_LEASE_FILTER_H
#define QUARKDB_REDIS_LEASE_FILTER_H
namespace quarkdb {
class RedisRequest;
class RedisEncodedResponse;
using ClockValue = uint64_t;
class LeaseFilter {
public:
//----------------------------------------------------------------------------
// Transform LEASE_GET and LEASE_ACQUIRE into TIMESTAMPED_LEASE_GET and
// TIMESTAMPED_LEASE_ACQUIRE, respectively.
//----------------------------------------------------------------------------
static bool transform(RedisRequest &req, ClockValue timestamp, RedisEncodedResponse &err);
};
}
#endif
......@@ -34,7 +34,10 @@
#include "utils/Random.hh"
#include "redis/Transaction.hh"
#include "redis/Authenticator.hh"
#include "redis/LeaseFilter.hh"
#include "redis/RedisEncodedResponse.hh"
#include "Utils.hh"
#include "Formatter.hh"
using namespace quarkdb;
......@@ -438,3 +441,37 @@ TEST(Transaction, Parsing) {
ASSERT_THROW(tx3.emplace_back("asdf", "1234"), FatalException);
}
TEST(LeaseFilter, BasicSanity) {
ClockValue timestamp = 567;
RedisRequest req = {"get", "adsf"};
RedisEncodedResponse resp;
ASSERT_THROW(LeaseFilter::transform(req, timestamp, resp), FatalException);
req = {"lease-acquire", "my-lease", "lease-holder-1234", "10000" };
ASSERT_TRUE(LeaseFilter::transform(req, timestamp, resp));
ASSERT_EQ(req[0], "TIMESTAMPED_LEASE_ACQUIRE");
ASSERT_EQ(req[1], "my-lease");
ASSERT_EQ(req[2], "lease-holder-1234");
ASSERT_EQ(req[3], "10000");
ASSERT_EQ(req[4], unsignedIntToBinaryString(567));
ASSERT_EQ(req.getCommand(), RedisCommand::TIMESTAMPED_LEASE_ACQUIRE);
req = {"lease-acquire", "my-lease"};
ASSERT_FALSE(LeaseFilter::transform(req, timestamp, resp));
ASSERT_EQ(resp, Formatter::errArgs(req[0]));
req = {"lease-get", "my-lease", "holder-1234", "2000"};
ASSERT_FALSE(LeaseFilter::transform(req, timestamp, resp));
ASSERT_EQ(resp, Formatter::errArgs(req[0]));
req = {"lease-get", "my-lease"};
ASSERT_TRUE(LeaseFilter::transform(req, timestamp, resp));
ASSERT_EQ(req[0], "TIMESTAMPED_LEASE_GET");
ASSERT_EQ(req[1], "my-lease");
ASSERT_EQ(req[2], unsignedIntToBinaryString(567));
ASSERT_EQ(req.getCommand(), RedisCommand::TIMESTAMPED_LEASE_GET);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment