Files
orchard/pkg/client/events.go
T
Nikolay EdigaryevandFedor Korotkov 77656517fd Controller info endpoint and API integration examples (#75)
* Controller API: introduce controller's information endpoint

* Prevent generation of empty events after channel closure

* Allow events to be buffered in the events channel

* Controller API: introduce controller's information endpoint[1]

* IntegrationGuide.md: a couple of Python and Golang examples

* Rephrase a sentence

Co-authored-by: Fedor Korotkov <fedor.korotkov@gmail.com>

---------

Co-authored-by: Fedor Korotkov <fedor.korotkov@gmail.com>
2023-04-11 07:28:46 +00:00

76 lines
1.5 KiB
Go

package client
import (
"context"
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
"github.com/hashicorp/go-multierror"
"io"
"net/http"
)
type EventStreamer struct {
client *Client
endpoint string
eventsChannel chan v1.Event
sendErr error
io.Closer
}
func NewEventStreamer(client *Client, endpoint string) *EventStreamer {
streamer := &EventStreamer{
client: client,
endpoint: endpoint,
eventsChannel: make(chan v1.Event, 64),
}
go streamer.stream()
return streamer
}
func (streamer *EventStreamer) Stream(event v1.Event) {
streamer.eventsChannel <- event
}
func (streamer *EventStreamer) stream() {
ctx := context.Background()
for {
events, finished := streamer.readAvailableEvents()
err := streamer.client.request(ctx, http.MethodPost, streamer.endpoint, events, nil, nil)
if err != nil {
streamer.sendErr = multierror.Append(streamer.sendErr, err)
}
if finished {
break
}
}
}
func (streamer *EventStreamer) readAvailableEvents() ([]v1.Event, bool) {
var result []v1.Event
// blocking wait for at least one event
nextEvent, ok := <-streamer.eventsChannel
if !ok {
return result, true
}
result = append(result, nextEvent)
// non-blocking wait for more events, if any
for {
select {
case nextEvent, ok := <-streamer.eventsChannel:
if !ok {
return result, true
}
result = append(result, nextEvent)
default:
return result, false
}
}
}
func (streamer *EventStreamer) Close() error {
close(streamer.eventsChannel)
return streamer.sendErr
}