Skip to content

Implement OnceRun for MixedDbClient and DbClient Subscribe ONCE#685

Open
ashwnsri wants to merge 3 commits into
sonic-net:masterfrom
ashwnsri:gnmi-subscribe-oncemode
Open

Implement OnceRun for MixedDbClient and DbClient Subscribe ONCE#685
ashwnsri wants to merge 3 commits into
sonic-net:masterfrom
ashwnsri:gnmi-subscribe-oncemode

Conversation

@ashwnsri
Copy link
Copy Markdown

@ashwnsri ashwnsri commented May 28, 2026

Why I did it

Subscribe ONCE mode (gnmi_cli -query_type=once) was broken because OnceRun() in both MixedDbClient and DbClient were no-op stubs that returned immediately without sending any data to the client.

Implement OnceRun to perform a single-shot data fetch from Redis, enqueue the results to the priority queue, and send a sync_response to signal completion. This follows the same pattern as PollRun but executes only one iteration.

How I did it

Changes:

  • sonic_data_client/mixed_db_client.go: Implement MixedDbClient.OnceRun()
  • sonic_data_client/db_client.go: Implement DbClient.OnceRun()
  • test/utils.py: Add gnmi_subscribe_once() and gnmi_subscribe_once_multiple()
  • test/test_gnmi_configdb.py: Add TestGNMISubscribeOnce with 7 test cases

Without this fix, any gNMI client using Subscribe ONCE hangs until timeout (rc=124) because the server never sends data or sync_response.

How to verify it

Inside gnmi container with TLS + client auth configured:

gnmi_cli -client_types=gnmi -a :8080
-client_crt /etc/sonic/telemetry/gnmiclient.crt
-client_key /etc/sonic/telemetry/gnmiclient.key
-ca_crt /etc/sonic/telemetry/gnmiCA.pem
-logtostderr -origin=sonic-db -query_type=once
-q /CONFIG_DB/localhost/DEVICE_METADATA/localhost

Expected Behavior

OnceRun should perform a single-shot data fetch (equivalent to one iteration of PollRun) and then send a sync_response to indicate completion. The client should receive the requested data and disconnect cleanly.

Console Logs from DUT

Logs without this change

root@sonic-device:/# ps -ef | grep telemetry
root     2480367 2480365  2 21:24 pts/1    00:00:00 /usr/sbin/telemetry -logtostderr --port 8080 --server_crt /etc/sonic/telemetry/gnmiserver.crt --server_key /etc/sonic/telemetry/gnmiserver.key --config_table_name GNMI_CLIENT_CERT --client_auth cert --enable_crl=true --ca_crt /etc/sonic/telemetry/gnmiCA.pem -gnmi_native_write=true -v=10
root     2480728 2461158  0 21:24 pts/1    00:00:00 grep telemetry
root@sonic-device:/# 

