加入等待继电器释放,加入程序停止执行时释放所有资源
This commit is contained in:
@@ -11,7 +11,7 @@ log:
|
|||||||
maxAge: 30
|
maxAge: 30
|
||||||
compress: true
|
compress: true
|
||||||
mqtt:
|
mqtt:
|
||||||
url: mqtt://58.144.199.46:1883
|
url: mqtt://wushan-mqtt.chaoshengshuzi.com:1883
|
||||||
aliyun:
|
aliyun:
|
||||||
accessKeyID:
|
accessKeyID:
|
||||||
accessKeySecret:
|
accessKeySecret:
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ func Run() {
|
|||||||
if config.C.Relay != "" {
|
if config.C.Relay != "" {
|
||||||
r, err = relay.New(config.C.Relay)
|
r, err = relay.New(config.C.Relay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Panicln("继电器连接异常: ", err)
|
zap.S().Errorln("继电器连接异常: ", err)
|
||||||
}
|
}
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
}
|
}
|
||||||
@@ -179,6 +179,9 @@ func Run() {
|
|||||||
if e := cm.Disconnect(ctx); e != nil {
|
if e := cm.Disconnect(ctx); e != nil {
|
||||||
zap.S().Errorln("断开连接异常", e)
|
zap.S().Errorln("断开连接异常", e)
|
||||||
}
|
}
|
||||||
|
if e := router.Disconnect(ctx); e != nil {
|
||||||
|
zap.S().Errorln("停止所以任务超时", e)
|
||||||
|
}
|
||||||
|
|
||||||
zap.S().Infoln("关闭完成")
|
zap.S().Infoln("关闭完成")
|
||||||
}
|
}
|
||||||
|
|||||||
46
leaf/leaf.go
46
leaf/leaf.go
@@ -34,8 +34,13 @@ func (c HandlersChain) Last() HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
ctx context.Context
|
queueWg sync.WaitGroup
|
||||||
|
|
||||||
|
ctx context.Context
|
||||||
|
cancelCtx context.CancelFunc
|
||||||
|
done chan struct{}
|
||||||
|
|
||||||
Handlers HandlersChain
|
Handlers HandlersChain
|
||||||
defaultHandler HandlersChain
|
defaultHandler HandlersChain
|
||||||
subscriptions map[string]HandlersChain
|
subscriptions map[string]HandlersChain
|
||||||
@@ -44,8 +49,11 @@ type Engine struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context) *Engine {
|
func New(ctx context.Context) *Engine {
|
||||||
|
c, cancel := context.WithCancel(ctx)
|
||||||
return &Engine{
|
return &Engine{
|
||||||
ctx: ctx,
|
ctx: c,
|
||||||
|
cancelCtx: cancel,
|
||||||
|
done: make(chan struct{}),
|
||||||
Handlers: make(HandlersChain, 0),
|
Handlers: make(HandlersChain, 0),
|
||||||
subscriptions: make(map[string]HandlersChain),
|
subscriptions: make(map[string]HandlersChain),
|
||||||
aliases: make(map[uint16]string),
|
aliases: make(map[uint16]string),
|
||||||
@@ -54,8 +62,11 @@ func New(ctx context.Context) *Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Default(ctx context.Context) *Engine {
|
func Default(ctx context.Context) *Engine {
|
||||||
|
c, cancel := context.WithCancel(ctx)
|
||||||
engine := &Engine{
|
engine := &Engine{
|
||||||
ctx: ctx,
|
ctx: c,
|
||||||
|
cancelCtx: cancel,
|
||||||
|
done: make(chan struct{}),
|
||||||
Handlers: make(HandlersChain, 0),
|
Handlers: make(HandlersChain, 0),
|
||||||
subscriptions: make(map[string]HandlersChain),
|
subscriptions: make(map[string]HandlersChain),
|
||||||
aliases: make(map[uint16]string),
|
aliases: make(map[uint16]string),
|
||||||
@@ -108,13 +119,21 @@ func (e *Engine) Route(pb *packets.Publish) {
|
|||||||
for route, handlers := range e.subscriptions {
|
for route, handlers := range e.subscriptions {
|
||||||
if match(route, topic) {
|
if match(route, topic) {
|
||||||
e.debug.Println("found handler for:", route)
|
e.debug.Println("found handler for:", route)
|
||||||
go WithLeafContext(e.ctx, m, e, handlers).Next()
|
e.queueWg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer e.queueWg.Done()
|
||||||
|
WithLeafContext(e.ctx, m, e, handlers).Next()
|
||||||
|
}()
|
||||||
handlerCalled = true
|
handlerCalled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !handlerCalled && e.defaultHandler != nil {
|
if !handlerCalled && e.defaultHandler != nil {
|
||||||
go WithLeafContext(e.ctx, m, e, e.defaultHandler).Next()
|
e.queueWg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer e.queueWg.Done()
|
||||||
|
WithLeafContext(e.ctx, m, e, e.defaultHandler).Next()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +153,21 @@ func (e *Engine) DefaultHandler(h HandlerFunc) {
|
|||||||
e.defaultHandler = e.combineHandlers(HandlersChain{h})
|
e.defaultHandler = e.combineHandlers(HandlersChain{h})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Engine) Disconnect(ctx context.Context) error {
|
||||||
|
go func() {
|
||||||
|
e.queueWg.Wait()
|
||||||
|
close(e.done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
e.cancelCtx()
|
||||||
|
select {
|
||||||
|
case <-e.done: // wait for goroutine to exit
|
||||||
|
return nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Engine) combineHandlers(handlers HandlersChain) HandlersChain {
|
func (e *Engine) combineHandlers(handlers HandlersChain) HandlersChain {
|
||||||
finalSize := len(e.Handlers) + len(handlers)
|
finalSize := len(e.Handlers) + len(handlers)
|
||||||
assert1(finalSize < int(abortIndex), "too many handlers")
|
assert1(finalSize < int(abortIndex), "too many handlers")
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func InitProLogger(cls *TenCls) {
|
|||||||
cn := zapcore.NewJSONEncoder(nc)
|
cn := zapcore.NewJSONEncoder(nc)
|
||||||
|
|
||||||
// 多个输出
|
// 多个输出
|
||||||
mws := zapcore.NewMultiWriteSyncer(zapcore.AddSync(cls), zapcore.AddSync(os.Stdout))
|
mws := zapcore.NewMultiWriteSyncer(zapcore.AddSync(cls), zapcore.AddSync(config.C.Log.File), zapcore.AddSync(os.Stdout))
|
||||||
|
|
||||||
// 核心配置
|
// 核心配置
|
||||||
core := zapcore.NewCore(cn, mws, level)
|
core := zapcore.NewCore(cn, mws, level)
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package relay
|
package relay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"github.com/grid-x/modbus"
|
"github.com/grid-x/modbus"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Relay interface {
|
type Relay interface {
|
||||||
@@ -56,6 +62,29 @@ func (r *device) Off(num int) error {
|
|||||||
func New(address string) (Relay, error) {
|
func New(address string) (Relay, error) {
|
||||||
zap.S().Infoln("连接继电器: ", address)
|
zap.S().Infoln("连接继电器: ", address)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
a := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(a)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
zap.S().Infoln("等待继电器资源释放超时:", address)
|
||||||
|
return
|
||||||
|
case <-time.After(3 * time.Second):
|
||||||
|
_, err := os.OpenFile(address, os.O_RDWR, 0666)
|
||||||
|
var e *fs.PathError
|
||||||
|
if errors.As(err, &e) && strings.Contains(e.Error(), "busy") {
|
||||||
|
zap.S().Infoln("等待继电器资源释放:", address)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
<-a
|
||||||
|
|
||||||
h := modbus.NewRTUClientHandler(address)
|
h := modbus.NewRTUClientHandler(address)
|
||||||
h.SlaveID = 1
|
h.SlaveID = 1
|
||||||
h.BaudRate = 9600
|
h.BaudRate = 9600
|
||||||
|
|||||||
Reference in New Issue
Block a user