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  }