root@sonic-device:/# gnmi_cli -client_types=gnmi -a 192.168.0.1:8080 -client_crt /etc/sonic/telemetry/gnmiclient.crt -client_key /etc/sonic/telemetry/gnmiclient.key -ca_crt /etc/sonic/telemetry/gnmiCA.pem -logtostderr -origin=sonic-db -query_type=once -q /CONFIG_DB/localhost/DEVICE_METADATA/localhost 
I0527 21:25:24.127501 2480367 client_subscribe.go:123] Client 192.168.0.1:40438 recieved initial query subscribe:{prefix:{origin:"sonic-db"} subscription:{path:{element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}}} mode:ONCE}
I0527 21:25:24.127709 2480367 client_subscribe.go:78] prefix : &gnmi.Path{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc00028c3d8)}, sizeCache:0, unknownFields:[]uint8(nil), Element:[]string(nil), Origin:"sonic-db", Elem:[]*gnmi.PathElem(nil), Target:""} SubscribRequest : &gnmi.SubscriptionList{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc00028cf60)}, sizeCache:0, unknownFields:[]uint8(nil), Prefix:(*gnmi.Path)(0xc00097ac00), Subscription:[]*gnmi.Subscription{(*gnmi.Subscription)(0xc000af9770)}, UseAliases:false, Qos:(*gnmi.QOSMarking)(nil), Mode:1, AllowAggregation:false, UseModels:[]*gnmi.ModelData(nil), Encoding:0, UpdatesOnly:false}
I0527 21:25:24.127812 2480367 client_subscribe.go:90] gnmi Paths : [element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}]
I0527 21:25:24.128119 2480367 connection_manager.go:68] Adding client connection: 192.168.0.1:40438|CONFIG_DB|localhost|DEVICE_METADATA|localhost|2026-05-27T21:25:24Z
I0527 21:25:24.129411 2480367 client_subscribe.go:159] mode=ONCE, origin="sonic-db", target=""
I0527 21:25:24.130268 2480367 clientCertAuth.go:185] Get Crl Urls for cert: []
I0527 21:25:24.130290 2480367 clientCertAuth.go:226] Cert does not contains and CRL distribution points
I0527 21:25:24.130315 2480367 server.go:558] authenticate user , roles [gnmi_readwrite]
I0527 21:25:24.130409 2480367 client_subscribe.go:225] Client 192.168.0.1:40438 running
I0527 21:25:24.130720 2480367 client_subscribe.go:262] Client 192.168.0.1:40438 blocking on stream.Recv()
.
.
.
^CI0527 21:26:48.085918 2480367 client_subscribe.go:268] Client 192.168.0.1:40438 received error: rpc error: code = Canceled desc = context canceled
I0527 21:26:48.086113 2480367 client_subscribe.go:240] Client 192.168.0.1:40438 Close, sendMsg 0 recvMsg 2 errors 0
I0527 21:26:48.086180 2480367 client_subscribe.go:304] queue: disposed
I0527 21:26:48.086202 2480367 client_subscribe.go:240] Client 192.168.0.1:40438 Close, sendMsg 0 recvMsg 2 errors 0
E0527 21:26:48.086338 2482257 gnmi_cli.go:250] sendQueryAndDisplay(ctx, {Addrs:[192.168.0.1:8080] AddressChains:[] Origin:sonic-db Target: Replica:0 UpdatesOnly:false Queries:[[CONFIG_DB localhost DEVICE_METADATA localhost]] Type:once Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:<nil> TLS:0xe3b500 Extra:map[] SubReq:<nil> Streaming_type:TARGET_DEFINED Streaming_sample_int:0 Heartbeat_int:0 Suppress_redundant:false}, &{PollingInterval:30s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x8c3500 DisplayPrefix: DisplayIndent:   DisplayType:group DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[gnmi]}):
	client had error while displaying results:
	rpc error: code = Canceled desc = context canceled

]

root@sonic-device:/# timeout 30 gnmi_cli -client_types=gnmi -a 192.168.0.1:8080 -client_crt /etc/sonic/telemetry/gnmiclient.crt -client_key /etc/sonic/telemetry/gnmiclient.key -ca_crt /etc/sonic/telemetry/gnmiCA.pem -logtostderr -origin=sonic-db -query_type=once -q /CONFIG_DB/localhost/DEVICE_METADATA/localhost 
I0527 21:27:03.900657 2480367 client_subscribe.go:123] Client 192.168.0.1:45784 recieved initial query subscribe:{prefix:{origin:"sonic-db"} subscription:{path:{element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}}} mode:ONCE}
I0527 21:27:03.900839 2480367 client_subscribe.go:78] prefix : &gnmi.Path{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc00028c3d8)}, sizeCache:0, unknownFields:[]uint8(nil), Element:[]string(nil), Origin:"sonic-db", Elem:[]*gnmi.PathElem(nil), Target:""} SubscribRequest : &gnmi.SubscriptionList{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc00028cf60)}, sizeCache:0, unknownFields:[]uint8(nil), Prefix:(*gnmi.Path)(0xc00097b600), Subscription:[]*gnmi.Subscription{(*gnmi.Subscription)(0xc000704410)}, UseAliases:false, Qos:(*gnmi.QOSMarking)(nil), Mode:1, AllowAggregation:false, UseModels:[]*gnmi.ModelData(nil), Encoding:0, UpdatesOnly:false}
I0527 21:27:03.900900 2480367 client_subscribe.go:90] gnmi Paths : [element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}]
I0527 21:27:03.901055 2480367 connection_manager.go:68] Adding client connection: 192.168.0.1:45784|CONFIG_DB|localhost|DEVICE_METADATA|localhost|2026-05-27T21:27:03Z
I0527 21:27:03.901521 2480367 client_subscribe.go:159] mode=ONCE, origin="sonic-db", target=""
I0527 21:27:03.902184 2480367 clientCertAuth.go:185] Get Crl Urls for cert: []
I0527 21:27:03.902201 2480367 clientCertAuth.go:226] Cert does not contains and CRL distribution points
I0527 21:27:03.902215 2480367 server.go:558] authenticate user , roles [gnmi_readwrite]
I0527 21:27:03.902238 2480367 client_subscribe.go:225] Client 192.168.0.1:45784 running
I0527 21:27:03.902270 2480367 client_subscribe.go:262] Client 192.168.0.1:45784 blocking on stream.Recv()

