127 lines
3.1 KiB
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"
|
|
}
|