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 }