watch.proto 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Copyright 2017 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. syntax = "proto3";
  15. package google.watcher.v1;
  16. import "google/api/annotations.proto";
  17. import "google/protobuf/any.proto";
  18. import "google/protobuf/empty.proto";
  19. option go_package = "google.golang.org/genproto/googleapis/watcher/v1;watcher";
  20. option java_multiple_files = true;
  21. option java_outer_classname = "WatchProto";
  22. option java_package = "com.google.watcher.v1";
  23. // ## API Overview
  24. //
  25. // [Watcher][] lets a client watch for updates to a named entity, such as a
  26. // directory or database table. For each watched entity, the client receives a
  27. // reliable stream of watch events, without re-ordering.
  28. //
  29. // Watching is done by sending an RPC to a service that implements the API. The
  30. // argument to the RPC contains the name of the entity. The result stream
  31. // consists of a sequence of Change messages that the service continues to
  32. // send until the call fails or is cancelled.
  33. //
  34. // ## Data model
  35. //
  36. // This API assumes that each *entity* has a name and a
  37. // set of *elements*, where each element has a name and a value. The
  38. // entity's name must be a unique identifier within the service, such as
  39. // a resource name. What constitutes an entity or element is
  40. // implementation-specific: for example, a file system implementation
  41. // might define an entity as either a directory or a file, and elements would be
  42. // child files or directories of that entity.
  43. //
  44. // The Watch API allows a client to watch an entity E's immediate
  45. // elements or the whole tree rooted at E. Elements are organized into
  46. // a hierarchy ("" at the top; the rest follows the natural hierarchy of the
  47. // namespace of elements that is being watched). For example, when
  48. // recursively watching a filesystem namespace, X is an ancestor of
  49. // X/Y and X/Y/Z).
  50. //
  51. // ## Watch request
  52. //
  53. // When a client makes a request to watch an entity, it can indicate
  54. // whether it wants to receive the initial state of the entity, just
  55. // new changes to the entity, or resume watching from a particular
  56. // point in a previous watch stream, specified with a `resume_marker` value.
  57. // It can also indicate whether it wants to watch only one entity or all
  58. // entities in the subtree rooted at a particular entity's name.
  59. //
  60. // On receiving a watch request for an entity, the server sends one or more
  61. // messages to the client. The first message informs the client that the server
  62. // has registered the client's request: the instant of time when the
  63. // client receives the event is referred to as the client's "watch
  64. // point" for that entity.
  65. //
  66. // ## Atomic delivery
  67. //
  68. // The response stream consists of a sequence of Change messages. Each
  69. // message contains an `continued` bit. A sub-sequence of Change messages with
  70. // `continued=true` followed by a Change message with `continued=false` forms an
  71. // *atomic group*. Systems that support multi-element atomic updates may
  72. // guarantee that all changes resulting from a single atomic
  73. // update are delivered in the same atomic group. It is up to the
  74. // documentation of a particular system that implements the Watch API to
  75. // document whether or not it supports such grouping. We expect that most
  76. // callers will ignore the notion of atomic delivery and the `continued` bit,
  77. // i.e., they will just process each Change message as it is received.
  78. //
  79. // ## Batching
  80. //
  81. // Multiple Change messages may be grouped into a single ChangeBatch message
  82. // to reduce message transfer overhead. A single ChangeBatch may contain many
  83. // atomic groups, or a single atomic group may be split across many
  84. // ChangeBatch messages.
  85. //
  86. // ## Initial State
  87. //
  88. // The first atomic group delivered by a watch call is special. It is
  89. // delivered as soon as possible and contains the initial state of the
  90. // entity being watched. The client should consider itself caught up
  91. // after processing this first atomic group.
  92. //
  93. // The messages in the first atomic group will either refer to the
  94. // entity itself (`Change.element` == "") or to elements inside the
  95. // entity (`Change.element` != ""). Here are the cases to consider:
  96. //
  97. // 1. `resume_marker` is "" or not specified: For every element P
  98. // (including the entity itself) that exists, there will be at least
  99. // one message delivered with element == P and the last such message
  100. // will contain the current state of P. For every element Q
  101. // (including the entity itself) that does not exist, either no
  102. // message will be delivered, or the last message for Q will have
  103. // state == DOES_NOT_EXIST. At least one message for element="" will
  104. // be delivered.
  105. //
  106. // 2. `resume_marker` == "now": there will be exactly one message with
  107. // element = "" and state INITIAL_STATE_SKIPPED. The client cannot
  108. // assume whether or not the entity exists after receiving this
  109. // message.
  110. //
  111. // 3. `resume_marker` has a value R from a preceding watch call on this
  112. // entity: The same messages as described in (1) will be delivered to
  113. // the client, except that any information implied by messages received
  114. // on the preceding call up to and including R may not be
  115. // delivered. The expectation is that the client will start with state
  116. // it had built up from the preceding watch call, apply the changes
  117. // received from this call, and build an up-to-date view of the entity
  118. // without having to fetch a potentially large amount of information
  119. // that has not changed. Note that some information that had already
  120. // been delivered by the preceding call might be delivered again.
  121. //
  122. // ## Ordering and Reliability
  123. //
  124. // The Change messages that apply to a particular element of the entity are
  125. // delivered eventually in order without loss for the duration of the RPC. Note
  126. // however that if multiple Changes apply to the same element, the
  127. // implementation is free to suppress them and deliver just the last one. The
  128. // underlying system must provide the guarantee that any relevant update
  129. // received for an entity E after a client's watch point for E MUST be delivered
  130. // to that client.
  131. //
  132. // These tight guarantees allow for the following simplifications in the client:
  133. //
  134. // 1. The client does not need to have a separate polling loop to make up for
  135. // missed updates.
  136. //
  137. // 2. The client does not need to manage timestamps/versions manually; the
  138. // last update delivered corresponds to the eventual state of the entity.
  139. //
  140. // Example: a calendar entry may have elements named { "starttime", "endtime",
  141. // "attendees" } with corresponding values or it may have a single element name
  142. // "entry" with a serialized proto for the calendar entry.
  143. //
  144. // ## Ordering constraints for parents/descendants
  145. //
  146. // The Watch API provides guarantees regarding the order in which
  147. // messages for a parent and its descendants are delivered:
  148. //
  149. // 1. The creation of an ancestor (i.e., the first EXISTS message for
  150. // the ancestor) is reported before the creation of any of its
  151. // descendants.
  152. //
  153. // 2. The deletion of an ancestor (via a DOES_NOT_EXIST message)
  154. // implies the deletion of all its descendants. The service will
  155. // not deliver any messages for the descendants until the parent
  156. // has been recreated.
  157. // The service that a client uses to connect to the watcher system.
  158. // The errors returned by the service are in the canonical error space,
  159. // see [google.rpc.Code][].
  160. service Watcher {
  161. // Start a streaming RPC to get watch information from the server.
  162. rpc Watch(Request) returns (stream ChangeBatch) {
  163. option (google.api.http) = {
  164. get: "/v1/watch"
  165. };
  166. }
  167. }
  168. // The message used by the client to register interest in an entity.
  169. message Request {
  170. // The `target` value **must** be a valid URL path pointing to an entity
  171. // to watch. Note that the service name **must** be
  172. // removed from the target field (e.g., the target field must say
  173. // "/foo/bar", not "myservice.googleapis.com/foo/bar"). A client is
  174. // also allowed to pass system-specific parameters in the URL that
  175. // are only obeyed by some implementations. Some parameters will be
  176. // implementation-specific. However, some have predefined meaning
  177. // and are listed here:
  178. //
  179. // * recursive = true|false [default=false]
  180. // If set to true, indicates that the client wants to watch all elements
  181. // of entities in the subtree rooted at the entity's name in `target`. For
  182. // descendants that are not the immediate children of the target, the
  183. // `Change.element` will contain slashes.
  184. //
  185. // Note that some namespaces and entities will not support recursive
  186. // watching. When watching such an entity, a client must not set recursive
  187. // to true. Otherwise, it will receive an `UNIMPLEMENTED` error.
  188. //
  189. // Normal URL encoding must be used inside `target`. For example, if a query
  190. // parameter name or value, or the non-query parameter portion of `target`
  191. // contains a special character, it must be %-encoded. We recommend that
  192. // clients and servers use their runtime's URL library to produce and consume
  193. // target values.
  194. string target = 1;
  195. // The `resume_marker` specifies how much of the existing underlying state is
  196. // delivered to the client when the watch request is received by the
  197. // system. The client can set this marker in one of the following ways to get
  198. // different semantics:
  199. //
  200. // * Parameter is not specified or has the value "".
  201. // Semantics: Fetch initial state.
  202. // The client wants the entity's initial state to be delivered. See the
  203. // description in "Initial State".
  204. //
  205. // * Parameter is set to the string "now" (UTF-8 encoding).
  206. // Semantics: Fetch new changes only.
  207. // The client just wants to get the changes received by the system after
  208. // the watch point. The system may deliver changes from before the watch
  209. // point as well.
  210. //
  211. // * Parameter is set to a value received in an earlier
  212. // `Change.resume_marker` field while watching the same entity.
  213. // Semantics: Resume from a specific point.
  214. // The client wants to receive the changes from a specific point; this
  215. // value must correspond to a value received in the `Change.resume_marker`
  216. // field. The system may deliver changes from before the `resume_marker`
  217. // as well. If the system cannot resume the stream from this point (e.g.,
  218. // if it is too far behind in the stream), it can raise the
  219. // `FAILED_PRECONDITION` error.
  220. //
  221. // An implementation MUST support an unspecified parameter and the
  222. // empty string "" marker (initial state fetching) and the "now" marker.
  223. // It need not support resuming from a specific point.
  224. bytes resume_marker = 2;
  225. }
  226. // A batch of Change messages.
  227. message ChangeBatch {
  228. // A list of Change messages.
  229. repeated Change changes = 1;
  230. }
  231. // A Change indicates the most recent state of an element.
  232. message Change {
  233. // A reported value can be in one of the following states:
  234. enum State {
  235. // The element exists and its full value is included in data.
  236. EXISTS = 0;
  237. // The element does not exist.
  238. DOES_NOT_EXIST = 1;
  239. // Element may or may not exist. Used only for initial state delivery when
  240. // the client is not interested in fetching the initial state. See the
  241. // "Initial State" section above.
  242. INITIAL_STATE_SKIPPED = 2;
  243. // The element may exist, but some error has occurred. More information is
  244. // available in the data field - the value is a serialized Status
  245. // proto (from [google.rpc.Status][])
  246. ERROR = 3;
  247. }
  248. // Name of the element, interpreted relative to the entity's actual
  249. // name. "" refers to the entity itself. The element name is a valid
  250. // UTF-8 string.
  251. string element = 1;
  252. // The state of the `element`.
  253. State state = 2;
  254. // The actual change data. This field is present only when `state() == EXISTS`
  255. // or `state() == ERROR`. Please see
  256. // [google.protobuf.Any][google.protobuf.Any] about how to use the Any type.
  257. google.protobuf.Any data = 6;
  258. // If present, provides a compact representation of all the messages that have
  259. // been received by the caller for the given entity, e.g., it could be a
  260. // sequence number or a multi-part timestamp/version vector. This marker can
  261. // be provided in the Request message, allowing the caller to resume the
  262. // stream watching at a specific point without fetching the initial state.
  263. bytes resume_marker = 4;
  264. // If true, this Change is followed by more Changes that are in the same group
  265. // as this Change.
  266. bool continued = 5;
  267. }