6
6
"encoding/binary"
7
7
"encoding/json"
8
8
"errors"
9
- "flag"
10
9
"fmt"
11
10
"io"
12
11
"net"
@@ -52,21 +51,22 @@ const (
52
51
)
53
52
54
53
type Options struct {
55
- Filesystem afero.Fs
56
- LogDir string
57
- TempDir string
58
- ExchangeToken func (ctx context.Context ) (string , error )
59
- Client Client
60
- ReconnectingPTYTimeout time.Duration
61
- EnvironmentVariables map [string ]string
62
- Logger slog.Logger
63
- IgnorePorts map [int ]string
64
- SSHMaxTimeout time.Duration
65
- TailnetListenPort uint16
66
- Subsystem codersdk.AgentSubsystem
67
- Addresses []netip.Prefix
68
-
69
- PrometheusRegistry * prometheus.Registry
54
+ Filesystem afero.Fs
55
+ LogDir string
56
+ TempDir string
57
+ ExchangeToken func (ctx context.Context ) (string , error )
58
+ Client Client
59
+ ReconnectingPTYTimeout time.Duration
60
+ EnvironmentVariables map [string ]string
61
+ Logger slog.Logger
62
+ IgnorePorts map [int ]string
63
+ SSHMaxTimeout time.Duration
64
+ TailnetListenPort uint16
65
+ Subsystem codersdk.AgentSubsystem
66
+ Addresses []netip.Prefix
67
+ PrometheusRegistry * prometheus.Registry
68
+ ReportMetadataInterval time.Duration
69
+ ServiceBannerRefreshInterval time.Duration
70
70
}
71
71
72
72
type Client interface {
@@ -107,6 +107,12 @@ func New(options Options) Agent {
107
107
return "" , nil
108
108
}
109
109
}
110
+ if options .ReportMetadataInterval == 0 {
111
+ options .ReportMetadataInterval = 1 * time .Minute
112
+ }
113
+ if options .ServiceBannerRefreshInterval == 0 {
114
+ options .ServiceBannerRefreshInterval = 2 * time .Minute
115
+ }
110
116
111
117
prometheusRegistry := options .PrometheusRegistry
112
118
if prometheusRegistry == nil {
@@ -115,25 +121,27 @@ func New(options Options) Agent {
115
121
116
122
ctx , cancelFunc := context .WithCancel (context .Background ())
117
123
a := & agent {
118
- tailnetListenPort : options .TailnetListenPort ,
119
- reconnectingPTYTimeout : options .ReconnectingPTYTimeout ,
120
- logger : options .Logger ,
121
- closeCancel : cancelFunc ,
122
- closed : make (chan struct {}),
123
- envVars : options .EnvironmentVariables ,
124
- client : options .Client ,
125
- exchangeToken : options .ExchangeToken ,
126
- filesystem : options .Filesystem ,
127
- logDir : options .LogDir ,
128
- tempDir : options .TempDir ,
129
- lifecycleUpdate : make (chan struct {}, 1 ),
130
- lifecycleReported : make (chan codersdk.WorkspaceAgentLifecycle , 1 ),
131
- lifecycleStates : []agentsdk.PostLifecycleRequest {{State : codersdk .WorkspaceAgentLifecycleCreated }},
132
- ignorePorts : options .IgnorePorts ,
133
- connStatsChan : make (chan * agentsdk.Stats , 1 ),
134
- sshMaxTimeout : options .SSHMaxTimeout ,
135
- subsystem : options .Subsystem ,
136
- addresses : options .Addresses ,
124
+ tailnetListenPort : options .TailnetListenPort ,
125
+ reconnectingPTYTimeout : options .ReconnectingPTYTimeout ,
126
+ logger : options .Logger ,
127
+ closeCancel : cancelFunc ,
128
+ closed : make (chan struct {}),
129
+ envVars : options .EnvironmentVariables ,
130
+ client : options .Client ,
131
+ exchangeToken : options .ExchangeToken ,
132
+ filesystem : options .Filesystem ,
133
+ logDir : options .LogDir ,
134
+ tempDir : options .TempDir ,
135
+ lifecycleUpdate : make (chan struct {}, 1 ),
136
+ lifecycleReported : make (chan codersdk.WorkspaceAgentLifecycle , 1 ),
137
+ lifecycleStates : []agentsdk.PostLifecycleRequest {{State : codersdk .WorkspaceAgentLifecycleCreated }},
138
+ ignorePorts : options .IgnorePorts ,
139
+ connStatsChan : make (chan * agentsdk.Stats , 1 ),
140
+ reportMetadataInterval : options .ReportMetadataInterval ,
141
+ serviceBannerRefreshInterval : options .ServiceBannerRefreshInterval ,
142
+ sshMaxTimeout : options .SSHMaxTimeout ,
143
+ subsystem : options .Subsystem ,
144
+ addresses : options .Addresses ,
137
145
138
146
prometheusRegistry : prometheusRegistry ,
139
147
metrics : newAgentMetrics (prometheusRegistry ),
@@ -165,13 +173,14 @@ type agent struct {
165
173
closed chan struct {}
166
174
167
175
envVars map [string ]string
168
- // manifest is atomic because values can change after reconnection.
169
- manifest atomic.Pointer [agentsdk.Manifest ]
170
- // serviceBanner is atomic because it can change.
171
- serviceBanner atomic.Pointer [codersdk.ServiceBannerConfig ]
172
- sessionToken atomic.Pointer [string ]
173
- sshServer * agentssh.Server
174
- sshMaxTimeout time.Duration
176
+
177
+ manifest atomic.Pointer [agentsdk.Manifest ] // manifest is atomic because values can change after reconnection.
178
+ reportMetadataInterval time.Duration
179
+ serviceBanner atomic.Pointer [codersdk.ServiceBannerConfig ] // serviceBanner is atomic because it is periodically updated.
180
+ serviceBannerRefreshInterval time.Duration
181
+ sessionToken atomic.Pointer [string ]
182
+ sshServer * agentssh.Server
183
+ sshMaxTimeout time.Duration
175
184
176
185
lifecycleUpdate chan struct {}
177
186
lifecycleReported chan codersdk.WorkspaceAgentLifecycle
@@ -283,17 +292,6 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
283
292
return result
284
293
}
285
294
286
- // adjustIntervalForTests returns a duration of testInterval milliseconds long
287
- // for tests and interval seconds long otherwise.
288
- func adjustIntervalForTests (interval time.Duration , testInterval time.Duration ) time.Duration {
289
- // In tests we want to set shorter intervals because engineers are
290
- // impatient.
291
- if flag .Lookup ("test.v" ) != nil {
292
- return testInterval
293
- }
294
- return interval
295
- }
296
-
297
295
type metadataResultAndKey struct {
298
296
result * codersdk.WorkspaceAgentMetadataResult
299
297
key string
@@ -315,12 +313,10 @@ func (t *trySingleflight) Do(key string, fn func()) {
315
313
}
316
314
317
315
func (a * agent ) reportMetadataLoop (ctx context.Context ) {
318
- baseInterval := adjustIntervalForTests (time .Second , time .Millisecond * 100 )
319
-
320
316
const metadataLimit = 128
321
317
322
318
var (
323
- baseTicker = time .NewTicker (baseInterval )
319
+ baseTicker = time .NewTicker (a . reportMetadataInterval )
324
320
lastCollectedAts = make (map [string ]time.Time )
325
321
metadataResults = make (chan metadataResultAndKey , metadataLimit )
326
322
)
@@ -391,11 +387,7 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
391
387
continue
392
388
}
393
389
// The last collected value isn't quite stale yet, so we skip it.
394
- if collectedAt .Add (
395
- adjustIntervalForTests (
396
- time .Duration (md .Interval )* time .Second ,
397
- time .Duration (md .Interval )* time .Millisecond * 100 ),
398
- ).After (time .Now ()) {
390
+ if collectedAt .Add (a .reportMetadataInterval ).After (time .Now ()) {
399
391
continue
400
392
}
401
393
}
@@ -506,7 +498,7 @@ func (a *agent) setLifecycle(ctx context.Context, state codersdk.WorkspaceAgentL
506
498
// not be fetched immediately; the expectation is that it is primed elsewhere
507
499
// (and must be done before the session actually starts).
508
500
func (a * agent ) fetchServiceBannerLoop (ctx context.Context ) {
509
- ticker := time .NewTicker (adjustIntervalForTests ( 2 * time . Minute , time . Millisecond * 5 ) )
501
+ ticker := time .NewTicker (a . serviceBannerRefreshInterval )
510
502
defer ticker .Stop ()
511
503
for {
512
504
select {
0 commit comments