mirror of
https://github.com/netsampler/goflow2.git
synced 2024-05-06 15:54:52 +00:00
Defer unlocking just after taking a lock when possible (when unlock is done at the very end) and when not trivial (the function body is more than a couple of lines). This simplifies a bit some functions (no need to unlock before each return) and for the other, it may avoid a bug in the future in case a return is inserted into the body of a function. Use of defer has been optimized a lot in Go and it is believed that simpler defers have zero overhead since Go 1.14: https://golang.org/doc/go1.14#runtime > This release improves the performance of most uses of defer to incur > almost zero overhead compared to calling the deferred function > directly. As a result, defer can now be used in performance-critical > code without overhead concerns.
69 lines
1.4 KiB
Go
69 lines
1.4 KiB
Go
package transport
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
var (
|
|
transportDrivers = make(map[string]TransportDriver)
|
|
lock = &sync.RWMutex{}
|
|
)
|
|
|
|
type TransportDriver interface {
|
|
Prepare() error // Prepare driver (eg: flag registration)
|
|
Init(context.Context) error // Initialize driver (eg: start connections, open files...)
|
|
Close(context.Context) error // Close driver (eg: close connections and files...)
|
|
Send(key, data []byte) error // Send a formatted message
|
|
}
|
|
|
|
type TransportInterface interface {
|
|
Send(key, data []byte) error
|
|
}
|
|
|
|
type Transport struct {
|
|
driver TransportDriver
|
|
}
|
|
|
|
func (t *Transport) Close(ctx context.Context) {
|
|
t.driver.Close(ctx)
|
|
}
|
|
func (t *Transport) Send(key, data []byte) error {
|
|
return t.driver.Send(key, data)
|
|
}
|
|
|
|
func RegisterTransportDriver(name string, t TransportDriver) {
|
|
lock.Lock()
|
|
transportDrivers[name] = t
|
|
lock.Unlock()
|
|
|
|
if err := t.Prepare(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func FindTransport(ctx context.Context, name string) (*Transport, error) {
|
|
lock.RLock()
|
|
t, ok := transportDrivers[name]
|
|
lock.RUnlock()
|
|
if !ok {
|
|
return nil, fmt.Errorf("Transport %s not found", name)
|
|
}
|
|
|
|
err := t.Init(ctx)
|
|
return &Transport{t}, err
|
|
}
|
|
|
|
func GetTransports() []string {
|
|
lock.RLock()
|
|
defer lock.RUnlock()
|
|
t := make([]string, len(transportDrivers))
|
|
var i int
|
|
for k, _ := range transportDrivers {
|
|
t[i] = k
|
|
i++
|
|
}
|
|
return t
|
|
}
|