I0527 21:27:33.836250 2480367 client_subscribe.go:268] Client 192.168.0.1:45784 received error: rpc error: code = Canceled desc = context canceled
I0527 21:27:33.836320 2480367 client_subscribe.go:240] Client 192.168.0.1:45784 Close, sendMsg 0 recvMsg 2 errors 0
I0527 21:27:33.836364 2480367 client_subscribe.go:304] queue: disposed
I0527 21:27:33.836383 2480367 client_subscribe.go:240] Client 192.168.0.1:45784 Close, sendMsg 0 recvMsg 2 errors 0
root@sonic-device:/# 

Logs with this change

root@sonic-device:/# ps -ef | grep telemetry
root     3155126 3151894  1 04:39 pts/2    00:00:00 /usr/sbin/telemetry -logtostderr --port 8080 --server_crt /etc/sonic/telemetry/gnmiserver.crt --server_key /etc/sonic/telemetry/gnmiserver.key --config_table_name GNMI_CLIENT_CERT --client_auth cert --enable_crl=true --ca_crt /etc/sonic/telemetry/gnmiCA.pem -gnmi_native_write=true -v=10
root     3156546 3151894  0 04:40 pts/2    00:00:00 grep telemetry
root@sonic-device:/# 
root@sonic-device:/# 
root@sonic-device:/# 
root@sonic-device:/# gnmi_cli -client_types=gnmi -a 192.168.0.1:8080 \
  -client_crt /etc/sonic/telemetry/gnmiclient.crt \
  -client_key /etc/sonic/telemetry/gnmiclient.key \
  -ca_crt /etc/sonic/telemetry/gnmiCA.pem \
  -logtostderr -origin=sonic-db -query_type=once \
  -q /CONFIG_DB/localhost/DEVICE_METADATA/localhost
