<commit_before>package scraper

import (
	"fmt"
	"math"
	"sync"
	"sync/atomic"

	"github.com/influxdata/kapacitor/edge"
	"github.com/influxdata/kapacitor/models"
	plog "github.com/prometheus/common/log"
	"github.com/prometheus/common/model"
	"github.com/prometheus/prometheus/config"
	"github.com/prometheus/prometheus/retrieval"
	"github.com/prometheus/prometheus/storage"
)

var (
	_ Registry               = &Service{}
	_ storage.SampleAppender = &Service{}
)

// Prometheus logger
type Diagnostic plog.Logger

// Service represents the scraper manager
type Service struct {
	PointsWriter interface {
		WriteKapacitorPoint(edge.PointMessage) error
	}
	mu sync.Mutex
	wg sync.WaitGroup

	open     bool
	running  bool
	closing  chan struct{}
	updating chan *config.Config

	configs atomic.Value // []Config

	diag Diagnostic

	discoverers []Discoverer

	// TargetManager represents a scraping/discovery manager
	mgr interface {
		ApplyConfig(cfg *config.Config) error
		Stop()
		Start()
		Wait()
	}
}

// NewService creates a new scraper service
func NewService(c []Config, d Diagnostic) *Service {
	s := &Service{
		diag: d,
	}
	s.storeConfigs(c)
	s.mgr = retrieval.NewTargetManager(s, d)
	return s
}

// Open starts the scraper service
func (s *Service) Open() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.open {
		return nil
	}

	s.open = true
	s.updating = make(chan *config.Config)
	s.closing = make(chan struct{})

	go s.scrape()

	s.open = true
	return nil
}

// Close stops the scraper service
func (s *Service) Close() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if !s.open {
		return nil
	}

	s.open = false
	close(s.closing)

	s.wg.Wait()

	return nil
}

func (s *Service) loadConfigs() []Config {
	return s.configs.Load().([]Config)
}

func (s *Service) storeConfigs(c []Config) {
	s.configs.Store(c)
}

func (s *Service) scrape() {
	s.wg.Add(1)<commit_msg>fix: guard less, otherwise `Close` cannot quit.<commit_after>package scraper

import (
	"fmt"
	"math"
	"sync"
	"sync/atomic"

	"github.com/influxdata/kapacitor/edge"
	"github.com/influxdata/kapacitor/models"
	plog "github.com/prometheus/common/log"
	"github.com/prometheus/common/model"
	"github.com/prometheus/prometheus/config"
	"github.com/prometheus/prometheus/retrieval"
	"github.com/prometheus/prometheus/storage"
)

var (
	_ Registry               = &Service{}
	_ storage.SampleAppender = &Service{}
)

// Prometheus logger
type Diagnostic plog.Logger

// Service represents the scraper manager
type Service struct {
	PointsWriter interface {
		WriteKapacitorPoint(edge.PointMessage) error
	}
	mu sync.Mutex
	wg sync.WaitGroup

	open     bool
	running  bool
	closing  chan struct{}
	updating chan *config.Config

	configs atomic.Value // []Config

	diag Diagnostic

	discoverers []Discoverer

	// TargetManager represents a scraping/discovery manager
	mgr interface {
		ApplyConfig(cfg *config.Config) error
		Stop()
		Start()
		Wait()
	}
}

// NewService creates a new scraper service
func NewService(c []Config, d Diagnostic) *Service {
	s := &Service{
		diag: d,
	}
	s.storeConfigs(c)
	s.mgr = retrieval.NewTargetManager(s, d)
	return s
}

// Open starts the scraper service
func (s *Service) Open() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.open {
		return nil
	}

	s.open = true
	s.updating = make(chan *config.Config)
	s.closing = make(chan struct{})

	go s.scrape()

	s.open = true
	return nil
}

// Close stops the scraper service
func (s *Service) Close() error {
	s.mu.Lock()
	if s.open {
		s.open = false
		s.mu.Unlock()
	} else {
		s.mu.Unlock()
		return nil
	}

	close(s.closing)

	s.wg.Wait()

	return nil
}

func (s *Service) loadConfigs() []Config {
	return s.configs.Load().([]Config)
}

func (s *Service) storeConfigs(c []Config) {
	s.configs.Store(c)
}

func (s *Service) scrape() {
	s.wg.Add(1)
{'fraction_non_alphanumeric': 0.13052631578947368, 'fraction_numerical': 0.0005263157894736842, 'mean_word_length': 3.6297198538367845, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '940320', 'n_tokens_mistral': 1470, 'n_tokens_neox': 1378, 'n_words': 337}