auditRedisKeys function

Future<RedisKeysAudit> auditRedisKeys(
  1. RedisClient client, {
  2. required String match,
  3. required String cachePrefix,
  4. int limit = 20,
})

Every key matching match (on every master), counted by type, and the keys under cachePrefix that never expire, at most limit of them: what a cache that only grows looks like.

Implementation

Future<RedisKeysAudit> auditRedisKeys(
  RedisClient client, {
  required String match,
  required String cachePrefix,
  int limit = 20,
}) async {
  var keys = 0;
  var withoutTtl = 0;
  final types = <String, int>{};
  final cacheWithoutTtl = <String>[];
  final batch = <String>[];
  Future<void> inspect() async {
    final replies = await client.pipeline([
      for (final key in batch) ...[
        ['TYPE', key],
        ['PTTL', key],
      ],
    ]);
    for (var i = 0; i < batch.length; i++) {
      final type = '${replies[i * 2]}';
      types[type] = (types[type] ?? 0) + 1;
      if (replies[i * 2 + 1] == -1) {
        withoutTtl++;
        if (batch[i].startsWith(cachePrefix) &&
            cacheWithoutTtl.length < limit) {
          cacheWithoutTtl.add(batch[i]);
        }
      }
    }
    keys += batch.length;
    batch.clear();
  }

  await for (final key in client.scan(match: match)) {
    batch.add(key);
    if (batch.length >= 200) {
      await inspect();
    }
  }
  if (batch.isNotEmpty) {
    await inspect();
  }
  return (
    keys: keys,
    types: types,
    withoutTtl: withoutTtl,
    cacheWithoutTtl: cacheWithoutTtl,
  );
}