deleteExpiredKeys method

Future<int> deleteExpiredKeys()

Deletes every key currently flagged expired by the underlying HiveKeystore's in-memory cache. Each deletion goes through _delete, which fires a DataDeleted on AtClient.dataEvents — so subscribers see expirations the same way they see any other delete. Returns the number of keys removed.

Callers arming a timer via AtClient.dataEvents should suppress re-arms while a sweep is in flight (the events fired during this method would otherwise cause N redundant re-arms). AtClientImpl._onExpiryFire does this via a _sweepInFlight flag.

Returns 0 (no-op) when the underlying keystore is not a HiveKeystore; non-Hive keystores are responsible for their own expiry mechanism if any.

Implementation

Future<int> deleteExpiredKeys() async {
  final ks = keyStore;
  if (ks is! HiveKeystore) {
    _logger.shout('Underlying keyStore is not HiveKeystore');
    return 0;
  }
  final expired = await ks.getExpiredKeys();
  if (expired.isEmpty) return 0;
  var deleted = 0;
  for (final keyString in expired) {
    try {
      final atKey = AtKey.fromString(keyString);
      final builder = DeleteVerbBuilder()..atKey = atKey;
      _logger.finer('Deleting expired key $atKey');
      // localOnly: true — TTL expiry happens autonomously at every
      // tier of the Atsign Protocol (publisher atServer, receiver
      // atServer, every atClient). No client→server push needed;
      // the publisher's atServer has already dropped (or will drop)
      // its own copy at the same TTL, and is responsible for the
      // recipients' `cached:` evictions.
      await _delete(builder, localOnly: true);
      deleted++;
    } on Exception catch (e) {
      _logger.warning('expiry sweep failed for $keyString: $e');
    }
  }
  return deleted;
}