Skip to content

Commit ed3d82a

Browse files
authored
Merge pull request #2505 from note35/watch
Handle BOOKMARK events in watch.py
2 parents 6fb1fd7 + 4618df8 commit ed3d82a

2 files changed

Lines changed: 31 additions & 15 deletions

File tree

kubernetes/base/watch/watch.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,18 @@ def unmarshal_event(self, data, return_type):
114114
try:
115115
js = json.loads(data)
116116
js['raw_object'] = js['object']
117-
# BOOKMARK event is treated the same as ERROR for a quick fix of
118-
# decoding exception
119-
# TODO: make use of the resource_version in BOOKMARK event for more
120-
# efficient WATCH
121-
if return_type and js['type'] != 'ERROR' and js['type'] != 'BOOKMARK':
117+
118+
if not return_type:
119+
return js
120+
121+
if js['type'] == 'BOOKMARK':
122+
# Extract and store resource_version from BOOKMARK event for
123+
# efficiency. No deserialization as event can be incomplete.
124+
if isinstance(js['object'], dict) and 'metadata' in js['object']:
125+
metadata = js['object']['metadata']
126+
if isinstance(metadata, dict) and 'resourceVersion' in metadata:
127+
self.resource_version = metadata['resourceVersion']
128+
elif js['type'] != 'ERROR':
122129
obj = SimpleNamespace(data=json.dumps(js['raw_object']))
123130
js['object'] = self._api_client.deserialize(obj, return_type)
124131
if hasattr(js['object'], 'metadata'):

kubernetes/base/watch/watch_test.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import unittest
16-
1715
import os
18-
1916
import time
20-
17+
import unittest
2118
from unittest.mock import Mock, call
2219

23-
from kubernetes import client,config
20+
from kubernetes import client, config
21+
from kubernetes.client import ApiException
2422

2523
from .watch import Watch
2624

27-
from kubernetes.client import ApiException
28-
2925

3026
class WatchTests(unittest.TestCase):
3127
def setUp(self):
@@ -392,9 +388,22 @@ def test_unmarshal_with_bookmark(self):
392388
'"metadata":{},"spec":{"containers":null}}},"status":{}}}',
393389
'V1Job')
394390
self.assertEqual("BOOKMARK", event['type'])
395-
# Watch.resource_version is *not* updated, as BOOKMARK is treated the
396-
# same as ERROR for a quick fix of decoding exception,
397-
# resource_version in BOOKMARK is *not* used at all.
391+
self.assertEqual("1", w.resource_version)
392+
393+
def test_unmarshal_with_bookmark_metadata_not_in_dict(self):
394+
w = Watch()
395+
event = w.unmarshal_event(
396+
'{"type":"BOOKMARK","object":{"metadata": "not-a-dict"}}',
397+
'V1Job')
398+
self.assertEqual("BOOKMARK", event['type'])
399+
self.assertEqual(None, w.resource_version)
400+
401+
def test_unmarshal_with_bookmark_metadata_without_resource_version(self):
402+
w = Watch()
403+
event = w.unmarshal_event(
404+
'{"type":"BOOKMARK","object":{"metadata": {"name": "foo"}}}',
405+
'V1Job')
406+
self.assertEqual("BOOKMARK", event['type'])
398407
self.assertEqual(None, w.resource_version)
399408

400409
def test_watch_with_exception(self):

0 commit comments

Comments
 (0)