diff options
| -rw-r--r-- | scan_report.go | 2 | ||||
| -rw-r--r-- | service.go | 25 | ||||
| -rw-r--r-- | service_options.go | 25 | ||||
| -rw-r--r-- | service_test.go | 10 | ||||
| -rw-r--r-- | worker_test.go | 19 |
5 files changed, 69 insertions, 12 deletions
diff --git a/scan_report.go b/scan_report.go index 16034de..6544dc7 100644 --- a/scan_report.go +++ b/scan_report.go @@ -7,6 +7,8 @@ import "time" // ScanReport contains the result of scanning service. type ScanReport struct { + Name string + // The time when the scan started. At time.Time @@ -8,6 +8,7 @@ import ( "log" "net" "net/http" + "time" "git.sr.ht/~shulhan/lilin/internal" ) @@ -15,6 +16,7 @@ import ( type Service struct { httpConn *http.Client dialer *net.Dialer + ticker *time.Ticker opts ServiceOptions isReady bool } @@ -35,6 +37,7 @@ func NewService(opts ServiceOptions) (svc *Service, err error) { func (svc *Service) Scan() (report ScanReport) { var err error + report.Name = svc.opts.Name report.At = internal.Now() if !svc.isReady { err = svc.connect() @@ -77,6 +80,28 @@ func (svc *Service) Scan() (report ScanReport) { return report } +// Start scanning periodically and send the report to reportq. +func (svc *Service) Start(reportq chan<- ScanReport) { + svc.ticker = time.NewTicker(svc.opts.interval) + + reportq <- svc.Scan() + + for { + _, ok := <-svc.ticker.C + if !ok { + log.Printf("Service: %s not ok", svc.opts.Name) + return + } + log.Printf(`Scan %s started`, svc.opts.Name) + reportq <- svc.Scan() + } +} + +// Stop the periodic scanning. +func (svc *Service) Stop() { + svc.ticker.Stop() +} + func (svc *Service) connect() (err error) { switch svc.opts.scanURL.Scheme { case serviceKindHTTP, serviceKindHTTPS: diff --git a/service_options.go b/service_options.go index 957987a..fc0da11 100644 --- a/service_options.go +++ b/service_options.go @@ -5,6 +5,7 @@ package lilin import ( "fmt" + "log" "net" "net/http" "net/url" @@ -19,6 +20,9 @@ const ( serviceKindUDP = `udp` ) +// defInterval define default interval in between scanning run. +const defInterval = 1 * time.Minute + type ServiceOptions struct { scanURL *url.URL @@ -37,7 +41,12 @@ type ServiceOptions struct { // Timeout for connecting and reading response from service. Timeout string `ini:"::timeout"` - timeout time.Duration + // Interval between each scan. + // The minimum value is 60 seconds or 1 minute. + Interval string `ini:"::interval"` + + timeout time.Duration + interval time.Duration } func (opts *ServiceOptions) init() (err error) { @@ -85,5 +94,19 @@ func (opts *ServiceOptions) init() (err error) { return fmt.Errorf(`invalid Timeout %s`, opts.Timeout) } } + + if len(opts.Interval) == 0 { + opts.interval = defInterval + } else { + opts.interval, err = time.ParseDuration(opts.Interval) + if err != nil { + return fmt.Errorf(`invalid Interval %s`, opts.Interval) + } + if opts.interval < defInterval { + log.Printf(`%s: interval is less than %s, revert to default`, + opts.Name, defInterval) + opts.interval = defInterval + } + } return nil } diff --git a/service_test.go b/service_test.go index 02285cb..bd58b91 100644 --- a/service_test.go +++ b/service_test.go @@ -11,10 +11,10 @@ import ( "git.sr.ht/~shulhan/pakakeh.go/lib/test" ) -func TestServiceScan_HTTP(t *testing.T) { +func TestServiceStart_HTTP(t *testing.T) { type testCase struct { - opts lilin.ServiceOptions expReport lilin.ScanReport + opts lilin.ServiceOptions } var listCase = []testCase{{ @@ -23,18 +23,22 @@ func TestServiceScan_HTTP(t *testing.T) { Address: `http://` + dummyHTTPAddress + `/health`, }, expReport: lilin.ScanReport{ + Name: `http_service`, At: internal.Now(), Success: true, }, }} + var reportq = make(chan lilin.ScanReport, 1) for _, tcase := range listCase { svc, err := lilin.NewService(tcase.opts) if err != nil { t.Fatal(err) } - var gotReport = svc.Scan() + go svc.Start(reportq) + var gotReport = <-reportq + svc.Stop() test.Assert(t, `Scan`, tcase.expReport, gotReport) } diff --git a/worker_test.go b/worker_test.go index 83fcc69..46e7cd3 100644 --- a/worker_test.go +++ b/worker_test.go @@ -39,6 +39,7 @@ func TestNewWorker(t *testing.T) { Address: `http://127.0.0.1:6121/health`, Timeout: `5s`, timeout: 5 * time.Second, + interval: defInterval, }, }, `example tcp`: &Service{ @@ -47,10 +48,11 @@ func TestNewWorker(t *testing.T) { Scheme: `tcp`, Host: `127.0.0.1:6122`, }, - Name: `example tcp`, - Address: `tcp://127.0.0.1:6122`, - Timeout: `5s`, - timeout: 5 * time.Second, + Name: `example tcp`, + Address: `tcp://127.0.0.1:6122`, + Timeout: `5s`, + timeout: 5 * time.Second, + interval: defInterval, }, }, `example udp`: &Service{ @@ -59,10 +61,11 @@ func TestNewWorker(t *testing.T) { Scheme: `udp`, Host: `127.0.0.1:6123`, }, - Name: `example udp`, - Address: `udp://127.0.0.1:6123`, - Timeout: `5s`, - timeout: 5 * time.Second, + Name: `example udp`, + Address: `udp://127.0.0.1:6123`, + Timeout: `5s`, + timeout: 5 * time.Second, + interval: defInterval, }, }, }, |
