@@ -73,7 +73,8 @@ type Options struct {
73
73
ReportMetadataInterval time.Duration
74
74
ServiceBannerRefreshInterval time.Duration
75
75
Syscaller agentproc.Syscaller
76
- ProcessManagementInterval time.Duration
76
+ ProcessManagementTick <- chan time.Time
77
+ ModifiedProcesses chan []* agentproc.Process
77
78
}
78
79
79
80
type Client interface {
@@ -130,10 +131,6 @@ func New(options Options) Agent {
130
131
options .Syscaller = agentproc.UnixSyscaller {}
131
132
}
132
133
133
- if options .ProcessManagementInterval == 0 {
134
- options .ProcessManagementInterval = time .Second
135
- }
136
-
137
134
ctx , cancelFunc := context .WithCancel (context .Background ())
138
135
a := & agent {
139
136
tailnetListenPort : options .TailnetListenPort ,
@@ -158,7 +155,8 @@ func New(options Options) Agent {
158
155
subsystems : options .Subsystems ,
159
156
addresses : options .Addresses ,
160
157
syscaller : options .Syscaller ,
161
- processManagementInterval : options .ProcessManagementInterval ,
158
+ processManagementTick : options .ProcessManagementTick ,
159
+ modifiedProcs : options .ModifiedProcesses ,
162
160
163
161
prometheusRegistry : prometheusRegistry ,
164
162
metrics : newAgentMetrics (prometheusRegistry ),
@@ -211,10 +209,11 @@ type agent struct {
211
209
212
210
connCountReconnectingPTY atomic.Int64
213
211
214
- prometheusRegistry * prometheus.Registry
215
- metrics * agentMetrics
216
- processManagementInterval time.Duration
217
- syscaller agentproc.Syscaller
212
+ prometheusRegistry * prometheus.Registry
213
+ metrics * agentMetrics
214
+ processManagementTick <- chan time.Time
215
+ modifiedProcs chan []* agentproc.Process
216
+ syscaller agentproc.Syscaller
218
217
}
219
218
220
219
func (a * agent ) TailnetConn () * tailnet.Conn {
@@ -1275,9 +1274,6 @@ func (a *agent) startReportingConnectionStats(ctx context.Context) {
1275
1274
var prioritizedProcs = []string {"coder" }
1276
1275
1277
1276
func (a * agent ) manageProcessPriorityLoop (ctx context.Context ) {
1278
- ticker := time .NewTicker (a .processManagementInterval )
1279
- defer ticker .Stop ()
1280
-
1281
1277
if val := a .envVars [EnvProcMemNice ]; val == "" || runtime .GOOS != "linux" {
1282
1278
a .logger .Info (ctx , "process priority not enabled, agent will not manage process niceness/oom_score_adj " ,
1283
1279
slog .F ("env_var" , EnvProcMemNice ),
@@ -1287,42 +1283,45 @@ func (a *agent) manageProcessPriorityLoop(ctx context.Context) {
1287
1283
return
1288
1284
}
1289
1285
1290
- // Do once before falling into loop.
1291
- if err := a .manageProcessPriority (ctx ); err != nil {
1292
- a .logger .Error (ctx , "manage process priority" ,
1293
- slog .F ("dir" , agentproc .DefaultProcDir ),
1294
- slog .Error (err ),
1295
- )
1286
+ manage := func () {
1287
+ // Do once before falling into loop.
1288
+ procs , err := a .manageProcessPriority (ctx )
1289
+ if err != nil {
1290
+ a .logger .Error (ctx , "manage process priority" ,
1291
+ slog .F ("dir" , agentproc .DefaultProcDir ),
1292
+ slog .Error (err ),
1293
+ )
1294
+ }
1295
+ if a .modifiedProcs != nil {
1296
+ a .modifiedProcs <- procs
1297
+ }
1296
1298
}
1297
1299
1300
+ manage ()
1301
+
1298
1302
for {
1299
1303
select {
1300
- case <- ticker .C :
1301
- if err := a .manageProcessPriority (ctx ); err != nil {
1302
- a .logger .Error (ctx , "manage process priority" ,
1303
- slog .F ("dir" , agentproc .DefaultProcDir ),
1304
- slog .Error (err ),
1305
- )
1306
- }
1307
-
1304
+ case <- a .processManagementTick :
1305
+ manage ()
1308
1306
case <- ctx .Done ():
1309
1307
return
1310
1308
}
1311
1309
}
1312
1310
}
1313
1311
1314
- func (a * agent ) manageProcessPriority (ctx context.Context ) error {
1312
+ func (a * agent ) manageProcessPriority (ctx context.Context ) ([] * agentproc. Process , error ) {
1315
1313
const (
1316
1314
procDir = agentproc .DefaultProcDir
1317
1315
niceness = 10
1318
- oomScoreAdj = 100
1316
+ oomScoreAdj = - 1000
1319
1317
)
1320
1318
1321
1319
procs , err := agentproc .List (a .filesystem , a .syscaller , agentproc .DefaultProcDir )
1322
1320
if err != nil {
1323
- return xerrors .Errorf ("list: %w" , err )
1321
+ return nil , xerrors .Errorf ("list: %w" , err )
1324
1322
}
1325
1323
1324
+ modProcs := []* agentproc.Process {}
1326
1325
for _ , proc := range procs {
1327
1326
// Trim off the path e.g. "./coder" -> "coder"
1328
1327
name := filepath .Base (proc .Name ())
@@ -1339,6 +1338,7 @@ func (a *agent) manageProcessPriority(ctx context.Context) error {
1339
1338
)
1340
1339
continue
1341
1340
}
1341
+ modProcs = append (modProcs , proc )
1342
1342
1343
1343
a .logger .Debug (ctx , "decreased process oom_score" ,
1344
1344
slog .F ("name" , proc .Name ()),
@@ -1382,8 +1382,9 @@ func (a *agent) manageProcessPriority(ctx context.Context) error {
1382
1382
slog .F ("pid" , proc .PID ),
1383
1383
slog .F ("niceness" , niceness ),
1384
1384
)
1385
+ modProcs = append (modProcs , proc )
1385
1386
}
1386
- return nil
1387
+ return modProcs , nil
1387
1388
}
1388
1389
1389
1390
// isClosed returns whether the API is closed or not.
0 commit comments