@@ -2,10 +2,12 @@ package immortalstreams
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"io"
7
8
"net"
8
9
"sync"
10
+ "syscall"
9
11
"time"
10
12
11
13
"github.com/google/uuid"
@@ -16,6 +18,14 @@ import (
16
18
"github.com/coder/coder/v2/codersdk"
17
19
)
18
20
21
+ // Package-level sentinel errors
22
+ var (
23
+ ErrTooManyStreams = xerrors .New ("too many streams" )
24
+ ErrStreamNotFound = xerrors .New ("stream not found" )
25
+ ErrConnRefused = xerrors .New ("connection refused" )
26
+ ErrAlreadyConnected = xerrors .New ("already connected" )
27
+ )
28
+
19
29
const (
20
30
// MaxStreams is the maximum number of immortal streams allowed per agent
21
31
MaxStreams = 32
@@ -56,7 +66,7 @@ func (m *Manager) CreateStream(ctx context.Context, port int) (*codersdk.Immorta
56
66
// Try to evict a disconnected stream
57
67
evicted := m .evictOldestDisconnectedLocked ()
58
68
if ! evicted {
59
- return nil , xerrors . New ( "too many immortal streams" )
69
+ return nil , ErrTooManyStreams
60
70
}
61
71
}
62
72
@@ -65,7 +75,7 @@ func (m *Manager) CreateStream(ctx context.Context, port int) (*codersdk.Immorta
65
75
conn , err := m .dialer .DialContext (ctx , "tcp" , addr )
66
76
if err != nil {
67
77
if isConnectionRefused (err ) {
68
- return nil , xerrors . Errorf ( "the connection was refused" )
78
+ return nil , ErrConnRefused
69
79
}
70
80
return nil , xerrors .Errorf ("dial local service: %w" , err )
71
81
}
@@ -88,13 +98,9 @@ func (m *Manager) CreateStream(ctx context.Context, port int) (*codersdk.Immorta
88
98
89
99
m .streams [id ] = stream
90
100
91
- return & codersdk.ImmortalStream {
92
- ID : id ,
93
- Name : name ,
94
- TCPPort : port ,
95
- CreatedAt : stream .createdAt ,
96
- LastConnectionAt : stream .createdAt ,
97
- }, nil
101
+ // Return the API representation of the stream
102
+ apiStream := stream .ToAPI ()
103
+ return & apiStream , nil
98
104
}
99
105
100
106
// GetStream returns a stream by ID
@@ -124,7 +130,7 @@ func (m *Manager) DeleteStream(id uuid.UUID) error {
124
130
125
131
stream , ok := m .streams [id ]
126
132
if ! ok {
127
- return xerrors . New ( "stream not found" )
133
+ return ErrStreamNotFound
128
134
}
129
135
130
136
if err := stream .Close (); err != nil {
@@ -216,17 +222,28 @@ func (m *Manager) HandleConnection(id uuid.UUID, conn io.ReadWriteCloser, readSe
216
222
m .mu .RUnlock ()
217
223
218
224
if ! ok {
219
- return xerrors . New ( "stream not found" )
225
+ return ErrStreamNotFound
220
226
}
221
227
222
228
return stream .HandleReconnect (conn , readSeqNum )
223
229
}
224
230
225
231
// isConnectionRefused checks if an error is a connection refused error
226
232
func isConnectionRefused (err error ) bool {
233
+ // Check for syscall.ECONNREFUSED through error unwrapping
234
+ var errno syscall.Errno
235
+ if errors .As (err , & errno ) && errno == syscall .ECONNREFUSED {
236
+ return true
237
+ }
238
+
239
+ // Fallback: check for net.OpError with "dial" operation
227
240
var opErr * net.OpError
228
- if xerrors .As (err , & opErr ) {
229
- return opErr .Op == "dial"
241
+ if errors .As (err , & opErr ) && opErr .Op == "dial" {
242
+ // Check if the underlying error is ECONNREFUSED
243
+ if errors .As (opErr .Err , & errno ) && errno == syscall .ECONNREFUSED {
244
+ return true
245
+ }
230
246
}
247
+
231
248
return false
232
249
}
0 commit comments