<commit_before>// Copyright (c) 2014-2019 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"runtime"
	"time"

	"github.com/bitmark-inc/logger"
)

type ConfigReader interface {
	Initialise(string)
	OptimalThreadCount() uint32
	SetCalendar(JobCalendar)
	Refresh() error
	GetConfig() (*Configuration, string, error)
	SetLog(*logger.L) error
	Start()
	FirstTimeRun()
	SetProofer(Proofer)
}

const (
	oneMinute          = time.Duration(1) * time.Minute
	minThreadCount     = 1
	ReaderLoggerPrefix = "config-reader"
)

var (
	totalCPUCount = uint32(runtime.NumCPU())
)

type ConfigReaderData struct {
	fileName             string
	refreshByMinute      time.Duration
	log                  *logger.L
	currentConfiguration *Configuration
	initialized          bool
	threadCount          uint32
	calendar             JobCalendar
	proofer              Proofer
	watcherChannel       WatcherChannel
}

func newConfigReader(ch WatcherChannel) ConfigReader {
	return &ConfigReaderData{
		log:                  nil,
		currentConfiguration: nil,
		threadCount:          1,
		initialized:          false,
		refreshByMinute:      oneMinute,
		watcherChannel:       ch,
	}
}

// configuration needs read first to know logger file location
func (c *ConfigReaderData) Initialise(fileName string) {
	c.fileName = fileName
}

func (c *ConfigReaderData) SetCalendar(calendar JobCalendar) {
	c.calendar = calendar
}

func (c *ConfigReaderData) SetProofer(proofer Proofer) {
	c.proofer = proofer
}

func (c *ConfigReaderData) FirstTimeRun() {
	err := c.Refresh()
	if nil != err {
		return
	}
	c.notify()
}

func (c *ConfigReaderData) Start() {
	go func() {
		for {
			select {
			case <-c.watcherChannel.change:
				c.log.Info("receive file change event, wait for 1 minute to adapt")
				<-time.After(c.refreshByMinute)
				err := c.Refresh()
				if nil != err {
					c.log.Errorf("failed to read configuration from :%s error %s",
						c.fileName, err)
				}
				c.notify()
			case <-c.watcherChannel.remove:
				c.log.Warn("config file removed")
			}
		}

	}()
}

func (c *ConfigReaderData) UpdatePeriodically() {
	c.log.Info("star to update config perioditically")

	go func() {
		for {
			select {
			case <-time.After(c.refreshByMinute):
				err := c.Refresh()
				if nil != err {
					c.log.Errorf("failed to read configuration from :%s error %s",
						c.fileName, err)
				}
				c.notify()
			}
		}
	}()
}

func (c *ConfigReaderData) Refresh() error {
	configuration, err := c.parse()
	if nil != err {
		return err
	}
	c.update(configuration)
	return nil
}

func (c *ConfigReaderData) notify() {
	c.calendar.Refresh(c.currentConfiguration.Calendar)
	c.proofer.Refresh()
}

func (c *ConfigReaderData) parse() (*Configuration, error) {
	configuration, err := getConfiguration(c.fileName)
	if nil != err {
		return nil, err
	}
	return configuration, nil<commit_msg>[recorderd] remove unused method<commit_after>// Copyright (c) 2014-2019 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"runtime"
	"time"

	"github.com/bitmark-inc/logger"
)

type ConfigReader interface {
	Initialise(string)
	OptimalThreadCount() uint32
	SetCalendar(JobCalendar)
	Refresh() error
	GetConfig() (*Configuration, string, error)
	SetLog(*logger.L) error
	Start()
	FirstTimeRun()
	SetProofer(Proofer)
}

const (
	oneMinute          = time.Duration(1) * time.Minute
	minThreadCount     = 1
	ReaderLoggerPrefix = "config-reader"
)

var (
	totalCPUCount = uint32(runtime.NumCPU())
)

type ConfigReaderData struct {
	fileName             string
	refreshByMinute      time.Duration
	log                  *logger.L
	currentConfiguration *Configuration
	initialized          bool
	threadCount          uint32
	calendar             JobCalendar
	proofer              Proofer
	watcherChannel       WatcherChannel
}

func newConfigReader(ch WatcherChannel) ConfigReader {
	return &ConfigReaderData{
		log:                  nil,
		currentConfiguration: nil,
		threadCount:          1,
		initialized:          false,
		refreshByMinute:      oneMinute,
		watcherChannel:       ch,
	}
}

// configuration needs read first to know logger file location
func (c *ConfigReaderData) Initialise(fileName string) {
	c.fileName = fileName
}

func (c *ConfigReaderData) SetCalendar(calendar JobCalendar) {
	c.calendar = calendar
}

func (c *ConfigReaderData) SetProofer(proofer Proofer) {
	c.proofer = proofer
}

func (c *ConfigReaderData) FirstTimeRun() {
	err := c.Refresh()
	if nil != err {
		return
	}
	c.notify()
}

func (c *ConfigReaderData) Start() {
	go func() {
		for {
			select {
			case <-c.watcherChannel.change:
				c.log.Info("receive file change event, wait for 1 minute to adapt")
				<-time.After(c.refreshByMinute)
				err := c.Refresh()
				if nil != err {
					c.log.Errorf("failed to read configuration from :%s error %s",
						c.fileName, err)
				}
				c.notify()
			case <-c.watcherChannel.remove:
				c.log.Warn("config file removed")
			}
		}

	}()
}

func (c *ConfigReaderData) Refresh() error {
	configuration, err := c.parse()
	if nil != err {
		return err
	}
	c.update(configuration)
	return nil
}

func (c *ConfigReaderData) notify() {
	c.calendar.Refresh(c.currentConfiguration.Calendar)
	c.proofer.Refresh()
}

func (c *ConfigReaderData) parse() (*Configuration, error) {
	configuration, err := getConfiguration(c.fileName)
	if nil != err {
		return nil, err
	}
	return configuration, nil
{'fraction_non_alphanumeric': 0.11034980165885323, 'fraction_numerical': 0.006491164803461955, 'mean_word_length': 3.1519461077844313, 'pattern_counts': {'":': 0, '<': 10, '<?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': '800601', 'n_tokens_mistral': 1965, 'n_tokens_neox': 1793, 'n_words': 479}