diff --git a/.github/workflows/gh-translator.yml b/.github/workflows/gh-translator.yml index c3a0f6d92..60bfe048a 100644 --- a/.github/workflows/gh-translator.yml +++ b/.github/workflows/gh-translator.yml @@ -20,4 +20,4 @@ jobs: with: BOT_GITHUB_TOKEN: ${{ secrets.GH_TRANSLATOR_TOKEN }} IS_MODIFY_TITLE: true - CUSTOM_BOT_NOTE: 🤖 Non-English text detected, translating... + CUSTOM_BOT_NOTE: 🤖 Non-English text detected, translating ... diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml new file mode 100644 index 000000000..762a5b316 --- /dev/null +++ b/.github/workflows/stale-bot.yml @@ -0,0 +1,48 @@ +name: Monitor inactive issues and PRs +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + stale-issues: + runs-on: ubuntu-latest + permissions: + actions: write + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + operations-per-run: 100 + days-before-issue-stale: 30 + days-before-issue-close: 7 + stale-issue-label: 'stale' + stale-issue-message: | + This issue is marked as stale because it has been open for 30 days with no activity. + + You should take one of the following actions: + - Manually close this issue if it is no longer relevant + - Comment if you have more information to share + + This issue will be automatically closed in 7 days if no further activity occurs. + close-issue-message: | + This issue was closed because it has been inactive for 7 days since being marked as stale. + + If you believe this is a false alarm, please leave a comment for it or open a new issue, you can also reopen this issue directly if you have permission. + days-before-pr-stale: 21 + days-before-pr-close: 7 + stale-pr-label: 'stale' + stale-pr-message: | + This PR is marked as stale because it has been open for 21 days with no activity. + + You should take one of the following actions: + - Manually close this PR if it is no longer relevant + - Push new commits or comment if you have more information to share + + This PR will be automatically closed in 7 days if no further activity occurs. + close-pr-message: | + This PR was closed because it has been inactive for 7 days since being marked as stale. + + If you believe this is a false alarm, feel free to reopen this PR or create a new one. + repo-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index 8c85967b3..fd9b0f4d9 100644 --- a/README.md +++ b/README.md @@ -246,9 +246,9 @@ Become a bronze sponsor with a monthly donation of $10 and get your logo on our # 🔑 JetBrains OS licenses -`gnet` had been being developed with `GoLand` IDE under the **free JetBrains Open Source license(s)** granted by JetBrains s.r.o., hence I would like to express my thanks here. +`gnet` has been being developed with `GoLand` IDE under the ***free JetBrains Open Source license(s)*** granted by JetBrains s.r.o., hence I would like to express my thanks here. - +JetBrains logo. # 🔋 Sponsorship diff --git a/README_ZH.md b/README_ZH.md index d166d1b76..04fae4bee 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -246,9 +246,9 @@ Test duration : 15s # 🔑 JetBrains 开源证书支持 -`gnet` 项目一直以来都是在 JetBrains 公司旗下的 GoLand 集成开发环境中进行开发,基于 **free JetBrains Open Source license(s)** 正版免费授权,在此表达我的谢意。 +`gnet` 项目一直以来都是在 JetBrains 公司旗下的 GoLand 集成开发环境中进行开发,基于 ***free JetBrains Open Source license(s)*** 正版免费授权,在此表达我的谢意。 - +JetBrains logo. # 🔋 赞助商 diff --git a/acceptor_windows.go b/acceptor_windows.go index ce6005c0e..d9d6339cd 100644 --- a/acceptor_windows.go +++ b/acceptor_windows.go @@ -39,11 +39,7 @@ func (eng *engine) listenStream(ln net.Listener) (err error) { if atomic.LoadInt32(&eng.beingShutdown) == 0 { eng.opts.Logger.Errorf("Accept() fails due to error: %v", err) } else if errors.Is(err, net.ErrClosed) { - err = errorx.ErrEngineShutdown - // TODO: errors.Join() is not supported until Go 1.20, - // we will uncomment this line after we bump up the - // minimal supported go version to 1.20. - // err = errors.Join(err, errorx.ErrEngineShutdown) + err = errors.Join(err, errorx.ErrEngineShutdown) } return } @@ -81,9 +77,7 @@ func (eng *engine) ListenUDP(pc net.PacketConn) (err error) { if atomic.LoadInt32(&eng.beingShutdown) == 0 { eng.opts.Logger.Errorf("failed to receive data from UDP fd due to error:%v", err) } else if errors.Is(err, net.ErrClosed) { - err = errorx.ErrEngineShutdown - // TODO: ditto. - // err = errors.Join(err, errorx.ErrEngineShutdown) + err = errors.Join(err, errorx.ErrEngineShutdown) } return } diff --git a/engine_unix.go b/engine_unix.go index 83a1ae864..3bc488f95 100644 --- a/engine_unix.go +++ b/engine_unix.go @@ -19,6 +19,7 @@ package gnet import ( "context" + "errors" "runtime" "strings" "sync" @@ -29,7 +30,7 @@ import ( "github.com/panjf2000/gnet/v2/internal/gfd" "github.com/panjf2000/gnet/v2/internal/netpoll" "github.com/panjf2000/gnet/v2/internal/queue" - "github.com/panjf2000/gnet/v2/pkg/errors" + errorx "github.com/panjf2000/gnet/v2/pkg/errors" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -59,7 +60,7 @@ func (eng *engine) isInShutdown() bool { // shutdown signals the engine to shut down. func (eng *engine) shutdown(err error) { - if err != nil && err != errors.ErrEngineShutdown { + if err != nil && !errors.Is(err, errorx.ErrEngineShutdown) { eng.opts.Logger.Errorf("engine is being shutdown with error: %v", err) } @@ -211,14 +212,14 @@ func (eng *engine) stop(s Engine) { // Notify all event-loops to exit. eng.eventLoops.iterate(func(i int, el *eventloop) bool { - err := el.poller.Trigger(queue.HighPriority, func(_ interface{}) error { return errors.ErrEngineShutdown }, nil) + err := el.poller.Trigger(queue.HighPriority, func(_ interface{}) error { return errorx.ErrEngineShutdown }, nil) if err != nil { eng.opts.Logger.Errorf("failed to enqueue shutdown signal of high-priority for event-loop(%d): %v", i, err) } return true }) if eng.ingress != nil { - err := eng.ingress.poller.Trigger(queue.HighPriority, func(_ interface{}) error { return errors.ErrEngineShutdown }, nil) + err := eng.ingress.poller.Trigger(queue.HighPriority, func(_ interface{}) error { return errorx.ErrEngineShutdown }, nil) if err != nil { eng.opts.Logger.Errorf("failed to enqueue shutdown signal of high-priority for main event-loop: %v", err) } diff --git a/internal/netpoll/poller_epoll_default.go b/internal/netpoll/poller_epoll_default.go index d5e4d4e48..ec47d0b46 100644 --- a/internal/netpoll/poller_epoll_default.go +++ b/internal/netpoll/poller_epoll_default.go @@ -19,6 +19,7 @@ package netpoll import ( + "errors" "os" "runtime" "sync/atomic" @@ -27,7 +28,7 @@ import ( "golang.org/x/sys/unix" "github.com/panjf2000/gnet/v2/internal/queue" - "github.com/panjf2000/gnet/v2/pkg/errors" + errorx "github.com/panjf2000/gnet/v2/pkg/errors" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -133,12 +134,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { if fd := int(ev.Fd); fd == p.efd { // poller is awakened to run tasks in queues. doChores = true } else { - switch err = callback(fd, ev.Events, 0); err { - case nil: - case errors.ErrAcceptSocket, errors.ErrEngineShutdown: + err = callback(fd, ev.Events, 0) + if errors.Is(err, errorx.ErrAcceptSocket) || errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in event-loop: %v", err) } } } @@ -147,12 +145,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { doChores = false task := p.urgentAsyncTaskQueue.Dequeue() for ; task != nil; task = p.urgentAsyncTaskQueue.Dequeue() { - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } @@ -160,12 +155,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { if task = p.asyncTaskQueue.Dequeue(); task == nil { break } - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } diff --git a/internal/netpoll/poller_epoll_ultimate.go b/internal/netpoll/poller_epoll_ultimate.go index fec70097e..730e0485b 100644 --- a/internal/netpoll/poller_epoll_ultimate.go +++ b/internal/netpoll/poller_epoll_ultimate.go @@ -18,6 +18,7 @@ package netpoll import ( + "errors" "os" "runtime" "sync/atomic" @@ -26,7 +27,7 @@ import ( "golang.org/x/sys/unix" "github.com/panjf2000/gnet/v2/internal/queue" - "github.com/panjf2000/gnet/v2/pkg/errors" + errorx "github.com/panjf2000/gnet/v2/pkg/errors" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -135,12 +136,9 @@ func (p *Poller) Polling() error { if pollAttachment.FD == p.epa.FD { // poller is awakened to run tasks in queues. doChores = true } else { - switch err = pollAttachment.Callback(pollAttachment.FD, ev.events, 0); err { - case nil: - case errors.ErrAcceptSocket, errors.ErrEngineShutdown: + err = pollAttachment.Callback(pollAttachment.FD, ev.events, 0) + if errors.Is(err, errorx.ErrAcceptSocket) || errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in event-loop: %v", err) } } } @@ -149,12 +147,9 @@ func (p *Poller) Polling() error { doChores = false task := p.urgentAsyncTaskQueue.Dequeue() for ; task != nil; task = p.urgentAsyncTaskQueue.Dequeue() { - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } @@ -162,12 +157,9 @@ func (p *Poller) Polling() error { if task = p.asyncTaskQueue.Dequeue(); task == nil { break } - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } diff --git a/internal/netpoll/poller_kqueue_default.go b/internal/netpoll/poller_kqueue_default.go index c44be9027..4fbcd8e60 100644 --- a/internal/netpoll/poller_kqueue_default.go +++ b/internal/netpoll/poller_kqueue_default.go @@ -19,6 +19,7 @@ package netpoll import ( + "errors" "os" "runtime" "sync/atomic" @@ -26,7 +27,7 @@ import ( "golang.org/x/sys/unix" "github.com/panjf2000/gnet/v2/internal/queue" - "github.com/panjf2000/gnet/v2/pkg/errors" + errorx "github.com/panjf2000/gnet/v2/pkg/errors" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -118,12 +119,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { doChores = true p.drainWakeupEvent() } else { - switch err = callback(fd, ev.Filter, ev.Flags); err { - case nil: - case errors.ErrAcceptSocket, errors.ErrEngineShutdown: + err = callback(fd, ev.Filter, ev.Flags) + if errors.Is(err, errorx.ErrAcceptSocket) || errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in event-loop: %v", err) } } } @@ -132,12 +130,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { doChores = false task := p.urgentAsyncTaskQueue.Dequeue() for ; task != nil; task = p.urgentAsyncTaskQueue.Dequeue() { - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } @@ -145,12 +140,9 @@ func (p *Poller) Polling(callback PollEventHandler) error { if task = p.asyncTaskQueue.Dequeue(); task == nil { break } - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } diff --git a/internal/netpoll/poller_kqueue_ultimate.go b/internal/netpoll/poller_kqueue_ultimate.go index fc50c6521..e12caf0c1 100644 --- a/internal/netpoll/poller_kqueue_ultimate.go +++ b/internal/netpoll/poller_kqueue_ultimate.go @@ -19,6 +19,7 @@ package netpoll import ( + "errors" "os" "runtime" "sync/atomic" @@ -27,7 +28,7 @@ import ( "golang.org/x/sys/unix" "github.com/panjf2000/gnet/v2/internal/queue" - "github.com/panjf2000/gnet/v2/pkg/errors" + errorx "github.com/panjf2000/gnet/v2/pkg/errors" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -120,12 +121,9 @@ func (p *Poller) Polling() error { p.drainWakeupEvent() } else { pollAttachment := restorePollAttachment(unsafe.Pointer(&ev.Udata)) - switch err = pollAttachment.Callback(int(ev.Ident), ev.Filter, ev.Flags); err { - case nil: - case errors.ErrAcceptSocket, errors.ErrEngineShutdown: + err = pollAttachment.Callback(int(ev.Ident), ev.Filter, ev.Flags) + if errors.Is(err, errorx.ErrAcceptSocket) || errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in event-loop: %v", err) } } } @@ -134,12 +132,9 @@ func (p *Poller) Polling() error { doChores = false task := p.urgentAsyncTaskQueue.Dequeue() for ; task != nil; task = p.urgentAsyncTaskQueue.Dequeue() { - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) } @@ -147,12 +142,9 @@ func (p *Poller) Polling() error { if task = p.asyncTaskQueue.Dequeue(); task == nil { break } - switch err = task.Run(task.Arg); err { - case nil: - case errors.ErrEngineShutdown: + err = task.Run(task.Arg) + if errors.Is(err, errorx.ErrEngineShutdown) { return err - default: - logging.Warnf("error occurs in user-defined function, %v", err) } queue.PutTask(task) }