Skip to content

Commit 12d3f3a

Browse files
authored
Merge pull request #58 from pior/linters
Fix linter errors
2 parents ff0191d + f7e2a4d commit 12d3f3a

8 files changed

Lines changed: 498 additions & 77 deletions

File tree

.golangci.yml

Lines changed: 431 additions & 0 deletions
Large diffs are not rendered by default.

closer_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package runnable
22

33
import (
44
"context"
5-
"errors"
65
"testing"
76
"time"
87

@@ -66,8 +65,8 @@ func Test_Closer_Close_Error(t *testing.T) {
6665

6766
err := CloserErr(closer).Run(ctx)
6867
require.EqualError(t, err, "closer: Close() returned an error: dummy error")
69-
require.IsType(t, &RunnableError{}, err)
70-
require.True(t, errors.Is(err, testErr))
68+
require.ErrorAs(t, err, new(*RunnableError))
69+
require.ErrorIs(t, err, testErr)
7170

7271
require.Equal(t, 1, closer.called)
7372
}
@@ -106,7 +105,7 @@ func Test_CloserCtxErr(t *testing.T) {
106105

107106
err := CloserCtxErr(closer).Run(ctx)
108107
require.EqualError(t, err, "closer: Close() returned an error: close failed")
109-
require.True(t, errors.Is(err, testErr))
108+
require.ErrorIs(t, err, testErr)
110109
require.Equal(t, 1, closer.called)
111110
require.NoError(t, closer.ctxErr, "context passed to Close should not be cancelled")
112111
})

example_test.go

Lines changed: 52 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,89 +4,80 @@ import (
44
"context"
55
"fmt"
66
"log/slog"
7-
"net/http"
87
"os"
98
"time"
109

1110
"github.com/pior/runnable"
1211
)
1312

14-
func NewJobs() *Jobs {
15-
return &Jobs{queue: make(chan string)}
16-
}
17-
18-
type Jobs struct {
19-
queue chan string
20-
}
21-
22-
func (s *Jobs) Perform(id string) {
23-
s.queue <- id
24-
}
25-
26-
// Run executes enqueued jobs, drains the queue and quits.
27-
func (s *Jobs) Run(ctx context.Context) error {
28-
for {
29-
select {
30-
case id := <-s.queue:
31-
fmt.Printf("Starting job %s\n", id)
32-
time.Sleep(time.Second)
33-
fmt.Printf("Completed job %s\n", id)
34-
35-
default:
36-
if err := ctx.Err(); err != nil {
37-
close(s.queue)
38-
return err
13+
// exampleLogger returns a text logger writing to stdout without timestamps,
14+
// suitable for deterministic testable examples.
15+
func exampleLogger() *slog.Logger {
16+
return slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
17+
ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr {
18+
if a.Key == slog.TimeKey {
19+
return slog.Attr{}
3920
}
40-
}
41-
}
21+
return a
22+
},
23+
}))
4224
}
4325

44-
type CleanupTask struct{}
26+
// JobQueue is a long-running service that processes background jobs.
27+
type JobQueue struct{}
4528

46-
func (*CleanupTask) Run(ctx context.Context) error {
29+
func (q *JobQueue) Run(ctx context.Context) error {
4730
<-ctx.Done()
4831
return nil
4932
}
5033

51-
func Example() {
52-
runnable.SetLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))
53-
54-
g := runnable.Manager()
34+
func (q *JobQueue) Enqueue(job string) {
35+
fmt.Println("JobQueue: " + job)
36+
}
5537

56-
jobs := NewJobs()
57-
g.RegisterService(jobs)
38+
// CleanupTask enqueues a cleanup job on each execution.
39+
type CleanupTask struct {
40+
jobs *JobQueue
41+
runs int
42+
done chan struct{}
43+
}
5844

59-
server := &http.Server{
60-
Addr: "127.0.0.1:8080",
61-
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
62-
id := r.URL.Query().Get("id")
63-
jobs.Perform(id)
64-
}),
45+
func (t *CleanupTask) Run(_ context.Context) error {
46+
t.runs++
47+
t.jobs.Enqueue(fmt.Sprintf("cleanup-%d", t.runs))
48+
if t.runs >= 3 {
49+
close(t.done)
6550
}
66-
g.Register(runnable.HTTPServer(server))
51+
return nil
52+
}
6753

