openconfig / gnmi

gRPC Network Management Interface
Apache License 2.0
473 stars 196 forks source link

Send initial state in POLL subscriptions? #44

Open infn-ke opened 5 years ago

infn-ke commented 5 years ago

When a client makes a POLL subscription to the target, what is the expected behavior from the target as a result of that? From reading the gNMI specification, there is some ambiguity in what happens:

1) Client needs to send the poll message to retrieve the current state ($3.5.1.5.3) 1) If updates_only is set, then only a sync_response is sent ($3.5.2.3). Does that imply that the initial state shall be sent if the flag updates_only is cleared?

Below is a sequence diagram for alternative 1.

1) Client invokes Subscribe, sending the SubscribeRequest to target. 1) Client sends an empty poll message on gRPC stream. 1) Server streams the data to the client 1) Server finishes operation by sending sync_response message

                ┌──────┐                            ┌──────┐          
                │gNMI  │                            │gNMI  │          
                │client│                            │server│          
                └──┬───┘                            └──┬───┘          
                   │        [1] Subscribe, POLL        │              
                   │ ──────────────────────────────────>              
                   │                                   │              
                   │     [2] stream->Write(), poll     │              
                   │ ──────────────────────────────────>              
                   │                                   │              
                   │                                   │              
      ╔═══════╤════╪═══════════════════════════════════╪═════════════╗
      ║ LOOP  │  for each leaf                         │             ║
      ╟───────┘    │                                   │             ║
      ║            │    [3] stream->Write(), update    │             ║
      ║            │ <──────────────────────────────────             ║
      ╚════════════╪═══════════════════════════════════╪═════════════╝
                   │                                   │              
                   │ [4] stream->Write(), sync_response│              
                   │ <──────────────────────────────────              
                ┌──┴───┐                            ┌──┴───┐          
                │gNMI  │                            │gNMI  │          
                │client│                            │server│          
                └──────┘                            └──────┘          
gcsl commented 5 years ago

The diagram matches what the current specification dictates if updates_only is set to true, with the addition that steps 2-4 can be repeated any number of times on the same subscription session. If updates_only is not set, then an additional server loop of sending the updates for each leaf is initiated immediately upon receiving the initial POLL subscription (after [1]) as well as for subsequent POLL requests (after [2]).

Regarding the "alternative 2" statement, there is never a time that sync_response is cleared. It is only a marker sent by the server indicating the client's synchronization at the time the marker is sent in the stream.

The updates_only option allows the polling subscription to be initiated by a client but not receive any data immediately. Although included in the specification for completeness, this field is generally more useful for streaming in which case one could issue a subscription to a set of paths that are expected to rarely change and only be notified of changes (e.g. "Tell me when the admin-status of any interface changes.").

On Wed, Dec 19, 2018 at 8:21 AM infn-ke notifications@github.com wrote:

When a client makes a POLL subscription to the target, what is the expected behavior from the target as a result of that? From reading the gNMI specification, there is some ambiguity in what happens:

  1. Client needs to send the poll message to retrieve the current state ($3.5.1.5.3)
  2. If updates_only is set, then only a sync_response is sent ($3.5.2.3). Does that imply that the initial state shall be sent if the flag sync_response is cleared?

Below is a sequence diagram for alternative 1.

1.

Client invokes Subscribe, sending the SubscribeRequest to target. 2.

Client sends an empty poll message on gRPC stream. 3.

Server streams the data to the client 4.

Server finishes operation by sending sync_response message

            ┌──────┐                            ┌──────┐
            │gNMI  │                            │gNMI  │
            │client│                            │server│
            └──┬───┘                            └──┬───┘
               │        [1] Subscribe, POLL        │
               │ ──────────────────────────────────>
               │                                   │
               │     [2] stream->Write(), poll     │
               │ ──────────────────────────────────>
               │                                   │
               │                                   │
  ╔═══════╤════╪═══════════════════════════════════╪═════════════╗
  ║ LOOP  │  for each leaf                         │             ║
  ╟───────┘    │                                   │             ║
  ║            │    [3] stream->Write(), update    │             ║
  ║            │ <──────────────────────────────────             ║
  ╚════════════╪═══════════════════════════════════╪═════════════╝
               │                                   │
               │ [4] stream->Write(), sync_response│
               │ <──────────────────────────────────
            ┌──┴───┐                            ┌──┴───┐
            │gNMI  │                            │gNMI  │
            │client│                            │server│
            └──────┘                            └──────┘

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/openconfig/gnmi/issues/44, or mute the thread https://github.com/notifications/unsubscribe-auth/ARfIL271FL2fbIzlGpkMQZS3Jqkcps75ks5u6meEgaJpZM4Zaksf .