I0528 04:41:54.214562 3155126 server.go:871] New Subscribe RPC: client 192.168.0.1:38636#1 (peer: 192.168.0.1:38636, total active: 0)
I0528 04:41:54.214635 3155126 server.go:878] Client 192.168.0.1:38636#1 registered (total active: 1)
I0528 04:41:54.215424 3155126 client_subscribe.go:153] Client 192.168.0.1:38636#1 recieved initial query subscribe:{prefix:{origin:"sonic-db"} subscription:{path:{element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}}} mode:ONCE}
I0528 04:41:54.215576 3155126 client_subscribe.go:108] prefix : &gnmi.Path{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc000068de0)}, sizeCache:0, unknownFields:[]uint8(nil), Element:[]string(nil), Origin:"sonic-db", Elem:[]*gnmi.PathElem(nil), Target:""} SubscribRequest : &gnmi.SubscriptionList{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(0xc000069968)}, sizeCache:0, unknownFields:[]uint8(nil), Prefix:(*gnmi.Path)(0xc000b25b00), Subscription:[]*gnmi.Subscription{(*gnmi.Subscription)(0xc001671400)}, UseAliases:false, Qos:(*gnmi.QOSMarking)(nil), Mode:1, AllowAggregation:false, UseModels:[]*gnmi.ModelData(nil), Encoding:0, UpdatesOnly:false}
I0528 04:41:54.215670 3155126 client_subscribe.go:120] gnmi Paths : [element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}]
I0528 04:41:54.215943 3155126 connection_manager.go:72] Adding client connection: 192.168.0.1:38636|CONFIG_DB|localhost|DEVICE_METADATA|localhost|2026-05-28T04:41:54Z
I0528 04:41:54.216349 3155126 client_subscribe.go:189] mode=ONCE, origin="sonic-db", target=""
I0528 04:41:54.217503 3155126 clientCertAuth.go:185] Get Crl Urls for cert: []
I0528 04:41:54.217544 3155126 clientCertAuth.go:226] Cert does not contains and CRL distribution points
I0528 04:41:54.217579 3155126 server.go:837] authenticate user , roles [gnmi_readwrite]
I0528 04:41:54.217648 3155126 client_subscribe.go:251] Client 192.168.0.1:38636#1 running
I0528 04:41:54.217694 3155126 client_subscribe.go:288] Client 192.168.0.1:38636#1 blocking on stream.Recv()
I0528 04:41:54.217820 3155126 mixed_db_client.go:671] index 0 elem : "DEVICE_METADATA" map[string]string(nil)
I0528 04:41:54.217860 3155126 mixed_db_client.go:671] index 1 elem : "localhost" map[string]string(nil)
I0528 04:41:54.218774 3155126 mixed_db_client.go:935] Added idex 0 fv map[bgp_asn:65100 buffer_model:traditional cloudtype:Public default_bgp_status:up default_pfcwd_status:disable deployment_id:1 docker_routing_config_mode:separated hostname:sonic-device hwsku:Juniper-QFX5241-64-QD mac:40:36:b7:a6:13:87 platform:x86_64-juniper_qfx5241-r0 region:None synchronous_mode:enable timezone:UTC type:ToRRouter yang_config_validation:disable] 
I0528 04:41:54.219151 3155126 mixed_db_client.go:1710] OnceRun: Added spbv #prefix:{origin:"sonic-db"} path:{element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}} timestamp:1779943314218899972 val:{json_ietf_val:"{\"bgp_asn\":\"65100\",\"buffer_model\":\"traditional\",\"cloudtype\":\"Public\",\"default_bgp_status\":\"up\",\"default_pfcwd_status\":\"disable\",\"deployment_id\":\"1\",\"docker_routing_config_mode\":\"separated\",\"hostname\":\"sonic-device\",\"hwsku\":\"Juniper-QFX5241-64-QD\",\"mac\":\"40:36:b7:a6:13:87\",\"platform\":\"x86_64-juniper_qfx5241-r0\",\"region\":\"None\",\"synchronous_mode\":\"enable\",\"timezone\":\"UTC\",\"type\":\"ToRRouter\",\"yang_config_validation\":\"disable\"}"}
I0528 04:41:54.219529 3155126 mixed_db_client.go:1720] OnceRun: Sync done, total time taken: 1 ms
I0528 04:41:54.219421 3155126 client_subscribe.go:363] Client 192.168.0.1:38636#1 done sending, msg count 1, msg update:{timestamp:1779943314218899972 prefix:{origin:"sonic-db"} update:{path:{element:"CONFIG_DB" element:"localhost" element:"DEVICE_METADATA" element:"localhost" elem:{name:"CONFIG_DB"} elem:{name:"localhost"} elem:{name:"DEVICE_METADATA"} elem:{name:"localhost"}} val:{json_ietf_val:"{\"bgp_asn\":\"65100\",\"buffer_model\":\"traditional\",\"cloudtype\":\"Public\",\"default_bgp_status\":\"up\",\"default_pfcwd_status\":\"disable\",\"deployment_id\":\"1\",\"docker_routing_config_mode\":\"separated\",\"hostname\":\"sonic-device\",\"hwsku\":\"Juniper-QFX5241-64-QD\",\"mac\":\"40:36:b7:a6:13:87\",\"platform\":\"x86_64-juniper_qfx5241-r0\",\"region\":\"None\",\"synchronous_mode\":\"enable\",\"timezone\":\"UTC\",\"type\":\"ToRRouter\",\"yang_config_validation\":\"disable\"}"}}}
I0528 04:41:54.219675 3155126 client_subscribe.go:363] Client 192.168.0.1:38636#1 done sending, msg count 2, msg sync_response:true
[
{
  "sonic-db": {
    "CONFIG_DB": {
      "localhost": {
        "DEVICE_METADATA": {
          "localhost": {
            "bgp_asn": "65100",
            "buffer_model": "traditional",
            "cloudtype": "Public",
            "default_bgp_status": "up",
            "default_pfcwd_status": "disable",
            "deployment_id": "1",
            "docker_routing_config_mode": "separated",
            "hostname": "sonic-device",
            "hwsku": "Juniper-QFX5241-64-QD",
            "mac": "40:36:b7:a6:13:87",
            "platform": "x86_64-juniper_qfx5241-r0",
            "region": "None",
            "synchronous_mode": "enable",
            "timezone": "UTC",
            "type": "ToRRouter",
            "yang_config_validation": "disable"
          }
        }
      }
    }
  }
}
]
I0528 04:41:54.222398 3155126 client_subscribe.go:294] Client 192.168.0.1:38636#1 received error: rpc error: code = Canceled desc = context canceled
I0528 04:41:54.222458 3155126 client_subscribe.go:266] Client 192.168.0.1:38636#1 Close, sendMsg 2 recvMsg 2 errors 0
root@sonic-device:/#

