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.
-
+
# 🔋 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)*** 正版免费授权,在此表达我的谢意。
-
+
# 🔋 赞助商
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)
}