infn-ke commented 5 years ago

So to conclude the discussion, the correct behavior for POLL is as follows;

1) updates_only=false => sent initial state when receiving the SubscribeRequest 1) updates_only=true => suppress sending initial state when receiving the SubscribeRequest

The two sequence diagrams would then look as follows. Can you confirm that they are according to the standard?

1) POLL, updates_only=false. Steps 4, 5, 6 can be repeated any number of times.

                ┌──────┐                            ┌──────┐          
                │gNMI  │                            │gNMI  │          
                │client│                            │server│          
                └──┬───┘                            └──┬───┘          
                   │       [1] Subscribe(), POLL       │              
                   │ ──────────────────────────────────>              
                   │                                   │              
                   │                                   │              
      ╔═══════╤════╪═══════════════════════════════════╪═════════════╗
      ║ LOOP  │  for each leaf                         │             ║
      ╟───────┘    │                                   │             ║
      ║            │    [2] stream->Write(), update    │             ║
      ║            │ <──────────────────────────────────             ║
      ╚════════════╪═══════════════════════════════════╪═════════════╝
                   │                                   │              
                   │ [3] stream->Write(), sync_response│              
                   │ <──────────────────────────────────              
                   │                                   │              
                   │     [4] stream->Write(), poll     │              
                   │ ──────────────────────────────────>              
                   │                                   │              
                   │                                   │              
      ╔═══════╤════╪═══════════════════════════════════╪═════════════╗
      ║ LOOP  │  for each leaf                         │             ║
      ╟───────┘    │                                   │             ║
      ║            │    [5] stream->Write(), update    │             ║
      ║            │ <──────────────────────────────────             ║
      ╚════════════╪═══════════════════════════════════╪═════════════╝
                   │                                   │              
                   │ [6] stream->Write(), sync_response│              
                   │ <──────────────────────────────────              
                ┌──┴───┐                            ┌──┴───┐          
                │gNMI  │                            │gNMI  │          
                │client│                            │server│          
                └──────┘                            └──────┘          

1) POLL, updates_only=true. Steps 3, 4, 5 can be repeated any number of times.

                ┌──────┐                             ┌──────┐                                                     
                │gNMI  │                             │gNMI  │                                                     
                │client│                             │server│                                                     
                └──┬───┘                             └──┬───┘                                                     
                   │ [1] Subscribe(), POLL, updates_only│                                                         
                   │ ───────────────────────────────────>                                                         
                   │                                    │                                                         
                   │ [2] stream->Write(), sync_response │  ╔═════════════════════════╗                            
                   │ <───────────────────────────────────  ║Only sync_response sent ░║                            
                   │                                    │  ╚═════════════════════════╝                            
                   │      [3] stream->Write(), poll     │                                                         
                   │ ───────────────────────────────────>                                                         
                   │                                    │                                                         
                   │                                    │                                                         
      ╔═══════╤════╪════════════════════════════════════╪═════════════╗  ╔═══════════════════════════════════════╗
      ║ LOOP  │  for each leaf                          │             ║  ║Generate updates for any changed data ░║
      ╟───────┘    │                                    │             ║  ╚═══════════════════════════════════════╝
      ║            │     [4] stream->Write(), update    │             ║                                           
      ║            │ <───────────────────────────────────             ║                                           
      ╚════════════╪════════════════════════════════════╪═════════════╝                                           
                   │                                    │                                                         
                   │ [5] stream->Write(), sync_response │                                                         
                   │ <───────────────────────────────────                                                         
                ┌──┴───┐                             ┌──┴───┐                                                     
                │gNMI  │                             │gNMI  │                                                     
                │client│                             │server│                                                     
                └──────┘                             └──────┘