Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track timestamp of each state in repl_dev_ctx. #514

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class HomestoreConan(ConanFile):
name = "homestore"
version = "6.4.55"
version = "6.4.56"

homepage = "https://github.com/eBay/Homestore"
description = "HomeStore Storage Engine"
Expand Down
15 changes: 11 additions & 4 deletions src/include/homestore/replication/repl_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ VENUM(repl_req_state_t, uint32_t,
DATA_WRITTEN = 1 << 2, // Data has been written to the storage
LOG_RECEIVED = 1 << 3, // Log is received and waiting for data
LOG_FLUSHED = 1 << 4, // Log has been flushed
ERRORED = 1 << 5 // Error has happened and cleaned up
ERRORED = 1 << 5, // Error has happened and cleaned up
LAST_STATE // Automatically adjusts to count the number of states
)

VENUM(journal_type_t, uint16_t,
Expand Down Expand Up @@ -125,7 +126,7 @@ struct repl_req_ctx : public boost::intrusive_ref_counter< repl_req_ctx, boost::
friend class SoloReplDev;

public:
repl_req_ctx() {}
repl_req_ctx() { m_timestamps[std::bit_width(uint32_cast(repl_req_state_t::INIT))] = Clock::now(); }
virtual ~repl_req_ctx();
void init(repl_key rkey, journal_type_t op_code, bool is_proposer, sisl::blob const& user_header,
sisl::blob const& key, uint32_t data_size);
Expand Down Expand Up @@ -156,8 +157,12 @@ struct repl_req_ctx : public boost::intrusive_ref_counter< repl_req_ctx, boost::
/////////////////////// Non modifiers methods //////////////////
std::string to_string() const;
std::string to_compact_string() const;
Clock::time_point created_time() const { return m_start_time; }
void set_created_time() { m_start_time = Clock::now(); }
Clock::time_point created_time() const { return ts_of_state(repl_req_state_t::INIT); }
Clock::time_point ts_of_state(repl_req_state_t state) const {
return m_timestamps[std::bit_width(uint32_cast(state))];
}
uint64_t time_from(repl_req_state_t s) const { return get_elapsed_time_sec(ts_of_state(s)); }
void print_timestamps() const;
bool is_expired() const;

/////////////////////// All Modifiers methods //////////////////
Expand Down Expand Up @@ -221,6 +226,8 @@ struct repl_req_ctx : public boost::intrusive_ref_counter< repl_req_ctx, boost::
std::mutex m_state_mtx;

private:
static constexpr int MAX_STATES = std::bit_width(uint32_t(repl_req_state_t::LAST_STATE));
Clock::time_point m_timestamps[MAX_STATES]; // timestamp of reaching each state
repl_key m_rkey; // Unique key for the request
sisl::blob m_header; // User header
sisl::blob m_key; // User supplied key for this req
Expand Down
17 changes: 15 additions & 2 deletions src/lib/replication/repl_dev/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,34 @@ bool repl_req_ctx::save_fetched_data(sisl::GenericClientResponse const& fetched_
return true;
}

void repl_req_ctx::add_state(repl_req_state_t s) { m_state.fetch_or(uint32_cast(s)); }
void repl_req_ctx::add_state(repl_req_state_t s) {
m_state.fetch_or(uint32_cast(s));
m_timestamps[std::bit_width(uint32_cast(s))] = Clock::now();
}

bool repl_req_ctx::add_state_if_not_already(repl_req_state_t s) {
bool changed{false};
auto cur_v = m_state.load();
while (!(cur_v & uint32_cast(s))) {
if (m_state.compare_exchange_weak(cur_v, cur_v | uint32_cast(s))) {
changed = true;
m_timestamps[std::bit_width(uint32_cast(s))] = Clock::now();
break;
}
}

return changed;
}

void repl_req_ctx::print_timestamps() const {
for (int i = 0; i < MAX_STATES; i++) {
if (m_timestamps[i] != Clock::time_point())
std::cout
<< "State " << i << " Timestamp "
<< std::chrono::duration_cast< std::chrono::milliseconds >(m_timestamps[i] - m_timestamps[0]).count();
}
}

void repl_req_ctx::clear() {
m_header = sisl::blob{};
m_key = sisl::blob{};
Expand Down Expand Up @@ -200,7 +213,7 @@ std::string repl_req_ctx::to_compact_string() const {
}

bool repl_req_ctx::is_expired() const {
return get_elapsed_time_sec(m_start_time) > HS_DYNAMIC_CONFIG(consensus.repl_req_timeout_sec);
return time_from(repl_req_state_t::LOG_RECEIVED) > HS_DYNAMIC_CONFIG(consensus.repl_req_timeout_sec);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if log received, before follower received the data (rreq will also be created), originator is gone, we should also clean up the rreqs, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes right now (the PR) is trying to be compatible with original implementation for is_expired, mainly to bring in all the timestamp we have as a foundation of next step

I think we discussed the GC stuff a bit today and that need a seperate design, we can visit that later.

}

} // namespace homestore
2 changes: 0 additions & 2 deletions src/lib/replication/repl_dev/raft_state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,6 @@ void RaftStateMachine::unlink_lsn_to_req(int64_t lsn) {
void RaftStateMachine::link_lsn_to_req(repl_req_ptr_t rreq, int64_t lsn) {
rreq->set_lsn(lsn);
rreq->add_state(repl_req_state_t::LOG_RECEIVED);
// reset the rreq created_at time to now https://github.com/eBay/HomeStore/issues/506
rreq->set_created_time();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no as I changed the is_expired() implementation.

[[maybe_unused]] auto r = m_lsn_req_map.insert(lsn, std::move(rreq));
RD_DBG_ASSERT_EQ(r.second, true, "lsn={} already in precommit list", lsn);
}
Expand Down
Loading