github.com/thiagoyeds/go-cloud@v0.26.0/pubsub/example_test.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 pubsub_test
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"log"
    21  
    22  	"gocloud.dev/pubsub"
    23  
    24  	pbraw "cloud.google.com/go/pubsub/apiv1"
    25  	pbapi "google.golang.org/genproto/googleapis/pubsub/v1"
    26  	"google.golang.org/grpc/status"
    27  )
    28  
    29  func ExampleTopic_Send() {
    30  	// PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored.
    31  	// PRAGMA: On gocloud.dev, hide lines until the next blank line.
    32  	ctx := context.Background()
    33  	var topic *pubsub.Topic
    34  
    35  	err := topic.Send(ctx, &pubsub.Message{
    36  		Body: []byte("Hello, World!\n"),
    37  		// Metadata is optional and can be nil.
    38  		Metadata: map[string]string{
    39  			// These are examples of metadata.
    40  			// There is nothing special about the key names.
    41  			"language":   "en",
    42  			"importance": "high",
    43  		},
    44  	})
    45  	if err != nil {
    46  		log.Fatal(err)
    47  	}
    48  }
    49  
    50  func ExampleSubscription_Receive() {
    51  	// PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored.
    52  	// PRAGMA: On gocloud.dev, hide lines until the next blank line.
    53  	ctx := context.Background()
    54  	var subscription *pubsub.Subscription
    55  
    56  	// Loop on received messages.
    57  	for {
    58  		msg, err := subscription.Receive(ctx)
    59  		if err != nil {
    60  			// Errors from Receive indicate that Receive will no longer succeed.
    61  			log.Printf("Receiving message: %v", err)
    62  			break
    63  		}
    64  		// Do work based on the message, for example:
    65  		fmt.Printf("Got message: %q\n", msg.Body)
    66  		// Messages must always be acknowledged with Ack.
    67  		msg.Ack()
    68  	}
    69  }
    70  
    71  func ExampleSubscription_Receive_concurrent() {
    72  	// PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored.
    73  	// PRAGMA: On gocloud.dev, hide lines until the next blank line.
    74  	ctx := context.Background()
    75  	var subscription *pubsub.Subscription
    76  
    77  	// Loop on received messages. We can use a channel as a semaphore to limit how
    78  	// many goroutines we have active at a time as well as wait on the goroutines
    79  	// to finish before exiting.
    80  	const maxHandlers = 10
    81  	sem := make(chan struct{}, maxHandlers)
    82  recvLoop:
    83  	for {
    84  		msg, err := subscription.Receive(ctx)
    85  		if err != nil {
    86  			// Errors from Receive indicate that Receive will no longer succeed.
    87  			log.Printf("Receiving message: %v", err)
    88  			break
    89  		}
    90  
    91  		// Wait if there are too many active handle goroutines and acquire the
    92  		// semaphore. If the context is canceled, stop waiting and start shutting
    93  		// down.
    94  		select {
    95  		case sem <- struct{}{}:
    96  		case <-ctx.Done():
    97  			break recvLoop
    98  		}
    99  
   100  		// Handle the message in a new goroutine.
   101  		go func() {
   102  			defer func() { <-sem }() // Release the semaphore.
   103  			defer msg.Ack()          // Messages must always be acknowledged with Ack.
   104  
   105  			// Do work based on the message, for example:
   106  			fmt.Printf("Got message: %q\n", msg.Body)
   107  		}()
   108  	}
   109  
   110  	// We're no longer receiving messages. Wait to finish handling any
   111  	// unacknowledged messages by totally acquiring the semaphore.
   112  	for n := 0; n < maxHandlers; n++ {
   113  		sem <- struct{}{}
   114  	}
   115  }
   116  
   117  func ExampleMessage_As() {
   118  	// This example is specific to the gcppubsub implementation; it demonstrates
   119  	// access to the underlying PubsubMessage type.
   120  	// The types exposed for As by gcppubsub are documented in
   121  	// https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As
   122  
   123  	ctx := context.Background()
   124  	sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/topic")
   125  	if err != nil {
   126  		log.Fatal(err)
   127  	}
   128  	defer sub.Shutdown(ctx)
   129  
   130  	msg, err := sub.Receive(ctx)
   131  	if err != nil {
   132  		log.Fatal(err)
   133  	}
   134  	var pm *pbapi.PubsubMessage
   135  	if msg.As(&pm) {
   136  		_ = pm.GetAttributes()
   137  	}
   138  	msg.Ack()
   139  }
   140  
   141  func ExampleSubscription_As() {
   142  	// This example is specific to the gcppubsub implementation; it demonstrates
   143  	// access to the underlying SubscriberClient type.
   144  	// The types exposed for As by gcppubsub are documented in
   145  	// https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As
   146  
   147  	ctx := context.Background()
   148  	sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/topic")
   149  	if err != nil {
   150  		log.Fatal(err)
   151  	}
   152  	defer sub.Shutdown(ctx)
   153  
   154  	var sc *pbraw.SubscriberClient
   155  	if sub.As(&sc) {
   156  		_ = sc.CallOptions
   157  	}
   158  }
   159  
   160  func ExampleSubscription_ErrorAs() {
   161  	// This example is specific to the gcppubsub implementation; it demonstrates
   162  	// access to the underlying Status type.
   163  	// The types exposed for As by gcppubsub are documented in
   164  	// https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As
   165  
   166  	ctx := context.Background()
   167  	sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/badtopic")
   168  	if err != nil {
   169  		log.Fatal(err)
   170  	}
   171  	defer sub.Shutdown(ctx)
   172  
   173  	msg, err := sub.Receive(ctx)
   174  	if err != nil {
   175  		var s *status.Status
   176  		if sub.ErrorAs(err, &s) {
   177  			_ = s.Code()
   178  		}
   179  		log.Fatal(err)
   180  	}
   181  	msg.Ack()
   182  }
   183  
   184  func ExampleTopic_As() {
   185  	// This example is specific to the gcppubsub implementation; it demonstrates
   186  	// access to the underlying PublisherClient type.
   187  	// The types exposed for As by gcppubsub are documented in
   188  	// https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As
   189  
   190  	ctx := context.Background()
   191  	topic, err := pubsub.OpenTopic(ctx, "gcppubsub://project/topic")
   192  	if err != nil {
   193  		log.Fatal(err)
   194  	}
   195  	defer topic.Shutdown(ctx)
   196  
   197  	var pc *pbraw.PublisherClient
   198  	if topic.As(&pc) {
   199  		_ = pc
   200  	}
   201  }
   202  
   203  func ExampleTopic_ErrorAs() {
   204  	// This example is specific to the gcppubsub implementation; it demonstrates
   205  	// access to the underlying Status type.
   206  	// The types exposed for As by gcppubsub are documented in
   207  	// https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As
   208  
   209  	ctx := context.Background()
   210  	topic, err := pubsub.OpenTopic(ctx, "gcppubsub://project/topic")
   211  	if err != nil {
   212  		log.Fatal(err)
   213  	}
   214  	defer topic.Shutdown(ctx)
   215  
   216  	err = topic.Send(ctx, &pubsub.Message{Body: []byte("hello")})
   217  	if err != nil {
   218  		var s *status.Status
   219  		if topic.ErrorAs(err, &s) {
   220  			_ = s.Code()
   221  		}
   222  		log.Fatal(err)
   223  	}
   224  }