mirror of
https://github.com/nxshock/gron.git
synced 2024-11-27 03:41:00 +05:00
Add basic Windows service support
This commit is contained in:
parent
afa9f9bc98
commit
a27dfd4b25
@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
programName = "gron"
|
||||||
|
|
||||||
defaultConfigFileName = "gron.conf"
|
defaultConfigFileName = "gron.conf"
|
||||||
|
|
||||||
defaultOnSuccessMessageFmt = "Job {{.JobName}} finished."
|
defaultOnSuccessMessageFmt = "Job {{.JobName}} finished."
|
||||||
|
1
go.mod
1
go.mod
@ -22,6 +22,7 @@ require (
|
|||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
||||||
|
github.com/kardianos/service v1.2.2
|
||||||
github.com/kr/pretty v0.3.0 // indirect
|
github.com/kr/pretty v0.3.0 // indirect
|
||||||
github.com/lib/pq v1.10.6 // indirect
|
github.com/lib/pq v1.10.6 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
3
go.sum
3
go.sum
@ -27,6 +27,8 @@ github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGU
|
|||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
|
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
|
||||||
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||||
|
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
|
||||||
|
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
@ -71,6 +73,7 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ func handler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
globalMutex.RLock()
|
globalMutex.RLock()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
jobEntries := c.Entries()
|
jobEntries := kernel.c.Entries()
|
||||||
|
|
||||||
jobs := make(map[string][]*Job)
|
jobs := make(map[string][]*Job)
|
||||||
for _, jobEntry := range jobEntries {
|
for _, jobEntry := range jobEntries {
|
||||||
@ -81,7 +80,7 @@ func handleForceStart(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jobEntries := c.Entries()
|
jobEntries := kernel.c.Entries()
|
||||||
|
|
||||||
for _, jobEntry := range jobEntries {
|
for _, jobEntry := range jobEntries {
|
||||||
job := jobEntry.Job.(*Job)
|
job := jobEntry.Job.(*Job)
|
||||||
@ -108,7 +107,7 @@ func handleShutdown(w http.ResponseWriter, r *http.Request) {
|
|||||||
go func() {
|
go func() {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
log.WithField("job", "http_server").Infoln("Shutdown requested")
|
log.WithField("job", "http_server").Infoln("Shutdown requested")
|
||||||
os.Exit(0)
|
_ = kernel.Stop(nil)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,10 +115,10 @@ func handleReloadJobs(w http.ResponseWriter, r *http.Request) {
|
|||||||
globalMutex.Lock()
|
globalMutex.Lock()
|
||||||
defer globalMutex.Unlock()
|
defer globalMutex.Unlock()
|
||||||
|
|
||||||
c.Stop()
|
kernel.c.Stop()
|
||||||
|
|
||||||
for _, entry := range c.Entries() {
|
for _, entry := range kernel.c.Entries() {
|
||||||
c.Remove(entry.ID)
|
kernel.c.Remove(entry.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := initJobs()
|
err := initJobs()
|
||||||
@ -128,7 +127,7 @@ func handleReloadJobs(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Start()
|
kernel.c.Start()
|
||||||
|
|
||||||
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
@ -140,7 +139,7 @@ func handleDetails(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jobEntries := c.Entries()
|
jobEntries := kernel.c.Entries()
|
||||||
|
|
||||||
for _, jobEntry := range jobEntries {
|
for _, jobEntry := range jobEntries {
|
||||||
job := jobEntry.Job.(*Job)
|
job := jobEntry.Job.(*Job)
|
||||||
|
57
kernel.go
Normal file
57
kernel.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kardianos/service"
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Kernel struct {
|
||||||
|
// windows service data
|
||||||
|
svcConfig *service.Config
|
||||||
|
|
||||||
|
// Other data
|
||||||
|
c *cron.Cron
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKernel() *Kernel {
|
||||||
|
svcConfig := &service.Config{
|
||||||
|
Name: "gron",
|
||||||
|
DisplayName: "Gron Job Scheduler",
|
||||||
|
Description: "Gron Job Scheduler.",
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel = &Kernel{
|
||||||
|
svcConfig: svcConfig,
|
||||||
|
c: cron.New()}
|
||||||
|
|
||||||
|
return kernel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *Kernel) Start(s service.Service) error {
|
||||||
|
go func() {
|
||||||
|
log.WithField("job", "core").Info("Started.")
|
||||||
|
|
||||||
|
err := initJobs()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel.c.Start()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *Kernel) Stop(s service.Service) error {
|
||||||
|
log.Info("Got stop signal.")
|
||||||
|
|
||||||
|
err := mainLogFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var kernel *Kernel
|
47
main.go
47
main.go
@ -3,17 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
formatter "github.com/antonfisher/nested-logrus-formatter"
|
formatter "github.com/antonfisher/nested-logrus-formatter"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/kardianos/service"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var c *cron.Cron
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
err := initConfig()
|
err := initConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -36,16 +32,12 @@ func init() {
|
|||||||
NoColors: true,
|
NoColors: true,
|
||||||
TrimMessages: true})
|
TrimMessages: true})
|
||||||
|
|
||||||
multiWriter := io.MultiWriter(os.Stderr, mainLogFile)
|
log.SetOutput(io.MultiWriter(os.Stderr, mainLogFile))
|
||||||
log.SetOutput(multiWriter)
|
|
||||||
|
|
||||||
log.SetLevel(log.InfoLevel)
|
log.SetLevel(log.InfoLevel)
|
||||||
|
|
||||||
initTemplate()
|
initTemplate()
|
||||||
|
|
||||||
go httpServer(config.HttpListenAddr)
|
go httpServer(config.HttpListenAddr)
|
||||||
|
|
||||||
c = cron.New()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initJobs() error {
|
func initJobs() error {
|
||||||
@ -66,7 +58,7 @@ func initJobs() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.AddJob(job.JobConfig.Cron, job)
|
_, err = kernel.c.AddJob(job.JobConfig.Cron, job)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -78,35 +70,30 @@ func initJobs() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.Entries()) == 0 {
|
if len(kernel.c.Entries()) == 0 {
|
||||||
log.Warn("No jobs loaded.")
|
log.Warn("No jobs loaded.")
|
||||||
} else {
|
} else {
|
||||||
log.Infof("Loaded jobs count: %d", len(c.Entries()))
|
log.Infof("Loaded jobs count: %d", len(kernel.c.Entries()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log := log.WithField("job", "core")
|
kernel = NewKernel()
|
||||||
|
|
||||||
log.Info("Started.")
|
s, err := service.New(kernel, kernel.svcConfig)
|
||||||
|
|
||||||
err := initJobs()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Start()
|
|
||||||
|
|
||||||
intChan := make(chan os.Signal)
|
|
||||||
signal.Notify(intChan, syscall.SIGTERM)
|
|
||||||
<-intChan
|
|
||||||
|
|
||||||
log.Info("Got stop signal.")
|
|
||||||
|
|
||||||
err = mainLogFile.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger, err := s.Logger(nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Run()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user