Skip to content

Commit

Permalink
fix: Watching resource with old version should restart (#735)
Browse files Browse the repository at this point in the history
Fixes #724 

Restart the watch loop when we receive HTTP 410 Gone, which seems to
mirror what other k8s frameworks are doing (see: java).
  • Loading branch information
robertcoltheart committed Mar 13, 2024
1 parent cbe7209 commit 183c381
Showing 1 changed file with 48 additions and 28 deletions.
76 changes: 48 additions & 28 deletions src/KubeOps.Operator/Watcher/ResourceWatcher{TEntity}.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using System.Net;
using System.Runtime.Serialization;
using System.Text.Json;

Expand Down Expand Up @@ -59,39 +60,58 @@ private async Task WatchClientEventsAsync(CancellationToken stoppingToken)
{
try
{
await foreach ((WatchEventType type, TEntity? entity) in client.WatchAsync<TEntity>(
settings.Namespace,
cancellationToken: stoppingToken))
while (!stoppingToken.IsCancellationRequested)
{
await foreach ((WatchEventType type, TEntity? entity) in client.WatchAsync<TEntity>(
settings.Namespace,
cancellationToken: stoppingToken))
{
#pragma warning disable SA1312
using var _ = logger.BeginScope(new
using var _ = logger.BeginScope(new
#pragma warning restore SA1312
{
EventType = type,

// ReSharper disable once RedundantAnonymousTypePropertyName
Kind = entity?.Kind,
Name = entity?.Name(),
ResourceVersion = entity?.ResourceVersion(),
});
logger.LogInformation(
"""Received watch event "{EventType}" for "{Kind}/{Name}", last observed resource version: {ResourceVersion}.""",
type,
entity?.Kind,
entity?.Name(),
entity?.ResourceVersion());
try
{
await OnEventAsync(type, entity, stoppingToken);
}
catch (Exception e)
{
logger.LogError(
e,
"Reconciliation of {EventType} for {Kind}/{Name} failed.",
{
EventType = type,

// ReSharper disable once RedundantAnonymousTypePropertyName
Kind = entity?.Kind,
Name = entity?.Name(),
ResourceVersion = entity?.ResourceVersion(),
});
logger.LogInformation(
"""Received watch event "{EventType}" for "{Kind}/{Name}", last observed resource version: {ResourceVersion}.""",
type,
entity?.Kind,
entity.Name());
entity?.Name(),
entity?.ResourceVersion());
try
{
await OnEventAsync(type, entity, stoppingToken);
}
catch (KubernetesException e)
{
if (e.Status.Code == (int)HttpStatusCode.Gone)
{
logger.LogDebug("Watch restarting due to 410 HTTP Gone");

break;
}

LogReconciliationFailed(e);
}
catch (Exception e)
{
LogReconciliationFailed(e);
}

void LogReconciliationFailed(Exception exception)
{
logger.LogError(
exception,
"Reconciliation of {EventType} for {Kind}/{Name} failed.",
type,
entity?.Kind,
entity.Name());
}
}
}
}
Expand Down

0 comments on commit 183c381

Please sign in to comment.