代码拉取完成,页面将自动刷新
package system
import (
"context"
"os"
"os/signal"
"sync"
"sync/atomic"
"syscall"
"time"
)
var closeCh chan bool
func init() {
var _ = closeCh
closeCh = make(chan bool)
}
type ExitSig struct {
S chan os.Signal
}
func (c *ExitSig) Done() <-chan os.Signal {
return c.S
}
func Exit() *ExitSig {
e := &ExitSig{S: make(chan os.Signal)}
signal.Notify(e.S, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGQUIT)
return e
}
func Closed() <-chan bool {
return closeCh
}
func Close() {
close(closeCh)
}
func AfterQuit(second time.Duration) {
Wait(second)
}
func Wait(second time.Duration) {
timeout := time.After(second)
select {
case <-timeout:
return
}
}
type Running struct {
ev *Event
wg sync.WaitGroup
}
var (
mainRun int32 = 0
running *Running
once sync.Once
)
func Go() *Running {
once.Do(func() {
running = NewRunning()
})
return running
}
// NewRunning
// f 是否fire
func NewRunning() *Running {
return &Running{ev: NewEvent()}
}
func ChildRunning(fn func(), exits ...func()) {
Go().Run(false, fn, exits...)
}
func MainRunning(fn func(), exits ...func()) {
if atomic.AddInt32(&mainRun, 1) > 1 {
panic("can not repeat call,only call one")
}
Go().Run(true, func() {
defer atomic.StoreInt32(&mainRun, 0)
fn()
}, exits...)
}
// Run if fire=true, select Running.Done()
func (m *Running) Run(fire bool, fn func(), exits ...func()) {
m.wg.Add(1)
go func() {
defer m.wg.Done()
defer Recover(exits...)
defer func() {
if !fire {
return
}
m.ev.Fire()
}()
fn()
}()
}
func (m *Running) Done() <-chan struct{} {
return m.ev.Done()
}
func (m *Running) Wait() {
m.wg.Wait()
}
type RunningCheck struct {
rm sync.RWMutex
fRun bool
}
func (rc *RunningCheck) IsRunning() bool {
rc.rm.RLock()
defer rc.rm.RUnlock()
return rc.fRun
}
// Deprecated: this function simply calls [GoRunning].
func (rc *RunningCheck) TryGoRunning(fn func(), exits ...func()) {
rc.GoRunning(fn, exits...)
}
func (rc *RunningCheck) GoRunning(fn func(), exits ...func()) {
rc.GoRunningV2(func() {}, fn, exits...)
}
func (rc *RunningCheck) GoRunningV2(running func(), fn func(), exits ...func()) {
if rc.IsRunning() {
return
}
rc.runningSet(true)
running()
ChildRunning(func() {
defer rc.runningSet(false)
fn()
}, exits...)
}
func (rc *RunningCheck) runningSet(flag bool) {
rc.rm.Lock()
rc.fRun = flag
rc.rm.Unlock()
}
type Task func() (any, error)
type Ctrl struct {
}
func NewCtrl() *Ctrl {
return &Ctrl{}
}
func (c *Ctrl) RunAfter(timeout time.Duration, task Task) (any, error) {
if timeout <= 0 {
return task()
}
resultCh := make(chan *resultWithError, 1)
ChildRunning(func() {
result, err := task()
resultCh <- &resultWithError{result, err}
})
select {
case <-time.After(timeout):
return nil, TimeoutError
case rwe := <-resultCh:
return rwe.result, rwe.err
case <-Closed():
return nil, ClosedError
}
}
func (c *Ctrl) RunWithContext(ctx context.Context, task Task) (any, error) {
resultCh := make(chan *resultWithError, 1)
ChildRunning(func() {
result, err := task()
resultCh <- &resultWithError{result, err}
})
select {
case <-ctx.Done():
return nil, ctx.Err()
case rwe := <-resultCh:
return rwe.result, rwe.err
case <-Closed():
return nil, ClosedError
}
}
// Ticker
// 定时调用
func (c *Ctrl) Ticker(tick time.Duration, fun func(any) bool, param any, funcDefer func(any) bool, paramDefer any) {
c.Delay(0, tick, fun, param, funcDefer, paramDefer)
}
func (c *Ctrl) DelayOnly(delay time.Duration, fun func(any) bool, param any, funcDefer func(any) bool, paramDefer any) {
c.Delay(delay, 0, fun, param, funcDefer, paramDefer)
}
func (c *Ctrl) Delay(delay, tick time.Duration, fun func(any) bool, param any, funcDefer func(any) bool, paramDefer any) {
if fun == nil {
panic("fun is nil")
}
ChildRunning(func() {
defer func() {
if funcDefer != nil {
funcDefer(paramDefer)
}
}()
if delay > 0 {
AfterQuit(delay)
if fun(param) {
return
}
}
if tick <= 0 {
fun(param)
return
}
ticker := time.NewTicker(tick)
for {
select {
case <-ticker.C:
if fun(param) {
return
}
case <-Closed():
return
}
}
})
}
type resultWithError struct {
result any
err error
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。