'purging': dir_state.purging}
return None
+ def get_tracked_instance_id(self, dir_path):
+ lookup = self.lookup(dir_path)
+ if not lookup:
+ return None
+ return lookup.get('instance_id')
+
def map(self, dir_path, dir_state):
log.debug(f'mapping {dir_path}')
min_instance_id = None
metrics.setdefault(dir_path, {}).setdefault('peer', {})[peer_uuid] = stat
+def _mark_sync_stat_stale(stat):
+ out = dict(stat)
+ out.pop('current_syncing_snap', None)
+ out['state'] = 'stale'
+ return out
+
+
+def _apply_stale_sync_metrics(stat, policy=None, dir_path=None,
+ live_instance_ids=None):
+ if not isinstance(stat, dict) or policy is None or dir_path is None:
+ return stat
+
+ persisted_instance_id = stat.get('_instance_id')
+ if persisted_instance_id is None:
+ return stat
+
+ persisted_id = str(persisted_instance_id)
+ if (live_instance_ids is not None and
+ persisted_id not in live_instance_ids):
+ return _mark_sync_stat_stale(stat)
+
+ tracked_id = policy.get_tracked_instance_id(dir_path)
+ if tracked_id is not None:
+ tracked_id = str(tracked_id)
+ if (tracked_id != persisted_id and
+ stat.get('state') != 'idle'):
+ return _mark_sync_stat_stale(stat)
+ return stat
+
+
# to match the output of peer_status
-def format_and_order_sync_stat_for_display(stat):
+def format_and_order_sync_stat_for_display(stat, policy=None, dir_path=None,
+ live_instance_ids=None):
if not isinstance(stat, dict):
return stat
- out = dict(stat)
+ out = dict(_apply_stale_sync_metrics(
+ stat, policy, dir_path, live_instance_ids))
last_synced_snap = out.get('last_synced_snap')
if isinstance(last_synced_snap, dict):
snap = dict(last_synced_snap)
f'failed to open metadata pool for {filesystem}')
-def load_sync_stat_metrics(ioctx, filesystem, peer_uuid=None):
+def load_sync_stat_metrics(ioctx, filesystem, peer_uuid=None, policy=None,
+ live_instance_ids=None):
metrics: Dict[str, Any] = {}
prefix = f'{SYNC_STAT_KEY_PREFIX}/{filesystem}/'
if peer_uuid:
continue
format_peer_status_metrics(
metrics, dir_path, peer,
- format_and_order_sync_stat_for_display(stat))
+ format_and_order_sync_stat_for_display(
+ stat, policy, dir_path, live_instance_ids))
start = omap_vals.popitem()[0]
except rados.Error as e:
log.error(f'failed to read sync stat omap: {e}')
return metrics
-def fetch_sync_stat_metrics(ioctx, filesystem, peers, mirrored_dir_path, peer_uuid):
+def fetch_sync_stat_metrics(ioctx, filesystem, peers, mirrored_dir_path,
+ peer_uuid, policy=None, live_instance_ids=None):
if mirrored_dir_path:
dir_path = norm_path(mirrored_dir_path)
keys = [sync_stat_omap_key(filesystem, peer, dir_path) for peer in peers]
if stat is not None:
format_peer_status_metrics(
metrics, dir_path, peer,
- format_and_order_sync_stat_for_display(stat))
+ format_and_order_sync_stat_for_display(
+ stat, policy, dir_path, live_instance_ids))
return metrics, False, dir_path
- metrics = load_sync_stat_metrics(ioctx, filesystem, peer_uuid)
+ metrics = load_sync_stat_metrics(
+ ioctx, filesystem, peer_uuid, policy, live_instance_ids)
return metrics, True, None
def schedule_action(self, dir_paths):
self.dir_paths.extend(dir_paths)
+ def get_live_instance_ids(self):
+ watcher = self.instance_watcher
+ if watcher is None:
+ return None
+ with watcher.lock:
+ return frozenset(str(instance_id) for instance_id in watcher.instances)
+
def init(self, dir_mapping, instances):
with self.lock:
self.policy.init(dir_mapping)
"""
log.debug('sync stat metrics for filesystem %s loaded from omap (complete)',
filesystem)
+ fspolicy = self.pool_policy[filesystem]
ioctx = metrics_load.open_metadata_ioctx(
self.rados, self.fs_map, filesystem)
- return metrics_load.load_sync_stat_metrics(ioctx, filesystem)
+ return metrics_load.load_sync_stat_metrics(
+ ioctx, filesystem, None, fspolicy.policy,
+ fspolicy.get_live_instance_ids())
@lru_cache_timeout(
lambda self, *_args, **_kwargs: CACHE_TTL_SECS,
'loaded from omap',
filesystem, dir_path, peer_scope)
peers = {peer_id: None for peer_id in peer_ids}
+ fspolicy = self.pool_policy[filesystem]
ioctx = metrics_load.open_metadata_ioctx(
self.rados, self.fs_map, filesystem)
metrics, _, _ = metrics_load.fetch_sync_stat_metrics(
- ioctx, filesystem, peers, dir_path, None)
+ ioctx, filesystem, peers, dir_path, None,
+ fspolicy.policy, fspolicy.get_live_instance_ids())
return metrics
def metrics_status(self, filesystem, mirrored_dir_path, peer_uuid):