sdk-go/v1/binding/example_using_test.go

127 lines
3.1 KiB
Go

package binding_test
import (
"context"
"fmt"
"io"
"strconv"
"github.com/cloudevents/sdk-go/v1/cloudevents"
"github.com/cloudevents/sdk-go/v1/cloudevents/client"
)
const count = 3 // Example ends after this many events.
// The sender uses the cloudevents.Client API, not the transport APIs directly.
func runSender(w io.Writer) error {
c, err := client.New(NewExTransport(nil, w), client.WithoutTracePropagation())
if err != nil {
return err
}
for i := 0; i < count; i++ {
e := cloudevents.New()
e.SetType("example.com/event")
e.SetSource("example.com/source")
e.SetID(strconv.Itoa(i))
if err := e.SetData(fmt.Sprintf("hello %d", i)); err != nil {
return err
}
if _, _, err := c.Send(context.TODO(), e); err != nil {
return err
}
}
return nil
}
// The receiver uses the cloudevents.Client API, not the transport APIs directly.
func runReceiver(r io.Reader) error {
i := 0
process := func(e cloudevents.Event) error {
fmt.Printf("%s\n", e)
i++
if i == count {
return io.EOF
}
return nil
}
c, err := client.New(NewExTransport(r, nil), client.WithoutTracePropagation())
if err != nil {
return err
}
return c.StartReceiver(context.TODO(), process)
}
// The intermediary receives events and forwards them to another
// process using ExReceiver and ExSender directly.
//
// By forwarding a transport.Message instead of a cloudevents.Event,
// it allows the transports to avoid un-necessary decoding of
// structured events, and to exchange delivery status between reliable
// transports. Even transports using different protocols can ensure
// reliable delivery.
//
func runIntermediary(r io.Reader, w io.WriteCloser) error {
defer w.Close()
for {
receiver := NewExReceiver(r)
sender := NewExSender(w)
for i := 0; i < count; i++ {
if m, err := receiver.Receive(context.TODO()); err != nil {
return err
} else if err := sender.Send(context.TODO(), m); err != nil {
return err
}
}
}
}
// This example shows how to use a transport in sender, receiver,
// and intermediary processes.
//
// The sender and receiver use the client.Client API to send and
// receive messages. the transport. Only the intermediary example
// actually uses the transport APIs for efficiency and reliability in
// forwarding events.
func Example_using() {
r1, w1 := io.Pipe() // The sender-to-intermediary pipe
r2, w2 := io.Pipe() // The intermediary-to-receiver pipe
done := make(chan error)
go func() { done <- runReceiver(r2) }()
go func() { done <- runIntermediary(r1, w2) }()
go func() { done <- runSender(w1) }()
for i := 0; i < 2; i++ {
if err := <-done; err != nil && err != io.EOF {
fmt.Println(err)
}
}
// Output:
// Validation: valid
// Context Attributes,
// specversion: 1.0
// type: example.com/event
// source: example.com/source
// id: 0
// Data,
// "hello 0"
//
// Validation: valid
// Context Attributes,
// specversion: 1.0
// type: example.com/event
// source: example.com/source
// id: 1
// Data,
// "hello 1"
//
// Validation: valid
// Context Attributes,
// specversion: 1.0
// type: example.com/event
// source: example.com/source
// id: 2
// Data,
// "hello 2"
}