1
0
mirror of https://github.com/netsampler/goflow2.git synced 2024-05-06 15:54:52 +00:00
Vincent Bernat 95945d3042 style: defer unlock when possible/not trivial
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.
2021-09-23 10:01:24 +02:00

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
}