2016-10-31 22:51:19 +00:00
|
|
|
package pubsub
|
|
|
|
|
|
|
|
import (
|
2017-03-15 15:55:30 +00:00
|
|
|
"context"
|
2016-12-27 15:35:19 +00:00
|
|
|
"strconv"
|
2016-10-31 22:51:19 +00:00
|
|
|
"sync"
|
|
|
|
|
2020-11-11 17:59:12 +00:00
|
|
|
"github.com/fleetdm/fleet/server/kolide"
|
2016-10-31 22:51:19 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type inmemQueryResults struct {
|
|
|
|
resultChannels map[uint]chan interface{}
|
|
|
|
channelMutex sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ kolide.QueryResultStore = &inmemQueryResults{}
|
|
|
|
|
|
|
|
// NewInmemQueryResults initializes a new in-memory implementation of the
|
|
|
|
// QueryResultStore interface.
|
|
|
|
func NewInmemQueryResults() *inmemQueryResults {
|
|
|
|
return &inmemQueryResults{resultChannels: map[uint]chan interface{}{}}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (im *inmemQueryResults) getChannel(id uint) chan interface{} {
|
|
|
|
im.channelMutex.Lock()
|
|
|
|
defer im.channelMutex.Unlock()
|
|
|
|
|
|
|
|
channel, ok := im.resultChannels[id]
|
|
|
|
if !ok {
|
|
|
|
channel = make(chan interface{})
|
|
|
|
im.resultChannels[id] = channel
|
|
|
|
}
|
|
|
|
return channel
|
|
|
|
}
|
|
|
|
|
|
|
|
func (im *inmemQueryResults) WriteResult(result kolide.DistributedQueryResult) error {
|
|
|
|
channel, ok := im.resultChannels[result.DistributedQueryCampaignID]
|
|
|
|
if !ok {
|
2016-12-27 15:35:19 +00:00
|
|
|
return noSubscriberError{strconv.Itoa(int(result.DistributedQueryCampaignID))}
|
2016-10-31 22:51:19 +00:00
|
|
|
}
|
|
|
|
|
2016-11-14 18:22:54 +00:00
|
|
|
select {
|
|
|
|
case channel <- result:
|
|
|
|
// intentionally do nothing
|
|
|
|
default:
|
2016-12-27 15:35:19 +00:00
|
|
|
return noSubscriberError{strconv.Itoa(int(result.DistributedQueryCampaignID))}
|
2016-11-14 18:22:54 +00:00
|
|
|
}
|
2016-10-31 22:51:19 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-06 16:30:24 +00:00
|
|
|
func (im *inmemQueryResults) ReadChannel(ctx context.Context, campaign kolide.DistributedQueryCampaign) (<-chan interface{}, error) {
|
|
|
|
channel := im.getChannel(campaign.ID)
|
2016-10-31 22:51:19 +00:00
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
close(channel)
|
|
|
|
im.channelMutex.Lock()
|
2020-10-06 16:30:24 +00:00
|
|
|
delete(im.resultChannels, campaign.ID)
|
2016-10-31 22:51:19 +00:00
|
|
|
im.channelMutex.Unlock()
|
|
|
|
}()
|
|
|
|
return channel, nil
|
|
|
|
}
|
2019-08-13 16:42:58 +00:00
|
|
|
|
|
|
|
func (im *inmemQueryResults) HealthCheck() error {
|
|
|
|
return nil
|
|
|
|
}
|