Skip to content
This repository was archived by the owner on Oct 9, 2020. It is now read-only.

Commit d261d37

Browse files
committed
Fix: before watching, fetch list, to get a recent resource_version to watch from
Watch() only returns entries, not the list. Entries in a list can be very old, and no longer valid to watch from. Additionally, the initial list watch() returns is unordered. To correct way of doing this is first list the entries. Here the list itself contains a resource_version that is recent. Using this version to watch will result in a correct watch(). A lot has been written about this. Most clear resource for me was: kubernetes-client/python#819
1 parent f84c918 commit d261d37

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

deployer/monitor.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,39 @@
1313
}
1414

1515

16+
def _emit_event(event):
17+
module = type_mapping.get(event["type"])
18+
if module:
19+
asyncio.ensure_future(module.handle_event(event))
20+
21+
1622
async def monitor(crds, namespace):
1723
log.info(f"Monitoring charts.k8s.openttd.org in namespace '{namespace}' for changes ...")
1824

19-
stream = watch.Watch().stream(crds.list_namespaced_custom_object,
20-
"k8s.openttd.org",
21-
"v1",
22-
namespace,
23-
"charts",
24-
_request_timeout=30)
25-
async for event in stream:
26-
module = type_mapping.get(event["type"])
27-
if module:
28-
asyncio.ensure_future(module.handle_event(event))
29-
30-
log.info(f"Monitoring in namespace '{namespace}' stopped")
25+
# Prepare what function we want to call with which parameters
26+
func = crds.list_namespaced_custom_object
27+
args = ["k8s.openttd.org", "v1", namespace, "charts"]
28+
29+
# Start by listing all entries, and emit an 'ADDED' for each existing
30+
# entry. This allows us to get in a known-good-state, and monitor all
31+
# changes after.
32+
initial_list = await func(*args)
33+
for item in initial_list['items']:
34+
_emit_event({"type": "ADDED", "object": item})
35+
36+
# The list has the resource_version we should use as starting point of
37+
# our watch().
38+
resource_version = initial_list['metadata']['resourceVersion']
39+
40+
my_watch = watch.Watch()
41+
# XXX - kubernetes-asyncio has not sync'd with upstream yet.
42+
# See https://github.com/kubernetes-client/python-base/commit/2d69e89dab7134186cbcdaf82381ab6295c6c394
43+
# and https://github.com/tomplus/kubernetes_asyncio/issues/77
44+
# If this gets fixed, the next line can be removed.
45+
my_watch.resource_version = resource_version
46+
47+
async with my_watch.stream(func, *args, resource_version=resource_version, _request_timeout=30) as stream:
48+
async for event in stream:
49+
_emit_event(event)
50+
51+
log.error(f"Monitoring in namespace '{namespace}' stopped unexpectedly")

0 commit comments

Comments
 (0)