Skip to content

Commit e0d3f67

Browse files
authored
Merge pull request #500 from blinklabs-io/feat/conn-manager-notify-close
feat: connection manager notify on conn close with no error
2 parents e3d0912 + ab6e4cd commit e0d3f67

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

connection_manager.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ package ouroboros
1616

1717
import "sync"
1818

19-
// ConnectionManagerErrorFunc is a function that takes a connection ID and an error
20-
type ConnectionManagerErrorFunc func(int, error)
19+
// ConnectionManagerConnClosedFunc is a function that takes a connection ID and an optional error
20+
type ConnectionManagerConnClosedFunc func(int, error)
2121

2222
// ConnectionManagerTag represents the various tags that can be associated with a host or connection
2323
type ConnectionManagerTag uint16
@@ -62,7 +62,7 @@ type ConnectionManager struct {
6262
}
6363

6464
type ConnectionManagerConfig struct {
65-
ErrorFunc ConnectionManagerErrorFunc
65+
ConnClosedFunc ConnectionManagerConnClosedFunc
6666
}
6767

6868
type ConnectionManagerHost struct {
@@ -117,13 +117,9 @@ func (c *ConnectionManager) AddConnection(connId int, conn *Connection) {
117117
}
118118
c.connectionsMutex.Unlock()
119119
go func() {
120-
err, ok := <-conn.ErrorChan()
121-
if !ok {
122-
// Connection has closed normally
123-
return
124-
}
125-
// Call configured error callback func
126-
c.config.ErrorFunc(connId, err)
120+
err := <-conn.ErrorChan()
121+
// Call configured connection closed callback func
122+
c.config.ConnClosedFunc(connId, err)
127123
}()
128124
}
129125

connection_manager_test.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestConnectionManagerConnError(t *testing.T) {
5151
doneChan := make(chan any)
5252
connManager := ouroboros.NewConnectionManager(
5353
ouroboros.ConnectionManagerConfig{
54-
ErrorFunc: func(connId int, err error) {
54+
ConnClosedFunc: func(connId int, err error) {
5555
if connId != expectedConnId {
5656
t.Fatalf("did not receive error from expected connection: got %d, wanted %d", connId, expectedConnId)
5757
}
@@ -96,3 +96,50 @@ func TestConnectionManagerConnError(t *testing.T) {
9696
t.Fatalf("did not receive error within timeout")
9797
}
9898
}
99+
100+
func TestConnectionManagerConnClosed(t *testing.T) {
101+
expectedConnId := 42
102+
doneChan := make(chan any)
103+
connManager := ouroboros.NewConnectionManager(
104+
ouroboros.ConnectionManagerConfig{
105+
ConnClosedFunc: func(connId int, err error) {
106+
if connId != expectedConnId {
107+
t.Fatalf("did not receive closed signal from expected connection: got %d, wanted %d", connId, expectedConnId)
108+
}
109+
if err != nil {
110+
t.Fatalf("received unexpected error: %s", err)
111+
}
112+
close(doneChan)
113+
},
114+
},
115+
)
116+
mockConn := ouroboros_mock.NewConnection(
117+
ouroboros_mock.ProtocolRoleClient,
118+
[]ouroboros_mock.ConversationEntry{
119+
ouroboros_mock.ConversationEntryHandshakeRequestGeneric,
120+
ouroboros_mock.ConversationEntryHandshakeNtNResponse,
121+
},
122+
)
123+
oConn, err := ouroboros.New(
124+
ouroboros.WithConnection(mockConn),
125+
ouroboros.WithNetworkMagic(ouroboros_mock.MockNetworkMagic),
126+
ouroboros.WithNodeToNode(true),
127+
ouroboros.WithKeepAlive(false),
128+
)
129+
if err != nil {
130+
t.Fatalf("unexpected error when creating Ouroboros object: %s", err)
131+
}
132+
connManager.AddConnection(expectedConnId, oConn)
133+
time.AfterFunc(
134+
1*time.Second,
135+
func() {
136+
oConn.Close()
137+
},
138+
)
139+
select {
140+
case <-doneChan:
141+
return
142+
case <-time.After(10 * time.Second):
143+
t.Fatalf("did not receive error within timeout")
144+
}
145+
}

0 commit comments

Comments
 (0)