From d11b866e6e392d02a2f38ae5cac73ba5cc8ddb93 Mon Sep 17 00:00:00 2001 From: zhihua Date: Sun, 27 Apr 2025 15:24:40 +0800 Subject: [PATCH 1/4] fix: waiting sync_response --- gnmi_cli_py/py_gnmicli.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gnmi_cli_py/py_gnmicli.py b/gnmi_cli_py/py_gnmicli.py index 0ea6f3d5..5eaf596e 100644 --- a/gnmi_cli_py/py_gnmicli.py +++ b/gnmi_cli_py/py_gnmicli.py @@ -496,9 +496,12 @@ def subscribe_start(stub, options, req_iterator): try: responses = stub.Subscribe(req_iterator, options['timeout'], metadata=metadata) update_count = 0 + synced = False for response in responses: print('{0} response received: '.format(datetime.datetime.now())) if response.HasField('sync_response'): + synced = True + update_count = update_count+1 print(str(response)) elif response.HasField('error'): print('gNMI Error '+str(response.error.code)+\ @@ -514,7 +517,8 @@ def subscribe_start(stub, options, req_iterator): raise Exception("Filter event regex should not be empty") else: print(response) - update_count = update_count+1 + if synced: + update_count = update_count+1 else: print('Unknown response received:\n'+str(response)) From 2b2997b68792bc5316fa2108e899adb5bbd0705a Mon Sep 17 00:00:00 2001 From: zhihua Date: Sun, 27 Apr 2025 15:25:43 +0800 Subject: [PATCH 2/4] feat: add updates_only argument --- gnmi_cli_py/py_gnmicli.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gnmi_cli_py/py_gnmicli.py b/gnmi_cli_py/py_gnmicli.py index 5eaf596e..270b3f37 100644 --- a/gnmi_cli_py/py_gnmicli.py +++ b/gnmi_cli_py/py_gnmicli.py @@ -165,6 +165,7 @@ def _create_parser(): parser.add_argument('--encoding', default=0, type=int, help='[0=JSON, 1=BYTES, 2=PROTO, 3=ASCII, 4=JSON_IETF]') parser.add_argument('--qos', default=0, type=int, help='') parser.add_argument('--use_alias', action='store_true', help='use alias') + parser.add_argument('--updates_only', action='store_true', help='updates only') parser.add_argument('--create_connections', type=int, nargs='?', const=1, default=1, help='Creates specific number of TCP connections with gNMI server side. ' 'Default number of TCP connections is 1 and use -1 to create ' @@ -467,7 +468,8 @@ def gen_request(paths, opt, prefix): myqos = None mysblist = gnmi_pb2.SubscriptionList(prefix=myprefix, mode=opt['subscribe_mode'], allow_aggregation=opt['aggregate'], encoding=opt['encoding'], - subscription=mysubs, use_aliases=opt['use_alias'], qos=myqos) + subscription=mysubs, use_aliases=opt['use_alias'], qos=myqos, + updates_only=opt['updates_only']) mysubreq = gnmi_pb2.SubscribeRequest(subscribe=mysblist) print('Sending SubscribeRequest\n'+str(mysubreq)) From d41c100de9417a242c6fda5e70d91c987b61f9c8 Mon Sep 17 00:00:00 2001 From: zhihua Date: Sun, 27 Apr 2025 15:26:59 +0800 Subject: [PATCH 3/4] fix: close channel to avoid `Exception in thread Thread-1 (most likely raised during interpreter shutdown)` --- gnmi_cli_py/py_gnmicli.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gnmi_cli_py/py_gnmicli.py b/gnmi_cli_py/py_gnmicli.py index 270b3f37..20390919 100644 --- a/gnmi_cli_py/py_gnmicli.py +++ b/gnmi_cli_py/py_gnmicli.py @@ -285,7 +285,7 @@ def _create_stub(creds, target, port, host_override): channel = gnmi_pb2_grpc.grpc.secure_channel(target + ':' + port, creds) else: channel = gnmi_pb2_grpc.grpc.insecure_channel(target + ':' + port) - return gnmi_pb2_grpc.gNMIStub(channel) + return gnmi_pb2_grpc.gNMIStub(channel), channel def _format_type(json_value): @@ -589,7 +589,7 @@ def main(): break try: - stub = _create_stub(creds, target, port, host_override) + stub, channel = _create_stub(creds, target, port, host_override) if mode == 'get': print('Performing GetRequest, encoding=JSON_IETF', 'to', target, ' with the following gNMI Path\n', '-'*25, '\n', paths) @@ -643,6 +643,8 @@ def main(): else: print("GRPC error\n {}".format(err.details())) sys.exit(1) + finally: + channel.close() if __name__ == '__main__': From d72b48f6bb2aaf60b8ced1261429920b0c960c31 Mon Sep 17 00:00:00 2001 From: zhihua Date: Sun, 27 Apr 2025 19:58:01 +0800 Subject: [PATCH 4/4] fix: poll subscription --- gnmi_cli_py/py_gnmicli.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gnmi_cli_py/py_gnmicli.py b/gnmi_cli_py/py_gnmicli.py index 20390919..9b1062c3 100644 --- a/gnmi_cli_py/py_gnmicli.py +++ b/gnmi_cli_py/py_gnmicli.py @@ -38,6 +38,7 @@ import ssl import sys import string +import time import six import datetime try: @@ -153,6 +154,8 @@ def _create_parser(): required=False, action='store_true') parser.add_argument('--interval', default=10000, type=int, help='sample interval in millisecond (default: 10000ms)') + parser.add_argument('--polling_interval', default=10000, type=int, + help='polling interval in millisecond (default: 10000ms)') parser.add_argument('--timeout', type=int, help='subscription' 'duration in seconds (default: none)') parser.add_argument('--heartbeat', default=0, type=int, help='heartbeat interval (default: None)') @@ -475,6 +478,12 @@ def gen_request(paths, opt, prefix): print('Sending SubscribeRequest\n'+str(mysubreq)) yield mysubreq + if opt["subscribe_mode"] == 2: + while True: + time.sleep(opt['polling_interval']/1000.0) + mysubreq = gnmi_pb2.SubscribeRequest(poll=gnmi_pb2.Poll()) + print('Sending SubscribeRequest\n'+str(mysubreq)) + yield mysubreq def check_event_response(response, filter_event_regex): resp = str(response) @@ -519,7 +528,7 @@ def subscribe_start(stub, options, req_iterator): raise Exception("Filter event regex should not be empty") else: print(response) - if synced: + if options["subscribe_mode"] != 2 and synced: # no polling update_count = update_count+1 else: print('Unknown response received:\n'+str(response))