60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
|
package beater
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
|
||
|
"github.com/elastic/beats/libbeat/publisher"
|
||
|
)
|
||
|
|
||
|
// ModuleRunner is a facade for a ModuleWrapper that provides a simple interface
|
||
|
// for starting and stopping a Module.
|
||
|
type ModuleRunner interface {
|
||
|
// Start starts the Module. If Start is called more than once, only the
|
||
|
// first will start the Module.
|
||
|
Start()
|
||
|
|
||
|
// Stop stops the Module and waits for module's MetricSets to exit. The
|
||
|
// publisher.Client will be closed by Stop. If Stop is called more than
|
||
|
// once, only the first stop the Module and wait for it to exit.
|
||
|
Stop()
|
||
|
}
|
||
|
|
||
|
// NewModuleRunner returns a ModuleRunner facade. The events generated by
|
||
|
// the Module will be published to a new publisher.Client generated from the
|
||
|
// pubClientFactory.
|
||
|
func NewModuleRunner(pubClientFactory func() publisher.Client, mod *ModuleWrapper) ModuleRunner {
|
||
|
return &moduleRunner{
|
||
|
done: make(chan struct{}),
|
||
|
mod: mod,
|
||
|
client: pubClientFactory(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type moduleRunner struct {
|
||
|
done chan struct{}
|
||
|
wg sync.WaitGroup
|
||
|
startOnce sync.Once
|
||
|
stopOnce sync.Once
|
||
|
mod *ModuleWrapper
|
||
|
client publisher.Client
|
||
|
}
|
||
|
|
||
|
func (mr *moduleRunner) Start() {
|
||
|
mr.startOnce.Do(func() {
|
||
|
output := mr.mod.Start(mr.done)
|
||
|
mr.wg.Add(1)
|
||
|
go func() {
|
||
|
defer mr.wg.Done()
|
||
|
PublishChannels(mr.client, output)
|
||
|
}()
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (mr *moduleRunner) Stop() {
|
||
|
mr.stopOnce.Do(func() {
|
||
|
close(mr.done)
|
||
|
mr.client.Close()
|
||
|
mr.wg.Wait()
|
||
|
})
|
||
|
}
|