Skip to content

Commit 183c381

Browse files
fix: Watching resource with old version should restart (#735)
Fixes #724 Restart the watch loop when we receive HTTP 410 Gone, which seems to mirror what other k8s frameworks are doing (see: java).
1 parent cbe7209 commit 183c381

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

src/KubeOps.Operator/Watcher/ResourceWatcher{TEntity}.cs

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Concurrent;
2+
using System.Net;
23
using System.Runtime.Serialization;
34
using System.Text.Json;
45

@@ -59,39 +60,58 @@ private async Task WatchClientEventsAsync(CancellationToken stoppingToken)
5960
{
6061
try
6162
{
62-
await foreach ((WatchEventType type, TEntity? entity) in client.WatchAsync<TEntity>(
63-
settings.Namespace,
64-
cancellationToken: stoppingToken))
63+
while (!stoppingToken.IsCancellationRequested)
6564
{
65+
await foreach ((WatchEventType type, TEntity? entity) in client.WatchAsync<TEntity>(
66+
settings.Namespace,
67+
cancellationToken: stoppingToken))
68+
{
6669
#pragma warning disable SA1312
67-
using var _ = logger.BeginScope(new
70+
using var _ = logger.BeginScope(new
6871
#pragma warning restore SA1312
69-
{
70-
EventType = type,
71-
72-
// ReSharper disable once RedundantAnonymousTypePropertyName
73-
Kind = entity?.Kind,
74-
Name = entity?.Name(),
75-
ResourceVersion = entity?.ResourceVersion(),
76-
});
77-
logger.LogInformation(
78-
"""Received watch event "{EventType}" for "{Kind}/{Name}", last observed resource version: {ResourceVersion}.""",
79-
type,
80-
entity?.Kind,
81-
entity?.Name(),
82-
entity?.ResourceVersion());
83-
try
84-
{
85-
await OnEventAsync(type, entity, stoppingToken);
86-
}
87-
catch (Exception e)
88-
{
89-
logger.LogError(
90-
e,
91-
"Reconciliation of {EventType} for {Kind}/{Name} failed.",
72+
{
73+
EventType = type,
74+
75+
// ReSharper disable once RedundantAnonymousTypePropertyName
76+
Kind = entity?.Kind,
77+
Name = entity?.Name(),
78+
ResourceVersion = entity?.ResourceVersion(),
79+
});
80+
logger.LogInformation(
81+
"""Received watch event "{EventType}" for "{Kind}/{Name}", last observed resource version: {ResourceVersion}.""",
9282
type,
9383
entity?.Kind,
94-
entity.Name());
84+
entity?.Name(),
85+
entity?.ResourceVersion());
86+
try
87+
{
88+
await OnEventAsync(type, entity, stoppingToken);
89+
}
90+
catch (KubernetesException e)
91+
{
92+
if (e.Status.Code == (int)HttpStatusCode.Gone)
93+
{
94+
logger.LogDebug("Watch restarting due to 410 HTTP Gone");
95+
96+
break;
97+
}
98+
99+
LogReconciliationFailed(e);
100+
}
101+
catch (Exception e)
102+
{
103+
LogReconciliationFailed(e);
104+
}
105+
106+
void LogReconciliationFailed(Exception exception)
107+
{
108+
logger.LogError(
109+
exception,
110+
"Reconciliation of {EventType} for {Kind}/{Name} failed.",
111+
type,
112+
entity?.Kind,
113+
entity.Name());
114+
}
95115
}
96116
}
97117
}

0 commit comments

Comments
 (0)