68-
task := runnable.Func(func(ctx context.Context) error {
69-
_, _ = http.Post("http://127.0.0.1:8080/?id=1", "test/plain", nil)
70-
_, _ = http.Post("http://127.0.0.1:8080/?id=2", "test/plain", nil)
71-
_, _ = http.Post("http://127.0.0.1:8080/?id=3", "test/plain", nil)
54+
func Example() {
55+
runnable.SetLogger(exampleLogger())
7256

73-
return nil // quit right away, will trigger a shutdown
74-
}).Name("enqueue")
75-
g.Register(task)
57+
jobs := &JobQueue{}
58+
done := make(chan struct{})
59+
cleanup := &CleanupTask{jobs: jobs, done: done}
7660

77-
cleanup := runnable.Schedule(&CleanupTask{}, runnable.Hourly())
78-
g.Register(cleanup)
61+
m := runnable.Manager()
62+
m.RegisterService(jobs)
63+
m.Register(runnable.Schedule(cleanup, runnable.Every(500*time.Millisecond)))
64+
m.Register(runnable.Func(func(_ context.Context) error {
65+
<-done
66+
return nil
67+
}).Name("app"))
7968

80-
runnable.Run(g)
69+
runnable.Run(m)
8170

82-
// level=INFO msg="manager/Jobs: started"
83-
// level=INFO msg="manager/httpserver: started"
84-
// level=INFO msg="manager/enqueue: started"
71+
// Output:
72+
// level=INFO msg="manager/JobQueue: started"
8573
// level=INFO msg="manager/schedule/CleanupTask: started"
86-
// level=INFO msg="httpserver: listening" addr=127.0.0.1:8080
87-
// Starting job 1
88-
// Completed job 1
89-
// ...
90-
// level=INFO msg="manager: starting shutdown" reason="enqueue died"
74+
// level=INFO msg="manager/app: started"
75+
// JobQueue: cleanup-1
76+
// JobQueue: cleanup-2
77+
// JobQueue: cleanup-3
78+
// level=INFO msg="manager/app: stopped"
79+
// level=INFO msg="manager: starting shutdown" reason="app died"
80+
// level=INFO msg="manager/schedule/CleanupTask: stopped"
81+
// level=INFO msg="manager/JobQueue: stopped"
9182
// level=INFO msg="manager: shutdown complete"
9283
}

logger.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ func init() {
88
SetLogger(nil)
99
}
1010

11-
// SetLogger replaces the default logger with a *slog.Logger.
12-
// Passing nil resets to slog.Default().
11+
// SetLogger replaces the default logger with a [*slog.Logger].
12+
// Passing nil resets to [slog.Default].
1313
func SetLogger(l *slog.Logger) {
1414
if l == nil {
1515
l = slog.Default()
1616
}
1717
logger = l
1818
}
19-

recover.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
)
77

88
type PanicError struct {
9-
value interface{}
9+
value any
1010
}
1111

1212
func (e *PanicError) Error() string {

run.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,27 @@ package runnable
22

33
import (
44
"context"
5+
"errors"
56
stdlog "log"
67
)
78

8-
// RunGroup runs all runnables in a Manager, and listen to SIGTERM/SIGINT
9+
// RunGroup runs all runnables in a Manager, and listens to SIGTERM/SIGINT.
910
func RunGroup(runners ...Runnable) {
1011
m := Manager()
1112
m.Register(runners...)
1213
Run(m)
1314
}
1415

15-
// Run runs a single runnable, and listen to SIGTERM/SIGINT
16+
// Run runs a single runnable, and listens to SIGTERM/SIGINT.
1617
func Run(runner Runnable) {
1718
ctx := context.Background()
1819
err := Signal(runner).Run(ctx)
19-
if err != nil && err != context.Canceled {
20+
if err != nil && !errors.Is(err, context.Canceled) {
2021
stdlog.Fatal(err)
2122
}
2223
}
2324

24-
// RunFunc runs a runnable function, and listen to SIGTERM/SIGINT
25+
// RunFunc runs a runnable function, and listens to SIGTERM/SIGINT.
2526
func RunFunc(fn RunnableFunc) {
2627
Run(Func(fn))
2728
}

server.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package runnable
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"net/http"
78
"time"
@@ -65,7 +66,7 @@ func (r *httpServer) Run(ctx context.Context) error {
6566
// Server stopped on its own — no Shutdown needed.
6667
}
6768

68-
if err == http.ErrServerClosed {
69+
if errors.Is(err, http.ErrServerClosed) {
6970
err = nil
7071
}
7172
if err != nil {

server_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ func TestHTTPServer(t *testing.T) {
4444
cancel()
4545

4646
select {
47-
case err := <-errChan:
48-
require.NoError(t, err)
47+
case runErr := <-errChan:
48+
require.NoError(t, runErr)
4949
case <-time.After(5 * time.Second):
5050
t.Fatal("server did not shut down within 5s")
5151
}
@@ -105,7 +105,6 @@ func TestHTTPServer(t *testing.T) {
105105

106106
require.Equal(t, fmt.Sprint(5*time.Second), fmt.Sprint(r.shutdownTimeout))
107107
})
108-
109108
}
110109

111110
func ExampleHTTPServer() {

0 commit comments

Comments
 (0)