You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[3.5.2.5 Atomic Containers in Subscribe and Get Requests](#3525-atomic-containers-in-subscribe-and-get-requests)
76
78
-[4 Appendix: Current Protobuf Message and Service Specification](#4-appendix-current-protobuf-message-and-service-specification)
77
79
-[5 Appendix: Current Outstanding Issues/Future Features](#5-appendix-current-outstanding-issuesfuture-features)
78
80
-[6 Copyright](#6-copyright)
@@ -165,10 +167,158 @@ The fields of the Notification message are as follows:
165
167
the receiving entity.
166
168
-`delete` - a list of paths (encoded as per [2.2.2](#222-paths)) that
167
169
indicate the deletion of data nodes on the target.
170
+
-`atomic` - a boolean option that indicates that the notification constitutes
171
+
an atomic update.
168
172
169
173
The creator of a Notification message MUST include the `timestamp` field. All
170
174
other fields are optional.
171
175
176
+
### 2.1.1 Parsing Atomic gNMI Notifications
177
+
178
+
Handling atomic notifications in gNMI is strictly **schema-independent**. The scope of an atomic update is determined entirely by the globally unique `prefix` included in the message (see [relevant gNMI discussion](https://github.com/openconfig/gnmi/issues/111#issuecomment-921072341)).
179
+
180
+
Parsing logic MUST NOT rely on external schema definitions to determine which container is being updated atomically; the parser only needs to evaluate the provided prefix.
181
+
182
+
#### Complete State
183
+
184
+
When a notification is marked `atomic: True`, it indicates that the payload contains the complete and absolute state of all leaves under the specified `prefix`.
185
+
186
+
For example, consider the following notification:
187
+
188
+
```yaml
189
+
Prefix: a/b
190
+
Update: c/d
191
+
Update: c/e
192
+
Update: f/g
193
+
atomic: True
194
+
time: 123
195
+
```
196
+
197
+
This message explicitly declares: *"These are all the existing leaves currently residing under `a/b`."*
198
+
199
+
#### Implicit Deletion of Prior State
200
+
201
+
Because an atomic notification represents the complete state of a prefix at a given timestamp, it **implicitly deletes and invalidates** all previously gathered information under that prefix. Any leaves explicitly omitted from the latest atomic notification are rendered invalid.
202
+
203
+
A simple illustration of implicit deletion: given two sequential atomic notifications for the same prefix —
204
+
205
+
```yaml
206
+
# Notification 1
207
+
Prefix: a/b
208
+
Update: c/d
209
+
Update: c/e
210
+
atomic: True
211
+
time: 1
212
+
```
213
+
214
+
```yaml
215
+
# Notification 2
216
+
Prefix: a/b
217
+
Update: c/e
218
+
atomic: True
219
+
time: 2
220
+
```
221
+
222
+
— the result is that `a/b/c/d` is **deleted**, because it is absent from the notification at `time: 2`.
223
+
224
+
This behavior can delete more than a single leaf.
225
+
For instance, the arrival of the notification at `time: 123` (above) would immediately invalidate the following previously received notifications:
226
+
227
+
**1. Prior Atomic Notifications**
228
+
229
+
```yaml
230
+
Prefix: a/b
231
+
Update: x/y
232
+
Update: x/z
233
+
Update: v/w
234
+
atomic: True
235
+
time: 122 # Disregarded: Overridden by the notification at time 123
236
+
```
237
+
238
+
**2. Prior Non-Atomic Notifications**
239
+
240
+
```yaml
241
+
Prefix: a/b
242
+
Update: some_counter
243
+
time: 121 # Disregarded: Overridden by the atomic notification at time 123
244
+
```
245
+
246
+
#### Invalidating Atomic State with Non-Atomic Updates
247
+
248
+
The "complete state" guarantee of an atomic notification is strictly bound to its specific timestamp. If a client subsequently receives a **non-atomic** notification for a path, which has a prefix that was previously established by an atomic notification, the prior atomic baseline is broken.
249
+
250
+
Because the state has now mutated incrementally, the client can no longer guarantee that it holds the complete and accurate state of the entire prefix tree. Therefore, the previous atomic notification MUST be invalidated.
251
+
252
+
Consider the following sequence:
253
+
254
+
**1. Establishing the Atomic Baseline**
255
+
256
+
```yaml
257
+
Prefix: a/b
258
+
Update: c/d
259
+
Update: c/e
260
+
atomic: True
261
+
time: 123 # Establishes complete state for a/b
262
+
```
263
+
264
+
**2. Subsequent Non-Atomic Update**
265
+
266
+
```yaml
267
+
Prefix: a/b
268
+
Update: f/g
269
+
atomic: False # (or omitted)
270
+
time: 124
271
+
```
272
+
273
+
When the notification at `time: 124` is received, the atomic snapshot established at `time: 123` is invalidated. The parser must treat the tree under `a/b` as an evolving, non-atomic dataset from this point forward, until a new `atomic: True` notification is received for that prefix.
274
+
275
+
In practice, it is not recommended to mix atomic and non-atomic notifications for the same prefix, as it can lead to unexpected behavior, as noted above.
276
+
277
+
This behavior of mixing atomic / non-atomic notifications is unpleasant enough that in OpenConfig, it is explicitly disallowed: if a path is marked atomic in the OpenConfig schema (via `oc-ext:telemetry-atomic`), the server MUST always send atomic updates for that path and MUST NOT send non-atomic updates that would break the atomic baseline.
278
+
279
+
Since gNMI is schema-agnostic, mixing atomic and non-atomic notifications for the same prefix may be acceptable under other schemas, but implementors should be aware of the client-side complexity this creates.
280
+
281
+
#### Delete Notifications and Atomic Flag
282
+
283
+
A `Notification` that contains `delete` entries MAY be marked as atomic, though it has no affect on the handling of deletes, which should proceed as normal.
284
+
If a notification deletes leaves that were previously sent atomically, then the entire atomic container is deleted.
285
+
As such, when the server sends deletes it SHOULD send them with the same prefix as the atomic container to avoid unexpected behavior.
286
+
287
+
#### The Importance of Prefix Scope
288
+
289
+
Because implicit deletion is bound strictly to the declared prefix, the structural choice of the prefix fundamentally changes the parsing behavior.
290
+
291
+
Even if the resulting data leaves are identical, an atomic notification scoped to a parent prefix has a much wider blast radius for invalidation. Consider this notification:
292
+
293
+
```yaml
294
+
Prefix: a
295
+
Update: b/c/d
296
+
Update: b/c/e
297
+
Update: b/f/g
298
+
atomic: True
299
+
time: 123
300
+
```
301
+
302
+
Unlike the previous example (scoped to `a/b`), this notification implicitly invalidates **all** previously received data under the entire `a/` tree, not just the `a/b/` subtree.
303
+
304
+
Additionally, a subsequent atomic notification scoped to a *sub*-prefix also invalidates a previously received atomic notification.
305
+
For example:
306
+
307
+
```yaml
308
+
Prefix: a/b
309
+
Update: c/d
310
+
atomic: True
311
+
time: 124
312
+
```
313
+
314
+
When this notification is received, it invalidates the entire notification previously received at time `123`, following the principle of complete state.
315
+
316
+
#### A Note on `oc-ext:telemetry-atomic`
317
+
318
+
It is important to distinguish between gNMI protocol behavior and YANG schema definitions.
319
+
320
+
The `oc-ext:telemetry-atomic` extension (defined in OpenConfig's [openconfig-extensions.yang](https://github.com/openconfig/public/blob/master/release/models/openconfig-extensions.yang)) governs telemetry *generation*, not parsing. It simply enforces a rule on the publisher: *"Updates containing a path within this schema container must use a prefix that matches this container and be transmitted as an atomic notification."* Once the notification is generated and sent, the standard gNMI atomic parsing rules described above apply.
321
+
172
322
## 2.2 Common Data Types
173
323
174
324
### 2.2.1 Timestamps
@@ -1746,6 +1896,33 @@ The following table clarifies the target behaviors for `Subscribe` for certain s
1746
1896
| Subscribed paths are syntactically correct but one or more paths is not implemented by the server. | Return `UNIMPLEMENTED` | Return `UNIMPLEMENTED` |
1747
1897
| One or more subscribed paths is syntactically incorrect. | Return `INVALID_ARGUMENT` | Return `INVALID_ARGUMENT` |
1748
1898
1899
+
#### 3.5.2.5 Atomic Containers in Subscribe and Get Requests
1900
+
1901
+
An edge case arises when a client subscribes to a specific subset of leaves within a container, but the target device treats that parent container as atomic. (Perhaps it is marked by the `oc-ext:atomic` extension in the schema the server implements.)
1902
+
1903
+
In these cases, the "complete state" principle of the atomic notification is constrained by the scope of the client's subscription. The device SHOULD send an atomic update using the atomic container's prefix, but the payload MUST ONLY contain the specific leaves requested in the subscription.
1904
+
1905
+
Assume a device has an atomic container `a/b` containing three leaves: `c/d`, `c/e`, and `f/g`.
1906
+
1907
+
If the client subscribes strictly to `a/b/c/d`, the device should generate the following notification:
1908
+
1909
+
```yaml
1910
+
Prefix: a/b
1911
+
Update: c/d
1912
+
# c/e and f/g are omitted because they are outside the subscription scope
1913
+
atomic: True
1914
+
time: 126
1915
+
```
1916
+
1917
+
The client must understand that the `atomic: True` flag in this context means *"Here are all the leaves under `a/b`**that you are currently subscribed to**."* The client must not assume that the omitted leaves (`c/e` and `f/g`) have been deleted from the device. From the client's perspective, the atomic cache for `a/b` simply consists only of the subscribed paths.
1918
+
1919
+
This applies also to `Get` requests, where the target device SHOULD return an atomic response for the atomic container's prefix, but when doing so, the payload MUST ONLY contain the specific leaves requested in the subscription.
1920
+
1921
+
Alternatively, if a device does not support partial-leaf subscriptions within an atomic container, it MAY return a gRPC `INVALID_ARGUMENT` error to indicate that subscribing to a subset of an atomic container is not supported.
1922
+
In such cases, Clients are expected to explicitly subscribe to the prefix of the atomic container.
1923
+
1924
+
**Best practice:** Atomic containers should not contain frequently-changing leaves such as counters or high-frequency telemetry values. Because every change to any leaf within an atomic container requires a full atomic re-send of the entire container's state (scoped to the subscription), placing rapidly-updating leaves inside atomic containers can result in significant bandwidth overhead.
1925
+
1749
1926
# 4 Appendix: Current Protobuf Message and Service Specification
1750
1927
1751
1928
The latest Protobuf IDL gNMI specification is found in GitHub at
@@ -1777,6 +1954,10 @@ limitations under the License
1777
1954
1778
1955
# 7 Revision History
1779
1956
1957
+
- v0.11.0: March 5, 2026
1958
+
1959
+
- Define parsing semantics for `atomic` flag in `Notification` message.
1960
+
1780
1961
- v0.10.0: May 25, 2023
1781
1962
1782
1963
- Add `union_replace` operation. Sync revision to gNMI proto revision.
0 commit comments