blob: 0b3bd5d012a4bffe50f30d4a2e41f4b0d751ba56 [file] [log] [blame]
Chen Wang86af8cf2015-01-21 18:05:40 -08001// Specification of the Pubsub API.
2
3syntax = "proto2";
4
5import "examples/tips/empty.proto";
6import "examples/tips/label.proto";
7
8package tech.pubsub;
9
10// -----------------------------------------------------------------------------
11// Overview of the Pubsub API
12// -----------------------------------------------------------------------------
13
14// This file describes an API for a Pubsub system. This system provides a
15// reliable many-to-many communication mechanism between independently written
16// publishers and subscribers where the publisher publishes messages to "topics"
17// and each subscriber creates a "subscription" and consumes messages from it.
18//
19// (a) The pubsub system maintains bindings between topics and subscriptions.
20// (b) A publisher publishes messages into a topic.
21// (c) The pubsub system delivers messages from topics into relevant
22// subscriptions.
23// (d) A subscriber receives pending messages from its subscription and
24// acknowledges or nacks each one to the pubsub system.
25// (e) The pubsub system removes acknowledged messages from that subscription.
26
27// -----------------------------------------------------------------------------
28// Data Model
29// -----------------------------------------------------------------------------
30
31// The data model consists of the following:
32//
33// * Topic: A topic is a resource to which messages are published by publishers.
34// Topics are named, and the name of the topic is unique within the pubsub
35// system.
36//
37// * Subscription: A subscription records the subscriber's interest in a topic.
38// It can optionally include a query to select a subset of interesting
39// messages. The pubsub system maintains a logical cursor tracking the
40// matching messages which still need to be delivered and acked so that
41// they can retried as needed. The set of messages that have not been
42// acknowledged is called the subscription backlog.
43//
44// * Message: A message is a unit of data that flows in the system. It contains
45// opaque data from the publisher along with its labels.
46//
47// * Message Labels (optional): A set of opaque key, value pairs assigned
48// by the publisher which the subscriber can use for filtering out messages
49// in the topic. For example, a label with key "foo.com/device_type" and
50// value "mobile" may be added for messages that are only relevant for a
51// mobile subscriber; a subscriber on a phone may decide to create a
52// subscription only for messages that have this label.
53
54// -----------------------------------------------------------------------------
55// Publisher Flow
56// -----------------------------------------------------------------------------
57
58// A publisher publishes messages to the topic using the Publish request:
59//
60// PubsubMessage message;
61// message.set_data("....");
62// Label label;
63// label.set_key("foo.com/key1");
64// label.set_str_value("value1");
65// message.add_label(label);
66// PublishRequest request;
67// request.set_topic("topicName");
68// request.set_message(message);
69// PublisherService.Publish(request);
70
71// -----------------------------------------------------------------------------
72// Subscriber Flow
73// -----------------------------------------------------------------------------
74
75// The subscriber part of the API is richer than the publisher part and has a
76// number of concepts w.r.t. subscription creation and monitoring:
77//
78// (1) A subscriber creates a subscription using the CreateSubscription call.
79// It may specify an optional "query" to indicate that it wants to receive
80// only messages with a certain set of labels using the label query syntax.
81// It may also specify an optional truncation policy to indicate when old
82// messages from the subcription can be removed.
83//
84// (2) A subscriber receives messages in one of two ways: via push or pull.
85//
86// (a) To receive messages via push, the PushConfig field must be specified in
87// the Subscription parameter when creating a subscription. The PushConfig
88// specifies an endpoint at which the subscriber must expose the
89// PushEndpointService. Messages are received via the HandlePubsubEvent
90// method. The push subscriber responds to the HandlePubsubEvent method
91// with a result code that indicates one of three things: Ack (the message
92// has been successfully processed and the Pubsub system may delete it),
93// Nack (the message has been rejected, the Pubsub system should resend it
94// at a later time), or Push-Back (this is a Nack with the additional
95// semantics that the subscriber is overloaded and the pubsub system should
96// back off on the rate at which it is invoking HandlePubsubEvent). The
97// endpoint may be a load balancer for better scalability.
98//
99// (b) To receive messages via pull a subscriber calls the Pull method on the
100// SubscriberService to get messages from the subscription. For each
101// individual message, the subscriber may use the ack_id received in the
102// PullResponse to Ack the message, Nack the message, or modify the ack
103// deadline with ModifyAckDeadline. See the
104// Subscription.ack_deadline_seconds field documentation for details on the
105// ack deadline behavior.
106//
107// Note: Messages may be consumed in parallel by multiple subscribers making
108// Pull calls to the same subscription; this will result in the set of
109// messages from the subscription being shared and each subscriber
110// receiving a subset of the messages.
111//
112// (4) The subscriber can explicitly truncate the current subscription.
113//
114// (5) "Truncated" events are delivered when a subscription is
115// truncated, whether due to the subscription's truncation policy
116// or an explicit request from the subscriber.
117//
118// Subscription creation:
119//
120// Subscription subscription;
121// subscription.set_topic("topicName");
122// subscription.set_name("subscriptionName");
123// subscription.push_config().set_push_endpoint("machinename:8888");
124// SubscriberService.CreateSubscription(subscription);
125//
126// Consuming messages via push:
127//
128// TODO(eschapira): Add HTTP push example.
129//
130// The port 'machinename:8888' must be bound to a stubby server that implements
131// the PushEndpointService with the following method:
132//
133// int HandlePubsubEvent(PubsubEvent event) {
134// if (event.subscription().equals("subscriptionName")) {
135// if (event.has_message()) {
136// Process(event.message().data());
137// } else if (event.truncated()) {
138// ProcessTruncatedEvent();
139// }
140// }
141// return OK; // This return code implies an acknowledgment
142// }
143//
144// Consuming messages via pull:
145//
146// The subscription must be created without setting the push_config field.
147//
148// PullRequest pull_request;
149// pull_request.set_subscription("subscriptionName");
150// pull_request.set_return_immediately(false);
151// while (true) {
152// PullResponse pull_response;
153// if (SubscriberService.Pull(pull_request, pull_response) == OK) {
154// PubsubEvent event = pull_response.pubsub_event();
155// if (event.has_message()) {
156// Process(event.message().data());
157// } else if (event.truncated()) {
158// ProcessTruncatedEvent();
159// }
160// AcknowledgeRequest ack_request;
161// ackRequest.set_subscription("subscriptionName");
162// ackRequest.set_ack_id(pull_response.ack_id());
163// SubscriberService.Acknowledge(ack_request);
164// }
165// }
166
167// -----------------------------------------------------------------------------
168// Reliability Semantics
169// -----------------------------------------------------------------------------
170
171// When a subscriber successfully creates a subscription using
172// Subscriber.CreateSubscription, it establishes a "subscription point" with
173// respect to that subscription - the subscriber is guaranteed to receive any
174// message published after this subscription point that matches the
175// subscription's query. Note that messages published before the Subscription
176// point may or may not be delivered.
177//
178// If the system truncates the subscription according to the specified
179// truncation policy, the system delivers a subscription status event with the
180// "truncated" field set to true. We refer to such events as "truncation
181// events". A truncation event:
182//
183// * Informs the subscriber that part of the subscription messages have been
184// discarded. The subscriber may want to recover from the message loss, e.g.,
185// by resyncing its state with its backend.
186// * Establishes a new subscription point, i.e., the subscriber is guaranteed to
187// receive all changes published after the trunction event is received (or
188// until another truncation event is received).
189//
190// Note that messages are not delivered in any particular order by the pubsub
191// system. Furthermore, the system guarantees at-least-once delivery
192// of each message or truncation events until acked.
193
194// -----------------------------------------------------------------------------
195// Deletion
196// -----------------------------------------------------------------------------
197
198// Both topics and subscriptions may be deleted. Deletion of a topic implies
199// deletion of all attached subscriptions.
200//
201// When a subscription is deleted directly by calling DeleteSubscription, all
202// messages are immediately dropped. If it is a pull subscriber, future pull
203// requests will return NOT_FOUND.
204//
205// When a topic is deleted all corresponding subscriptions are immediately
206// deleted, and subscribers experience the same behavior as directly deleting
207// the subscription.
208
209// -----------------------------------------------------------------------------
210// The Publisher service and its protos.
211// -----------------------------------------------------------------------------
212
213// The service that an application uses to manipulate topics, and to send
214// messages to a topic.
215service PublisherService {
216
217 // Creates the given topic with the given name.
218 rpc CreateTopic(Topic) returns (Topic) {
219 }
220
221 // Adds a message to the topic. Returns NOT_FOUND if the topic does not
222 // exist.
223 // (-- For different error code values returned via Stubby, see
224 // util/task/codes.proto. --)
225 rpc Publish(PublishRequest) returns (proto2.Empty) {
226 }
227
228 // Adds one or more messages to the topic. Returns NOT_FOUND if the topic does
229 // not exist.
230 rpc PublishBatch(PublishBatchRequest) returns (PublishBatchResponse) {
231 }
232
233 // Gets the configuration of a topic. Since the topic only has the name
234 // attribute, this method is only useful to check the existence of a topic.
235 // If other attributes are added in the future, they will be returned here.
236 rpc GetTopic(GetTopicRequest) returns (Topic) {
237 }
238
239 // Lists matching topics.
240 rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse) {
241 }
242
243 // Deletes the topic with the given name. All subscriptions to this topic
244 // are also deleted. Returns NOT_FOUND if the topic does not exist.
245 // After a topic is deleted, a new topic may be created with the same name.
246 rpc DeleteTopic(DeleteTopicRequest) returns (proto2.Empty) {
247 }
248}
249
250// A topic resource.
251message Topic {
252 // Name of the topic.
253 optional string name = 1;
254}
255
256// A message data and its labels.
257message PubsubMessage {
258 // The message payload.
259 optional bytes data = 1;
260
261 // Optional list of labels for this message. Keys in this collection must
262 // be unique.
263 //(-- TODO(eschapira): Define how key namespace may be scoped to the topic.--)
264 repeated tech.label.Label label = 2;
265
266 // ID of this message assigned by the server at publication time. Guaranteed
267 // to be unique within the topic. This value may be read by a subscriber
268 // that receives a PubsubMessage via a Pull call or a push delivery. It must
269 // not be populated by a publisher in a Publish call.
270 optional string message_id = 3;
271}
272
273// Request for the GetTopic method.
274message GetTopicRequest {
275 // The name of the topic to get.
276 optional string topic = 1;
277}
278
279// Request for the Publish method.
280message PublishRequest {
281 // The message in the request will be published on this topic.
282 optional string topic = 1;
283
284 // The message to publish.
285 optional PubsubMessage message = 2;
286}
287
288// Request for the PublishBatch method.
289message PublishBatchRequest {
290 // The messages in the request will be published on this topic.
291 optional string topic = 1;
292
293 // The messages to publish.
294 repeated PubsubMessage messages = 2;
295}
296
297// Response for the PublishBatch method.
298message PublishBatchResponse {
299 // The server-assigned ID of each published message, in the same order as
300 // the messages in the request. IDs are guaranteed to be unique within
301 // the topic.
302 repeated string message_ids = 1;
303}
304
305// Request for the ListTopics method.
306message ListTopicsRequest {
307 // A valid label query expression.
308 // (-- Which labels are required or supported is implementation-specific. --)
309 optional string query = 1;
310
311 // Maximum number of topics to return.
312 // (-- If not specified or <= 0, the implementation will select a reasonable
313 // value. --)
314 optional int32 max_results = 2;
315
316 // The value obtained in the last <code>ListTopicsResponse</code>
317 // for continuation.
318 optional string page_token = 3;
319
320}
321
322// Response for the ListTopics method.
323message ListTopicsResponse {
324 // The resulting topics.
325 repeated Topic topic = 1;
326
327 // If not empty, indicates that there are more topics that match the request,
328 // and this value should be passed to the next <code>ListTopicsRequest</code>
329 // to continue.
330 optional string next_page_token = 2;
331}
332
333// Request for the Delete method.
334message DeleteTopicRequest {
335 // Name of the topic to delete.
336 optional string topic = 1;
337}
338
339// -----------------------------------------------------------------------------
340// The Subscriber service and its protos.
341// -----------------------------------------------------------------------------
342
343// The service that an application uses to manipulate subscriptions and to
344// consume messages from a subscription via the pull method.
345service SubscriberService {
346
347 // Creates a subscription on a given topic for a given subscriber.
348 // If the subscription already exists, returns ALREADY_EXISTS.
349 // If the corresponding topic doesn't exist, returns NOT_FOUND.
350 //
351 // If the name is not provided in the request, the server will assign a random
352 // name for this subscription on the same project as the topic.
353 rpc CreateSubscription(Subscription) returns (Subscription) {
354 }
355
356 // Gets the configuration details of a subscription.
357 rpc GetSubscription(GetSubscriptionRequest) returns (Subscription) {
358 }
359
360 // Lists matching subscriptions.
361 rpc ListSubscriptions(ListSubscriptionsRequest)
362 returns (ListSubscriptionsResponse) {
363 }
364
365 // Deletes an existing subscription. All pending messages in the subscription
366 // are immediately dropped. Calls to Pull after deletion will return
367 // NOT_FOUND.
368 rpc DeleteSubscription(DeleteSubscriptionRequest) returns (proto2.Empty) {
369 }
370
371 // Removes all the pending messages in the subscription and releases the
372 // storage associated with them. Results in a truncation event to be sent to
373 // the subscriber. Messages added after this call returns are stored in the
374 // subscription as before.
375 rpc TruncateSubscription(TruncateSubscriptionRequest) returns (proto2.Empty) {
376 }
377
378 //
379 // Push subscriber calls.
380 //
381
382 // Modifies the <code>PushConfig</code> for a specified subscription.
383 // This method can be used to suspend the flow of messages to an endpoint
384 // by clearing the <code>PushConfig</code> field in the request. Messages
385 // will be accumulated for delivery even if no push configuration is
386 // defined or while the configuration is modified.
387 rpc ModifyPushConfig(ModifyPushConfigRequest) returns (proto2.Empty) {
388 }
389
390 //
391 // Pull Subscriber calls
392 //
393
394 // Pulls a single message from the server.
395 // If return_immediately is true, and no messages are available in the
396 // subscription, this method returns FAILED_PRECONDITION. The system is free
397 // to return an UNAVAILABLE error if no messages are available in a
398 // reasonable amount of time (to reduce system load).
399 rpc Pull(PullRequest) returns (PullResponse) {
400 }
401
402 // Pulls messages from the server. Returns an empty list if there are no
403 // messages available in the backlog. The system is free to return UNAVAILABLE
404 // if there are too many pull requests outstanding for the given subscription.
405 rpc PullBatch(PullBatchRequest) returns (PullBatchResponse) {
406 }
407
408 // Modifies the Ack deadline for a message received from a pull request.
409 rpc ModifyAckDeadline(ModifyAckDeadlineRequest) returns (proto2.Empty) {
410 }
411
412 // Acknowledges a particular received message: the Pub/Sub system can remove
413 // the given message from the subscription. Acknowledging a message whose
414 // Ack deadline has expired may succeed, but the message could have been
415 // already redelivered. Acknowledging a message more than once will not
416 // result in an error. This is only used for messages received via pull.
417 rpc Acknowledge(AcknowledgeRequest) returns (proto2.Empty) {
418 }
419
420 // Refuses processing a particular received message. The system will
421 // redeliver this message to some consumer of the subscription at some
422 // future time. This is only used for messages received via pull.
423 rpc Nack(NackRequest) returns (proto2.Empty) {
424 }
425}
426
427// A subscription resource.
428message Subscription {
429 // Name of the subscription.
430 optional string name = 1;
431
432 // The name of the topic from which this subscription is receiving messages.
433 optional string topic = 2;
434
435 // If <code>query</code> is non-empty, only messages on the subscriber's
436 // topic whose labels match the query will be returned. Otherwise all
437 // messages on the topic will be returned.
438 // (-- The query syntax is described in tech/label/proto/label_query.proto --)
439 optional string query = 3;
440
441 // The subscriber may specify requirements for truncating unacknowledged
442 // subscription entries. The system will honor the
443 // <code>CreateSubscription</code> request only if it can meet these
444 // requirements. If this field is not specified, messages are never truncated
445 // by the system.
446 optional TruncationPolicy truncation_policy = 4;
447
448 // Specifies which messages can be truncated by the system.
449 message TruncationPolicy {
450 oneof policy {
451 // If <code>max_bytes</code> is specified, the system is allowed to drop
452 // old messages to keep the combined size of stored messages under
453 // <code>max_bytes</code>. This is a hint; the system may keep more than
454 // this many bytes, but will make a best effort to keep the size from
455 // growing much beyond this parameter.
456 int64 max_bytes = 1;
457
458 // If <code>max_age_seconds</code> is specified, the system is allowed to
459 // drop messages that have been stored for at least this many seconds.
460 // This is a hint; the system may keep these messages, but will make a
461 // best effort to remove them when their maximum age is reached.
462 int64 max_age_seconds = 2;
463 }
464 }
465
466 // If push delivery is used with this subscription, this field is
467 // used to configure it.
468 optional PushConfig push_config = 5;
469
470 // For either push or pull delivery, the value is the maximum time after a
471 // subscriber receives a message before the subscriber should acknowledge or
472 // Nack the message. If the Ack deadline for a message passes without an
473 // Ack or a Nack, the Pub/Sub system will eventually redeliver the message.
474 // If a subscriber acknowledges after the deadline, the Pub/Sub system may
475 // accept the Ack, but it is possible that the message has been already
476 // delivered again. Multiple Acks to the message are allowed and will
477 // succeed.
478 //
479 // For push delivery, this value is used to set the request timeout for
480 // the call to the push endpoint.
481 //
482 // For pull delivery, this value is used as the initial value for the Ack
483 // deadline. It may be overridden for a specific pull request (message) with
484 // <code>ModifyAckDeadline</code>.
485 // While a message is outstanding (i.e. it has been delivered to a pull
486 // subscriber and the subscriber has not yet Acked or Nacked), the Pub/Sub
487 // system will not deliver that message to another pull subscriber
488 // (on a best-effort basis).
489 optional int32 ack_deadline_seconds = 6;
490
491 // If this parameter is set to n, the system is allowed to (but not required
492 // to) delete the subscription when at least n seconds have elapsed since the
493 // client presence was detected. (Presence is detected through any
494 // interaction using the subscription ID, including Pull(), Get(), or
495 // acknowledging a message.)
496 //
497 // If this parameter is not set, the subscription will stay live until
498 // explicitly deleted.
499 //
500 // Clients can detect such garbage collection when a Get call or a Pull call
501 // (for pull subscribers only) returns NOT_FOUND.
502 optional int64 garbage_collect_seconds = 7;
503}
504
505// Configuration for a push delivery endpoint.
506message PushConfig {
507 // A URL locating the endpoint to which messages should be pushed.
508 // For example, a Webhook endpoint might use "https://example.com/push".
509 // (-- An Android application might use "gcm:<REGID>", where <REGID> is a
510 // GCM registration id allocated for pushing messages to the application. --)
511 optional string push_endpoint = 1;
512}
513
514// An event indicating a received message or truncation event.
515message PubsubEvent {
516 // The subscription that received the event.
517 optional string subscription = 1;
518
519 oneof type {
520 // A received message.
521 PubsubMessage message = 2;
522
523 // Indicates that this subscription has been truncated.
524 bool truncated = 3;
525
526 // Indicates that this subscription has been deleted. (Note that pull
527 // subscribers will always receive NOT_FOUND in response in their pull
528 // request on the subscription, rather than seeing this boolean.)
529 bool deleted = 4;
530 }
531}
532
533// Request for the GetSubscription method.
534message GetSubscriptionRequest {
535 // The name of the subscription to get.
536 optional string subscription = 1;
537}
538
539// Request for the ListSubscriptions method.
540message ListSubscriptionsRequest {
541 // A valid label query expression.
542 // (-- Which labels are required or supported is implementation-specific.
543 // TODO(eschapira): This method must support to query by topic. We must
544 // define the key URI for the "topic" label. --)
545 optional string query = 1;
546
547 // Maximum number of subscriptions to return.
548 // (-- If not specified or <= 0, the implementation will select a reasonable
549 // value. --)
550 optional int32 max_results = 3;
551
552 // The value obtained in the last <code>ListSubscriptionsResponse</code>
553 // for continuation.
554 optional string page_token = 4;
555}
556
557// Response for the ListSubscriptions method.
558message ListSubscriptionsResponse {
559 // The subscriptions that match the request.
560 repeated Subscription subscription = 1;
561
562 // If not empty, indicates that there are more subscriptions that match the
563 // request and this value should be passed to the next
564 // <code>ListSubscriptionsRequest</code> to continue.
565 optional string next_page_token = 2;
566}
567
568// Request for the TruncateSubscription method.
569message TruncateSubscriptionRequest {
570 // The subscription that is being truncated.
571 optional string subscription = 1;
572}
573
574// Request for the DeleteSubscription method.
575message DeleteSubscriptionRequest {
576 // The subscription to delete.
577 optional string subscription = 1;
578}
579
580// Request for the ModifyPushConfig method.
581message ModifyPushConfigRequest {
582 // The name of the subscription.
583 optional string subscription = 1;
584
585 // An empty <code>push_config</code> indicates that the Pub/Sub system should
586 // pause pushing messages from the given subscription.
587 optional PushConfig push_config = 2;
588}
589
590// -----------------------------------------------------------------------------
591// The protos used by a pull subscriber.
592// -----------------------------------------------------------------------------
593
594// Request for the Pull method.
595message PullRequest {
596 // The subscription from which a message should be pulled.
597 optional string subscription = 1;
598
599 // If this is specified as true the system will respond immediately even if
600 // it is not able to return a message in the Pull response. Otherwise the
601 // system is allowed to wait until at least one message is available rather
602 // than returning FAILED_PRECONDITION. The client may cancel the request if
603 // it does not wish to wait any longer for the response.
604 optional bool return_immediately = 2;
605}
606
607// Either a <code>PubsubMessage</code> or a truncation event. One of these two
608// must be populated.
609message PullResponse {
610 // This ID must be used to acknowledge the received event or message.
611 optional string ack_id = 1;
612
613 // A pubsub message or truncation event.
614 optional PubsubEvent pubsub_event = 2;
615}
616
617// Request for the PullBatch method.
618message PullBatchRequest {
619 // The subscription from which messages should be pulled.
620 optional string subscription = 1;
621
622 // If this is specified as true the system will respond immediately even if
623 // it is not able to return a message in the Pull response. Otherwise the
624 // system is allowed to wait until at least one message is available rather
625 // than returning no messages. The client may cancel the request if it does
626 // not wish to wait any longer for the response.
627 optional bool return_immediately = 2;
628
629 // The maximum number of PubsubEvents returned for this request. The Pub/Sub
630 // system may return fewer than the number of events specified.
631 optional int32 max_events = 3;
632}
633
634// Response for the PullBatch method.
635message PullBatchResponse {
636
637 // Received Pub/Sub messages or status events. The Pub/Sub system will return
638 // zero messages if there are no more messages available in the backlog. The
639 // Pub/Sub system may return fewer than the max_events requested even if
640 // there are more messages available in the backlog.
641 repeated PullResponse pull_responses = 2;
642}
643
644// Request for the ModifyAckDeadline method.
645message ModifyAckDeadlineRequest {
646 // The name of the subscription from which messages are being pulled.
647 optional string subscription = 1;
648
649 // The acknowledgment ID.
650 optional string ack_id = 2;
651
652 // The new Ack deadline. Must be >= 0.
653 optional int32 ack_deadline_seconds = 3;
654}
655
656// Request for the Acknowledge method.
657message AcknowledgeRequest {
658 // The subscription whose message is being acknowledged.
659 optional string subscription = 1;
660
661 // The acknowledgment ID for the message being acknowledged. This was
662 // returned by the Pub/Sub system in the Pull response.
663 repeated string ack_id = 2;
664}
665
666// Request for the Nack method.
667message NackRequest {
668 // The subscription whose message is being Nacked.
669 optional string subscription = 1;
670
671 // The acknowledgment ID for the message being refused. This was returned by
672 // the Pub/Sub system in the Pull response.
673 repeated string ack_id = 2;
674}
675
676// -----------------------------------------------------------------------------
677// The service and protos used by a push subscriber.
678// -----------------------------------------------------------------------------
679
680// The service that a subscriber uses to handle messages sent via push
681// delivery.
682// This service is not currently exported for HTTP clients.
683// TODO(eschapira): Explain HTTP subscribers.
684service PushEndpointService {
685 // Sends a <code>PubsubMessage</code> or a subscription status event to a
686 // push endpoint.
687 // The push endpoint responds with an empty message and a code from
688 // util/task/codes.proto. The following codes have a particular meaning to the
689 // Pub/Sub system:
690 // OK - This is interpreted by Pub/Sub as Ack.
691 // ABORTED - This is intepreted by Pub/Sub as a Nack, without implying
692 // pushback for congestion control. The Pub/Sub system will
693 // retry this message at a later time.
694 // UNAVAILABLE - This is intepreted by Pub/Sub as a Nack, with the additional
695 // semantics of push-back. The Pub/Sub system will use an AIMD
696 // congestion control algorithm to backoff the rate of sending
697 // messages from this subscription.
698 // Any other code, or a failure to respond, will be interpreted in the same
699 // way as ABORTED; i.e. the system will retry the message at a later time to
700 // ensure reliable delivery.
701 rpc HandlePubsubEvent(PubsubEvent) returns (proto2.Empty);
702}