Skip to content

Commit

Permalink
KV get keys should not hang with deleted keys (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtmk authored Dec 22, 2023
1 parent ed1d42c commit 0cf8666
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/NATS.Client.KeyValueStore/NatsKVStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ public async IAsyncEnumerable<string> GetKeysAsync(NatsKVWatchOpts? opts = defau

opts = opts with
{
IgnoreDeletes = true,
IgnoreDeletes = false,
MetaOnly = true,
UpdatesOnly = false,
};
Expand All @@ -427,7 +427,8 @@ public async IAsyncEnumerable<string> GetKeysAsync(NatsKVWatchOpts? opts = defau
{
while (watcher.Entries.TryRead(out var entry))
{
yield return entry.Key;
if (entry.Operation is NatsKVOperation.Put)
yield return entry.Key;
if (entry.Delta == 0)
yield break;
}
Expand Down
48 changes: 48 additions & 0 deletions tests/NATS.Client.KeyValueStore.Tests/GetKeysTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using NATS.Client.Core.Tests;

namespace NATS.Client.KeyValueStore.Tests;

public class GetKeysTest
{
[Fact]
public async Task Get_keys_should_not_hang_when_there_are_deleted_keys()
{
const string bucket = "b1";
var config = new NatsKVConfig(bucket) { History = 10 };

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var cancellationToken = cts.Token;

await using var server = NatsServer.StartJS();
await using var nats1 = server.CreateClientConnection();
var js1 = new NatsJSContext(nats1);
var kv1 = new NatsKVContext(js1);
var store1 = await kv1.CreateStoreAsync(config, cancellationToken: cancellationToken);

await store1.PutAsync("k1", 1, cancellationToken: cancellationToken);
await store1.PutAsync("k2", 2, cancellationToken: cancellationToken);
await store1.PutAsync("k3", 3, cancellationToken: cancellationToken);

var ks1 = new List<string>();
await foreach (var k in store1.GetKeysAsync(cancellationToken: cancellationToken))
{
ks1.Add(k);
}

ks1.Sort();

Assert.Equal(new List<string> { "k1", "k2", "k3" }, ks1);

await store1.DeleteAsync("k2", cancellationToken: cancellationToken);

var ks2 = new List<string>();
await foreach (var k in store1.GetKeysAsync(cancellationToken: cancellationToken))
{
ks2.Add(k);
}

ks2.Sort();

Assert.Equal(new List<string> { "k1", "k3" }, ks2);
}
}

0 comments on commit 0cf8666

Please sign in to comment.