Allow Replayer to report the results of TraceRecords. (#8657)
Summary: `Replayer::Execute()` can directly returns the result (e.g, request latency, DB::Get() return code, returned value, etc.) `Replayer::Replay()` reports the results via a callback function. New interface: `TraceRecordResult` in "rocksdb/trace_record_result.h". `DBTest2.TraceAndReplay` and `DBTest2.TraceAndManualReplay` are updated accordingly. Pull Request resolved: https://github.com/facebook/rocksdb/pull/8657 Reviewed By: ajkr Differential Revision: D30290216 Pulled By: autopear fbshipit-source-id: 3c8d4e6b180ec743de1a9d9dcaee86064c74f0d6main
parent
b6269b078a
commit
d10801e983
@ -0,0 +1,178 @@ |
|||||||
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under both the GPLv2 (found in the
|
||||||
|
// COPYING file in the root directory) and Apache 2.0 License
|
||||||
|
// (found in the LICENSE.Apache file in the root directory).
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "rocksdb/rocksdb_namespace.h" |
||||||
|
#include "rocksdb/status.h" |
||||||
|
#include "rocksdb/trace_record.h" |
||||||
|
|
||||||
|
namespace ROCKSDB_NAMESPACE { |
||||||
|
|
||||||
|
class MultiValuesTraceExecutionResult; |
||||||
|
class SingleValueTraceExecutionResult; |
||||||
|
class StatusOnlyTraceExecutionResult; |
||||||
|
|
||||||
|
// Base class for the results of all types of trace records.
|
||||||
|
// Theses classes can be used to report the execution result of
|
||||||
|
// TraceRecord::Handler::Handle() or TraceRecord::Accept().
|
||||||
|
class TraceRecordResult { |
||||||
|
public: |
||||||
|
explicit TraceRecordResult(TraceType trace_type); |
||||||
|
|
||||||
|
virtual ~TraceRecordResult() = default; |
||||||
|
|
||||||
|
// Trace type of the corresponding TraceRecord.
|
||||||
|
virtual TraceType GetTraceType() const; |
||||||
|
|
||||||
|
class Handler { |
||||||
|
public: |
||||||
|
virtual ~Handler() = default; |
||||||
|
|
||||||
|
// Handle StatusOnlyTraceExecutionResult
|
||||||
|
virtual Status Handle(const StatusOnlyTraceExecutionResult& result) = 0; |
||||||
|
|
||||||
|
// Handle SingleValueTraceExecutionResult
|
||||||
|
virtual Status Handle(const SingleValueTraceExecutionResult& result) = 0; |
||||||
|
|
||||||
|
// Handle MultiValuesTraceExecutionResult
|
||||||
|
virtual Status Handle(const MultiValuesTraceExecutionResult& result) = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Example handler to just print the trace record execution results. |
||||||
|
* |
||||||
|
* class ResultPrintHandler : public TraceRecordResult::Handler { |
||||||
|
* public: |
||||||
|
* ResultPrintHandler(); |
||||||
|
* ~ResultPrintHandler() override {} |
||||||
|
* |
||||||
|
* Status Handle(const StatusOnlyTraceExecutionResult& result) override { |
||||||
|
* std::cout << "Status: " << result.GetStatus().ToString() << std::endl; |
||||||
|
* } |
||||||
|
* |
||||||
|
* Status Handle(const SingleValueTraceExecutionResult& result) override { |
||||||
|
* std::cout << "Status: " << result.GetStatus().ToString() |
||||||
|
* << ", value: " << result.GetValue() << std::endl; |
||||||
|
* } |
||||||
|
* |
||||||
|
* Status Handle(const MultiValuesTraceExecutionResult& result) override { |
||||||
|
* size_t size = result.GetMultiStatus().size(); |
||||||
|
* for (size_t i = 0; i < size; i++) { |
||||||
|
* std::cout << "Status: " << result.GetMultiStatus()[i].ToString() |
||||||
|
* << ", value: " << result.GetValues()[i] << std::endl; |
||||||
|
* } |
||||||
|
* } |
||||||
|
* }; |
||||||
|
* */ |
||||||
|
|
||||||
|
// Accept the handler.
|
||||||
|
virtual Status Accept(Handler* handler) = 0; |
||||||
|
|
||||||
|
private: |
||||||
|
TraceType trace_type_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Base class for the results from the trace record execution handler (created
|
||||||
|
// by TraceRecord::NewExecutionHandler()).
|
||||||
|
//
|
||||||
|
// The actual execution status or returned values may be hidden from
|
||||||
|
// TraceRecord::Handler::Handle and TraceRecord::Accept. For example, a
|
||||||
|
// GetQueryTraceRecord's execution calls DB::Get() internally. DB::Get() may
|
||||||
|
// return Status::NotFound() but TraceRecord::Handler::Handle() or
|
||||||
|
// TraceRecord::Accept() will still return Status::OK(). The actual status from
|
||||||
|
// DB::Get() and the returned value string may be saved in a
|
||||||
|
// SingleValueTraceExecutionResult.
|
||||||
|
class TraceExecutionResult : public TraceRecordResult { |
||||||
|
public: |
||||||
|
TraceExecutionResult(uint64_t start_timestamp, uint64_t end_timestamp, |
||||||
|
TraceType trace_type); |
||||||
|
|
||||||
|
// Execution start/end timestamps and request latency in microseconds.
|
||||||
|
virtual uint64_t GetStartTimestamp() const; |
||||||
|
virtual uint64_t GetEndTimestamp() const; |
||||||
|
inline uint64_t GetLatency() const { |
||||||
|
return GetEndTimestamp() - GetStartTimestamp(); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
uint64_t ts_start_; |
||||||
|
uint64_t ts_end_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Result for operations that only return a single Status.
|
||||||
|
// Example operations: DB::Write(), Iterator::Seek() and
|
||||||
|
// Iterator::SeekForPrev().
|
||||||
|
class StatusOnlyTraceExecutionResult : public TraceExecutionResult { |
||||||
|
public: |
||||||
|
StatusOnlyTraceExecutionResult(Status status, uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type); |
||||||
|
|
||||||
|
virtual ~StatusOnlyTraceExecutionResult() override = default; |
||||||
|
|
||||||
|
// Return value of DB::Write(), etc.
|
||||||
|
virtual const Status& GetStatus() const; |
||||||
|
|
||||||
|
virtual Status Accept(Handler* handler) override; |
||||||
|
|
||||||
|
private: |
||||||
|
Status status_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Result for operations that return a Status and a value.
|
||||||
|
// Example operation: DB::Get()
|
||||||
|
class SingleValueTraceExecutionResult : public TraceExecutionResult { |
||||||
|
public: |
||||||
|
SingleValueTraceExecutionResult(Status status, const std::string& value, |
||||||
|
uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type); |
||||||
|
|
||||||
|
SingleValueTraceExecutionResult(Status status, std::string&& value, |
||||||
|
uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type); |
||||||
|
|
||||||
|
virtual ~SingleValueTraceExecutionResult() override; |
||||||
|
|
||||||
|
// Return status of DB::Get(), etc.
|
||||||
|
virtual const Status& GetStatus() const; |
||||||
|
|
||||||
|
// Value for the searched key.
|
||||||
|
virtual const std::string& GetValue() const; |
||||||
|
|
||||||
|
virtual Status Accept(Handler* handler) override; |
||||||
|
|
||||||
|
private: |
||||||
|
Status status_; |
||||||
|
std::string value_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Result for operations that return multiple Status(es) and values.
|
||||||
|
// Example operation: DB::MultiGet()
|
||||||
|
class MultiValuesTraceExecutionResult : public TraceExecutionResult { |
||||||
|
public: |
||||||
|
MultiValuesTraceExecutionResult(std::vector<Status> multi_status, |
||||||
|
std::vector<std::string> values, |
||||||
|
uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type); |
||||||
|
|
||||||
|
virtual ~MultiValuesTraceExecutionResult() override; |
||||||
|
|
||||||
|
// Returned Status(es) of DB::MultiGet(), etc.
|
||||||
|
virtual const std::vector<Status>& GetMultiStatus() const; |
||||||
|
|
||||||
|
// Returned values for the searched keys.
|
||||||
|
virtual const std::vector<std::string>& GetValues() const; |
||||||
|
|
||||||
|
virtual Status Accept(Handler* handler) override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::vector<Status> multi_status_; |
||||||
|
std::vector<std::string> values_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace ROCKSDB_NAMESPACE
|
@ -0,0 +1,106 @@ |
|||||||
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under both the GPLv2 (found in the
|
||||||
|
// COPYING file in the root directory) and Apache 2.0 License
|
||||||
|
// (found in the LICENSE.Apache file in the root directory).
|
||||||
|
|
||||||
|
#include "rocksdb/trace_record_result.h" |
||||||
|
|
||||||
|
namespace ROCKSDB_NAMESPACE { |
||||||
|
|
||||||
|
// TraceRecordResult
|
||||||
|
TraceRecordResult::TraceRecordResult(TraceType trace_type) |
||||||
|
: trace_type_(trace_type) {} |
||||||
|
|
||||||
|
TraceType TraceRecordResult::GetTraceType() const { return trace_type_; } |
||||||
|
|
||||||
|
// TraceExecutionResult
|
||||||
|
TraceExecutionResult::TraceExecutionResult(uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, |
||||||
|
TraceType trace_type) |
||||||
|
: TraceRecordResult(trace_type), |
||||||
|
ts_start_(start_timestamp), |
||||||
|
ts_end_(end_timestamp) { |
||||||
|
assert(ts_start_ <= ts_end_); |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t TraceExecutionResult::GetStartTimestamp() const { return ts_start_; } |
||||||
|
|
||||||
|
uint64_t TraceExecutionResult::GetEndTimestamp() const { return ts_end_; } |
||||||
|
|
||||||
|
// StatusOnlyTraceExecutionResult
|
||||||
|
StatusOnlyTraceExecutionResult::StatusOnlyTraceExecutionResult( |
||||||
|
Status status, uint64_t start_timestamp, uint64_t end_timestamp, |
||||||
|
TraceType trace_type) |
||||||
|
: TraceExecutionResult(start_timestamp, end_timestamp, trace_type), |
||||||
|
status_(std::move(status)) {} |
||||||
|
|
||||||
|
const Status& StatusOnlyTraceExecutionResult::GetStatus() const { |
||||||
|
return status_; |
||||||
|
} |
||||||
|
|
||||||
|
Status StatusOnlyTraceExecutionResult::Accept(Handler* handler) { |
||||||
|
assert(handler != nullptr); |
||||||
|
return handler->Handle(*this); |
||||||
|
} |
||||||
|
|
||||||
|
// SingleValueTraceExecutionResult
|
||||||
|
SingleValueTraceExecutionResult::SingleValueTraceExecutionResult( |
||||||
|
Status status, const std::string& value, uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type) |
||||||
|
: TraceExecutionResult(start_timestamp, end_timestamp, trace_type), |
||||||
|
status_(std::move(status)), |
||||||
|
value_(value) {} |
||||||
|
|
||||||
|
SingleValueTraceExecutionResult::SingleValueTraceExecutionResult( |
||||||
|
Status status, std::string&& value, uint64_t start_timestamp, |
||||||
|
uint64_t end_timestamp, TraceType trace_type) |
||||||
|
: TraceExecutionResult(start_timestamp, end_timestamp, trace_type), |
||||||
|
status_(std::move(status)), |
||||||
|
value_(std::move(value)) {} |
||||||
|
|
||||||
|
SingleValueTraceExecutionResult::~SingleValueTraceExecutionResult() { |
||||||
|
value_.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
const Status& SingleValueTraceExecutionResult::GetStatus() const { |
||||||
|
return status_; |
||||||
|
} |
||||||
|
|
||||||
|
const std::string& SingleValueTraceExecutionResult::GetValue() const { |
||||||
|
return value_; |
||||||
|
} |
||||||
|
|
||||||
|
Status SingleValueTraceExecutionResult::Accept(Handler* handler) { |
||||||
|
assert(handler != nullptr); |
||||||
|
return handler->Handle(*this); |
||||||
|
} |
||||||
|
|
||||||
|
// MultiValuesTraceExecutionResult
|
||||||
|
MultiValuesTraceExecutionResult::MultiValuesTraceExecutionResult( |
||||||
|
std::vector<Status> multi_status, std::vector<std::string> values, |
||||||
|
uint64_t start_timestamp, uint64_t end_timestamp, TraceType trace_type) |
||||||
|
: TraceExecutionResult(start_timestamp, end_timestamp, trace_type), |
||||||
|
multi_status_(std::move(multi_status)), |
||||||
|
values_(std::move(values)) {} |
||||||
|
|
||||||
|
MultiValuesTraceExecutionResult::~MultiValuesTraceExecutionResult() { |
||||||
|
multi_status_.clear(); |
||||||
|
values_.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
const std::vector<Status>& MultiValuesTraceExecutionResult::GetMultiStatus() |
||||||
|
const { |
||||||
|
return multi_status_; |
||||||
|
} |
||||||
|
|
||||||
|
const std::vector<std::string>& MultiValuesTraceExecutionResult::GetValues() |
||||||
|
const { |
||||||
|
return values_; |
||||||
|
} |
||||||
|
|
||||||
|
Status MultiValuesTraceExecutionResult::Accept(Handler* handler) { |
||||||
|
assert(handler != nullptr); |
||||||
|
return handler->Handle(*this); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace ROCKSDB_NAMESPACE
|
Loading…
Reference in new issue