Description for the changelog

Implement OnceRun for MixedDbClient and DbClient Subscribe ONCE

Fixes #688

@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@ashwnsri ashwnsri enabled auto-merge (squash) May 28, 2026 08:26
@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@ashwnsri ashwnsri added the bug Something isn't working label May 28, 2026
@ashwnsri ashwnsri requested a review from zbud-msft May 28, 2026 10:02
@ashwnsri ashwnsri force-pushed the gnmi-subscribe-oncemode branch from 60005a6 to e2d3f33 Compare May 28, 2026 21:00
@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@ashwnsri ashwnsri removed the request for review from ganglyu May 28, 2026 21:44
@ashwnsri
Copy link
Copy Markdown
Author

ashwnsri commented Jun 1, 2026

@hdwhdw @zbud-msft please help review, thanks!

@hdwhdw
Copy link
Copy Markdown
Contributor

hdwhdw commented Jun 1, 2026

@zbud-msft can you take a look?

ashwnsri added 2 commits June 1, 2026 12:27
Subscribe ONCE mode (gnmi_cli -query_type=once) was broken because
OnceRun() in both MixedDbClient and DbClient were no-op stubs that
returned immediately without sending any data to the client.

Implement OnceRun to perform a single-shot data fetch from Redis,
enqueue the results to the priority queue, and send a sync_response
to signal completion. This follows the same pattern as PollRun but
executes only one iteration.

Changes:
- sonic_data_client/mixed_db_client.go: Implement MixedDbClient.OnceRun()
- sonic_data_client/db_client.go: Implement DbClient.OnceRun()
- test/utils.py: Add gnmi_subscribe_once() and gnmi_subscribe_once_multiple()
- test/test_gnmi_configdb.py: Add TestGNMISubscribeOnce with 7 test cases

Without this fix, any gNMI client using Subscribe ONCE hangs until
timeout (rc=124) because the server never sends data or sync_response.

Signed-off-by: Ashwin Srinivasan <asrinivasan@juniper.net>
The CI test environment's mock DB only has bgp_asn and cloudtype in DEVICE_METADATA|localhost, not hostname.

test_gnmi_once_multiple_paths: Changed the second path from /CONFIG_DB/localhost/PORT to /CONFIG_DB/localhost/DEVICE_METADATA.
The PORT table doesn't exist in the CI test environment.

Signed-off-by: Ashwin Srinivasan <asrinivasan@juniper.net>
@ashwnsri ashwnsri force-pushed the gnmi-subscribe-oncemode branch from e2d3f33 to 9c0d0c0 Compare June 1, 2026 21:27
@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Tests added:
- TestDbClientOnceRun: Success path, channel closed early exit
  and no-data path

- TestMixedDbClientOnceRun: Success path, channel closed early exit,
  getDbtablePath error (putFatalMsg), and tableData2TypedValue error

Signed-off-by: Ashwin Srinivasan <asrinivasan@juniper.net>
@ashwnsri ashwnsri force-pushed the gnmi-subscribe-oncemode branch from 9c0d0c0 to 6d01585 Compare June 1, 2026 21:31
@mssonicbld
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@ashwnsri
Copy link
Copy Markdown
Author

ashwnsri commented Jun 3, 2026

@zbud-msft please take a look when you can, thanks!

@ashwnsri
Copy link
Copy Markdown
Author

ashwnsri commented Jun 5, 2026

@hdwhdw could you please help review, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Subscribe ONCE mode never returns data as OnceRun() function is currently a no-op

3 participants