if (object_player->empty() && object_player->refetch_required()) {
ldout(m_cct, 10) << "refetching potentially partially decoded object"
<< dendl;
- object_player->clear_refetch_required();
+ object_player->set_refetch_state(ObjectPlayer::REFETCH_STATE_NONE);
fetch(object_player);
} else if (!remove_empty_object_player(object_player)) {
ldout(m_cct, 10) << "prefetch of object complete" << dendl;
m_prune_tag_tid = tag_tid;
}
+ bool pruned = false;
for (auto &player_pair : m_object_players) {
ObjectPlayerPtr object_player(player_pair.second);
ldout(m_cct, 15) << __func__ << ": checking " << object_player->get_oid()
if (entry.get_tag_tid() == tag_tid) {
ldout(m_cct, 20) << __func__ << ": pruned " << entry << dendl;
object_player->pop_front();
+ pruned = true;
} else {
break;
}
}
+ }
+
+ // avoid watch delay when pruning stale tags from journal objects
+ if (pruned) {
+ ldout(m_cct, 15) << __func__ << ": reseting refetch state to immediate"
+ << dendl;
+ for (auto &player_pair : m_object_players) {
+ ObjectPlayerPtr object_player(player_pair.second);
+ object_player->set_refetch_state(ObjectPlayer::REFETCH_STATE_IMMEDIATE);
+ }
+ }
- // trim empty player to prefetch the next available object
+ // trim empty player to prefetch the next available object
+ for (auto &player_pair : m_object_players) {
remove_empty_object_player(player_pair.second);
}
}
<< "require refetch" << dendl;
m_active_set = active_set;
for (auto &pair : m_object_players) {
- pair.second->set_refetch_required();
+ pair.second->set_refetch_state(ObjectPlayer::REFETCH_STATE_IMMEDIATE);
}
return false;
}
ObjectPlayerPtr object_player = get_object_player();
if (object_player->refetch_required()) {
- object_player->clear_refetch_required();
+ object_player->set_refetch_state(ObjectPlayer::REFETCH_STATE_NONE);
fetch(object_player);
return;
}
uint64_t active_set = m_journal_metadata->get_active_set();
uint64_t object_set = object_player->get_object_number() / splay_width;
if (immediate ||
+ (object_player->get_refetch_state() ==
+ ObjectPlayer::REFETCH_STATE_IMMEDIATE) ||
(object_set < active_set && object_player->refetch_required())) {
- ldout(m_cct, 20) << __func__ << ": refetching "
+ ldout(m_cct, 20) << __func__ << ": immediately refetching "
<< object_player->get_oid()
<< dendl;
- object_player->clear_refetch_required();
+ object_player->set_refetch_state(ObjectPlayer::REFETCH_STATE_NONE);
watch_interval = 0;
}
}
typedef std::list<Entry> Entries;
typedef interval_set<uint64_t> InvalidRanges;
+ enum RefetchState {
+ REFETCH_STATE_NONE,
+ REFETCH_STATE_REQUIRED,
+ REFETCH_STATE_IMMEDIATE
+ };
+
ObjectPlayer(librados::IoCtx &ioctx, const std::string &object_oid_prefix,
uint64_t object_num, SafeTimer &timer, Mutex &timer_lock,
uint8_t order, uint64_t max_fetch_bytes);
}
inline bool refetch_required() const {
- return m_refetch_required;
+ return (get_refetch_state() != REFETCH_STATE_NONE);
}
- inline void set_refetch_required() {
- m_refetch_required = true;
+ inline RefetchState get_refetch_state() const {
+ return m_refetch_state;
}
- inline void clear_refetch_required() {
- m_refetch_required = false;
+ inline void set_refetch_state(RefetchState refetch_state) {
+ m_refetch_state = refetch_state;
}
private:
Context *m_watch_ctx = nullptr;
bool m_unwatched = false;
- bool m_refetch_required = true;
+ RefetchState m_refetch_state = REFETCH_STATE_IMMEDIATE;
int handle_fetch_complete(int r, const bufferlist &bl, bool *refetch);