You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngs/interface.go

109 lines
2.5 KiB
Go

package ngs
import (
"fmt"
"git.noahlan.cn/northlan/ngs/cluster"
"git.noahlan.cn/northlan/ngs/component"
"git.noahlan.cn/northlan/ngs/internal/env"
"git.noahlan.cn/northlan/ngs/internal/log"
"git.noahlan.cn/northlan/ngs/internal/runtime"
"git.noahlan.cn/northlan/ngs/scheduler"
"os"
"os/signal"
"path/filepath"
"strings"
"sync/atomic"
"syscall"
"time"
)
var running int32
var (
// app represents the current server process
app = &struct {
name string // current application name
startAt time.Time // startup time
}{}
)
// Listen listens on the TCP network address addr
// and then calls Serve with handler to handle requests
// on incoming connections.
func Listen(addr string, opts ...Option) {
if atomic.AddInt32(&running, 1) != 1 {
log.Println("Ngs has running")
return
}
// application initialize
app.name = strings.TrimLeft(filepath.Base(os.Args[0]), "/")
app.startAt = time.Now()
// environment initialize
if wd, err := os.Getwd(); err != nil {
panic(err)
} else {
env.Wd, _ = filepath.Abs(wd)
}
opt := cluster.Options{
Components: &component.Components{},
}
for _, option := range opts {
option(&opt)
}
// Use listen address as client address in non-cluster mode
if !opt.IsMaster && opt.AdvertiseAddr == "" && opt.ClientAddr == "" {
log.Println("The current server running in singleton mode")
opt.ClientAddr = addr
}
// Set the retry interval to 3 secondes if doesn't set by user
if opt.RetryInterval == 0 {
opt.RetryInterval = time.Second * 3
}
node := &cluster.Node{
Options: opt,
ServiceAddr: addr,
}
err := node.Startup()
if err != nil {
log.Fatalf("Node startup failed: %v", err)
}
runtime.CurrentNode = node
if node.ClientAddr != "" {
log.Println(fmt.Sprintf("Startup *Ngs gate server* %s, client address: %v, service address: %s",
app.name, node.ClientAddr, node.ServiceAddr))
} else {
log.Println(fmt.Sprintf("Startup *Ngs backend server* %s, service address %s",
app.name, node.ServiceAddr))
}
go scheduler.Schedule()
sg := make(chan os.Signal)
signal.Notify(sg, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM)
select {
case <-env.Die:
log.Println("The app will shutdown in a few seconds")
case s := <-sg:
log.Println("Ngs server got signal", s)
}
log.Println("Ngs server is stopping...")
node.Shutdown()
runtime.CurrentNode = nil
scheduler.Close()
atomic.StoreInt32(&running, 0)
}
// Shutdown send a signal to let 'ngs' shutdown itself.
func Shutdown() {
close(env.Die)
}