Skip to content

Commit

Permalink
fix: Use namespace and name for requeueing of entities (#801)
Browse files Browse the repository at this point in the history
Fixes #800
  • Loading branch information
robertcoltheart authored Aug 23, 2024
1 parent d408fe0 commit de986bf
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/KubeOps.Operator/Queue/TimedEntityQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal sealed class TimedEntityQueue<TEntity> : IDisposable
public void Enqueue(TEntity entity, TimeSpan requeueIn)
{
_management.AddOrUpdate(
entity.Name() ?? throw new InvalidOperationException("Cannot enqueue entities without name."),
GetKey(entity) ?? throw new InvalidOperationException("Cannot enqueue entities without name."),
key =>
{
var entry = new TimedQueueEntry<TEntity>(entity, requeueIn);
Expand Down Expand Up @@ -81,15 +81,30 @@ public async IAsyncEnumerator<TEntity> GetAsyncEnumerator(CancellationToken canc

public void Remove(TEntity entity)
{
var name = entity.Name();
if (name is null)
var key = GetKey(entity);
if (key is null)
{
return;
}

if (_management.Remove(name, out var task))
if (_management.Remove(key, out var task))
{
task.Cancel();
}
}

private string? GetKey(TEntity entity)
{
if (entity.Name() is null)
{
return null;
}

if (entity.Namespace() is null)
{
return entity.Name();
}

return $"{entity.Namespace()}/{entity.Name()}";
}
}
49 changes: 49 additions & 0 deletions test/KubeOps.Operator.Test/Queue/TimedEntityQueue.Test.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using k8s.Models;

using KubeOps.Operator.Queue;

namespace KubeOps.Operator.Test.Queue;

public class TimedEntityQueueTest
{
[Fact]
public async Task Can_Enqueue_Multiple_Entities_With_Same_Name()
{
var queue = new TimedEntityQueue<V1Secret>();

queue.Enqueue(CreateSecret("app-ns1", "secret-name"), TimeSpan.FromSeconds(1));
queue.Enqueue(CreateSecret("app-ns2", "secret-name"), TimeSpan.FromSeconds(1));

var items = new List<V1Secret>();

var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(2));

var enumerator = queue.GetAsyncEnumerator(tokenSource.Token);

try
{
while (await enumerator.MoveNextAsync())
{
items.Add(enumerator.Current);
}
}
catch (OperationCanceledException)
{
// We expect to timeout watching the queue so that we can assert the items received
}

Assert.Equal(2, items.Count);
}

private V1Secret CreateSecret(string secretNamespace, string secretName)
{
var secret = new V1Secret();
secret.EnsureMetadata();

secret.Metadata.SetNamespace(secretNamespace);
secret.Metadata.Name = secretName;

return secret;
}
}

0 comments on commit de986bf

Please sign in to comment.