github.com/thiagoyeds/go-cloud@v0.26.0/pubsub/driver/driver.go (about) 1 // Copyright 2018 The Go Cloud Development Kit Authors 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 // https://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 15 // Package driver defines interfaces to be implemented by pubsub drivers, which 16 // will be used by the pubsub package to interact with the underlying services. 17 // Application code should use package pubsub. 18 package driver // import "gocloud.dev/pubsub/driver" 19 20 import ( 21 "context" 22 23 "gocloud.dev/gcerrors" 24 ) 25 26 // AckID is the identifier of a message for purposes of acknowledgement. 27 type AckID interface{} 28 29 // AckInfo represents an action on an AckID. 30 type AckInfo struct { 31 // AckID is the AckID the action is for. 32 AckID AckID 33 // IsAck is true if the AckID should be acked, false if it should be nacked. 34 IsAck bool 35 } 36 37 // Message is data to be published (sent) to a topic and later received from 38 // subscriptions on that topic. 39 type Message struct { 40 // LoggableID should be set to an opaque message identifer for 41 // received messages. 42 LoggableID string 43 44 // Body contains the content of the message. 45 Body []byte 46 47 // Metadata has key/value pairs describing the message. 48 Metadata map[string]string 49 50 // AckID should be set to something identifying the message on the 51 // server. It may be passed to Subscription.SendAcks to acknowledge 52 // the message, or to Subscription.SendNacks. This field should only 53 // be set by methods implementing Subscription.ReceiveBatch. 54 AckID AckID 55 56 // AsFunc allows drivers to expose driver-specific types; 57 // see Topic.As for more details. 58 // AsFunc must be populated on messages returned from ReceiveBatch. 59 AsFunc func(interface{}) bool 60 61 // BeforeSend is a callback used when sending a message. It should remain 62 // nil on messages returned from ReceiveBatch. 63 // 64 // The callback must be called exactly once, before the message is sent. 65 // 66 // asFunc converts its argument to driver-specific types. 67 // See https://gocloud.dev/concepts/as/ for background information. 68 BeforeSend func(asFunc func(interface{}) bool) error 69 70 // AfterSend is a callback used when sending a message. It should remain 71 // nil on messages returned from ReceiveBatch. 72 // 73 // The callback must be called at most once, after the message is sent. 74 // If Send returns an error, AfterSend will not be called. 75 // 76 // asFunc converts its argument to driver-specific types. 77 // See https://gocloud.dev/concepts/as/ for background information. 78 AfterSend func(asFunc func(interface{}) bool) error 79 } 80 81 // ByteSize estimates the size in bytes of the message for the purpose of restricting batch sizes. 82 func (m *Message) ByteSize() int { 83 return len(m.Body) 84 } 85 86 // Topic publishes messages. 87 // Drivers may optionally also implement io.Closer; Close will be called 88 // when the pubsub.Topic is Shutdown. 89 type Topic interface { 90 // SendBatch should publish all the messages in ms. It should 91 // return only after all the messages are sent, an error occurs, or the 92 // context is done. 93 // 94 // Only the Body and (optionally) Metadata fields of the Messages in ms 95 // will be set by the caller of SendBatch. 96 // 97 // If any message in the batch fails to send, SendBatch should return an 98 // error. 99 // 100 // If there is a transient failure, this method should not retry but 101 // should return an error for which IsRetryable returns true. The 102 // concrete API takes care of retry logic. 103 // 104 // The slice ms should not be retained past the end of the call to 105 // SendBatch. 106 // 107 // SendBatch may be called concurrently from multiple goroutines. 108 // 109 // Drivers can control the number of messages sent in a single batch 110 // and the concurrency of calls to SendBatch via a batcher.Options 111 // passed to pubsub.NewTopic. 112 SendBatch(ctx context.Context, ms []*Message) error 113 114 // IsRetryable should report whether err can be retried. 115 // err will always be a non-nil error returned from SendBatch. 116 IsRetryable(err error) bool 117 118 // As allows drivers to expose driver-specific types. 119 // See https://gocloud.dev/concepts/as/ for background information. 120 As(i interface{}) bool 121 122 // ErrorAs allows drivers to expose driver-specific types for errors. 123 // See https://gocloud.dev/concepts/as/ for background information. 124 ErrorAs(error, interface{}) bool 125 126 // ErrorCode should return a code that describes the error, which was returned by 127 // one of the other methods in this interface. 128 ErrorCode(error) gcerrors.ErrorCode 129 130 // Close cleans up any resources used by the Topic. Once Close is called, 131 // there will be no method calls to the Topic other than As, ErrorAs, and 132 // ErrorCode. 133 Close() error 134 } 135 136 // Subscription receives published messages. 137 // Drivers may optionally also implement io.Closer; Close will be called 138 // when the pubsub.Subscription is Shutdown. 139 type Subscription interface { 140 // ReceiveBatch should return a batch of messages that have queued up 141 // for the subscription on the server, up to maxMessages. 142 // 143 // If there is a transient failure, this method should not retry but 144 // should return a nil slice and an error. The concrete API will take 145 // care of retry logic. 146 // 147 // If no messages are currently available, this method should block for 148 // no more than about 1 second. It can return an empty 149 // slice of messages and no error. ReceiveBatch will be called again 150 // immediately, so implementations should try to wait for messages for some 151 // non-zero amount of time before returning zero messages. If the underlying 152 // service doesn't support waiting, then a time.Sleep can be used. 153 // 154 // ReceiveBatch may be called concurrently from multiple goroutines. 155 // 156 // Drivers can control the maximum value of maxMessages and the concurrency 157 // of calls to ReceiveBatch via a batcher.Options passed to 158 // pubsub.NewSubscription. 159 ReceiveBatch(ctx context.Context, maxMessages int) ([]*Message, error) 160 161 // SendAcks should acknowledge the messages with the given ackIDs on 162 // the server so that they will not be received again for this 163 // subscription if the server gets the acks before their deadlines. 164 // This method should return only after all the ackIDs are sent, an 165 // error occurs, or the context is done. 166 // 167 // It is acceptable for SendAcks to be a no-op for drivers that don't 168 // support message acknowledgement. 169 // 170 // Drivers should suppress errors caused by double-acking a message. 171 // 172 // SendAcks may be called concurrently from multiple goroutines. 173 // 174 // Drivers can control the maximum size of ackIDs and the concurrency 175 // of calls to SendAcks/SendNacks via a batcher.Options passed to 176 // pubsub.NewSubscription. 177 SendAcks(ctx context.Context, ackIDs []AckID) error 178 179 // CanNack must return true iff the driver supports Nacking messages. 180 // 181 // If CanNack returns false, SendNacks will never be called, and Nack will 182 // panic if called. 183 CanNack() bool 184 185 // SendNacks should notify the server that the messages with the given ackIDs 186 // are not being processed by this client, so that they will be received 187 // again later, potentially by another subscription. 188 // This method should return only after all the ackIDs are sent, an 189 // error occurs, or the context is done. 190 // 191 // If the service does not suppport nacking of messages, return false from 192 // CanNack, and SendNacks will never be called. 193 // 194 // SendNacks may be called concurrently from multiple goroutines. 195 // 196 // Drivers can control the maximum size of ackIDs and the concurrency 197 // of calls to SendAcks/Nacks via a batcher.Options passed to 198 // pubsub.NewSubscription. 199 SendNacks(ctx context.Context, ackIDs []AckID) error 200 201 // IsRetryable should report whether err can be retried. 202 // err will always be a non-nil error returned from ReceiveBatch or SendAcks. 203 IsRetryable(err error) bool 204 205 // As converts i to driver-specific types. 206 // See https://gocloud.dev/concepts/as/ for background information. 207 As(i interface{}) bool 208 209 // ErrorAs allows drivers to expose driver-specific types for errors. 210 // See https://gocloud.dev/concepts/as/ for background information. 211 ErrorAs(error, interface{}) bool 212 213 // ErrorCode should return a code that describes the error, which was returned by 214 // one of the other methods in this interface. 215 ErrorCode(error) gcerrors.ErrorCode 216 217 // Close cleans up any resources used by the Topic. Once Close is called, 218 // there will be no method calls to the Topic other than As, ErrorAs, and 219 // ErrorCode. 220 Close() error 221 }