diff options
| author | Shulhan <ms@kilabit.info> | 2025-07-31 00:31:28 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2025-07-31 19:17:47 +0700 |
| commit | 9998582575aa02dbd2206497953f207af1f117d2 (patch) | |
| tree | d0735fccd6c6c36140a47f36533d8ced50ad217e | |
| parent | b6fec02b55a4227b6ecb47c2bc40a5a025af2b8a (diff) | |
| download | lilin-9998582575aa02dbd2206497953f207af1f117d2.tar.xz | |
all: implement Start and Stop methods on the Service
The Start method start the scanning periodically and send the report
to channel reportq.
The Stop method stop the periodic scanning.
This changes introduces new option Interval in the Service that define
the time interval between each scan.
| -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, }, }, }, |
