Skip to content

Commit 4ea4861

Browse files
Georgi Dimitrovrichpoirier
Georgi Dimitrov
authored andcommitted
Add a DeferExitHandler function
Useful for running exit handlers in the same order as defer statements
1 parent 7d8d638 commit 4ea4861

File tree

2 files changed

+70
-6
lines changed

2 files changed

+70
-6
lines changed

alt_exit.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ func Exit(code int) {
5151
os.Exit(code)
5252
}
5353

54-
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
55-
// all handlers. The handlers will also be invoked when any Fatal log entry is
56-
// made.
54+
// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
55+
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
56+
// any Fatal log entry is made.
5757
//
5858
// This method is useful when a caller wishes to use logrus to log a fatal
5959
// message but also needs to gracefully shutdown. An example usecase could be
@@ -62,3 +62,15 @@ func Exit(code int) {
6262
func RegisterExitHandler(handler func()) {
6363
handlers = append(handlers, handler)
6464
}
65+
66+
// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
67+
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
68+
// any Fatal log entry is made.
69+
//
70+
// This method is useful when a caller wishes to use logrus to log a fatal
71+
// message but also needs to gracefully shutdown. An example usecase could be
72+
// closing database connections, or sending a alert that the application is
73+
// closing.
74+
func DeferExitHandler(handler func()) {
75+
handlers = append([]func(){handler}, handlers...)
76+
}

alt_exit_test.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,61 @@ import (
1414

1515
func TestRegister(t *testing.T) {
1616
current := len(handlers)
17-
RegisterExitHandler(func() {})
18-
if len(handlers) != current+1 {
19-
t.Fatalf("expected %d handlers, got %d", current+1, len(handlers))
17+
18+
var results []string
19+
20+
h1 := func() { results = append(results, "first") }
21+
h2 := func() { results = append(results, "second") }
22+
23+
RegisterExitHandler(h1)
24+
RegisterExitHandler(h2)
25+
26+
if len(handlers) != current+2 {
27+
t.Fatalf("expected %d handlers, got %d", current+2, len(handlers))
28+
}
29+
30+
runHandlers()
31+
32+
if len(results) != 2 {
33+
t.Fatalf("expected 2 handlers to be run, ran %d", len(results))
34+
}
35+
36+
if results[0] != "first" {
37+
t.Fatal("expected handler h1 to be run first, but it wasn't")
38+
}
39+
40+
if results[1] != "second" {
41+
t.Fatal("expected handler h2 to be run second, but it wasn't")
42+
}
43+
}
44+
45+
func TestDefer(t *testing.T) {
46+
current := len(handlers)
47+
48+
var results []string
49+
50+
h1 := func() { results = append(results, "first") }
51+
h2 := func() { results = append(results, "second") }
52+
53+
DeferExitHandler(h1)
54+
DeferExitHandler(h2)
55+
56+
if len(handlers) != current+2 {
57+
t.Fatalf("expected %d handlers, got %d", current+2, len(handlers))
58+
}
59+
60+
runHandlers()
61+
62+
if len(results) != 2 {
63+
t.Fatalf("expected 2 handlers to be run, ran %d", len(results))
64+
}
65+
66+
if results[0] != "second" {
67+
t.Fatal("expected handler h2 to be run first, but it wasn't")
68+
}
69+
70+
if results[1] != "first" {
71+
t.Fatal("expected handler h1 to be run second, but it wasn't")
2072
}
2173
}
2274

0 commit comments

Comments
 (0)