@@ -47,7 +47,7 @@ func NewDockerClient(opts *client.Opt, logger *zap.Logger) (ContainerClient, err
47
47
}
48
48
49
49
func (d * dockerClient ) GetContainers (ctx context.Context , opts * container.ListOptions ) ([]Container , error ) {
50
- var containersList []Container
50
+ containersList := []Container {}
51
51
52
52
containers , err := d .client .ContainerList (ctx , * opts )
53
53
if err != nil {
@@ -66,6 +66,39 @@ func (d *dockerClient) GetContainers(ctx context.Context, opts *container.ListOp
66
66
return containersList , nil
67
67
}
68
68
69
+ func (d * dockerClient ) getResourceConstraints () container.Resources {
70
+ if config .IsResourceConstraintsEnabled () {
71
+ return container.Resources {
72
+ Memory : 500 * 1024 * 1024 , // 500 MB
73
+ NanoCPUs : 1000000000 , // 1 CPU
74
+ Ulimits : []* units.Ulimit {
75
+ {
76
+ Name : "nproc" ,
77
+ Soft : 64 ,
78
+ Hard : 128 ,
79
+ },
80
+ {
81
+ Name : "nofile" ,
82
+ Soft : 64 ,
83
+ Hard : 128 ,
84
+ },
85
+ {
86
+ Name : "core" ,
87
+ Soft : 0 ,
88
+ Hard : 0 ,
89
+ },
90
+ {
91
+ // Maximum file size that can be created by the process (output file in our case)
92
+ Name : "fsize" ,
93
+ Soft : 20 * 1024 * 1024 ,
94
+ Hard : 20 * 1024 * 1024 ,
95
+ },
96
+ },
97
+ }
98
+ }
99
+ return container.Resources {}
100
+ }
101
+
69
102
func (d * dockerClient ) ExecuteCode (ctx context.Context , code * Code ) (string , error ) {
70
103
codeFileName , inputFileName , err := createCodeAndInputFilesHost (code , d .logger )
71
104
if err != nil {
@@ -76,6 +109,8 @@ func (d *dockerClient) ExecuteCode(ctx context.Context, code *Code) (string, err
76
109
zap .String ("input file name" , inputFileName ),
77
110
)
78
111
112
+ resourceConstraints := d .getResourceConstraints ()
113
+
79
114
res , err := d .client .ContainerCreate (ctx , & container.Config {
80
115
Cmd : getContainerCommand (code , codeFileName , inputFileName ),
81
116
Image : code .Image ,
@@ -92,40 +127,13 @@ func (d *dockerClient) ExecuteCode(ctx context.Context, code *Code) (string, err
92
127
RestartPolicy : container.RestartPolicy {
93
128
Name : "no" ,
94
129
},
95
- // We are reading the container logs to get the output. So it's better to disable and have a separate thread to delete stale containers
130
+ // We are reading the container logs to get the output.
131
+ // So it's better to disable and have a separate thread to delete stale containers
96
132
AutoRemove : false ,
97
133
// Drop all the capabilities
98
134
CapDrop : []string {"ALL" },
99
135
Privileged : false ,
100
- // Set the memory limit to 1GB
101
- Resources : container.Resources {
102
- // set 500 MB as the memory limit in bytes
103
- Memory : 500 * 1024 * 1024 ,
104
- NanoCPUs : 500000000 , // 0.5 CPU
105
- Ulimits : []* units.Ulimit {
106
- {
107
- Name : "nproc" ,
108
- Soft : 64 ,
109
- Hard : 128 ,
110
- },
111
- {
112
- Name : "nofile" ,
113
- Soft : 64 ,
114
- Hard : 128 ,
115
- },
116
- {
117
- Name : "core" ,
118
- Soft : 0 ,
119
- Hard : 0 ,
120
- },
121
- {
122
- // Maximum file size that can be created by the process (output file in our case)
123
- Name : "fsize" ,
124
- Soft : 20 * 1024 * 1024 ,
125
- Hard : 20 * 1024 * 1024 ,
126
- },
127
- },
128
- },
136
+ Resources : resourceConstraints ,
129
137
}, nil , nil , getContainerName ())
130
138
131
139
if err != nil {
@@ -217,22 +225,36 @@ func deleteStaleFiles(dir string, logger *zap.Logger) error {
217
225
}
218
226
219
227
func (d * dockerClient ) FreeUpZombieContainers (ctx context.Context ) error {
228
+ ticker := time .NewTicker (GarbageCollectionTimeWindow )
220
229
for {
221
- pruneResults , err := d .client .ContainersPrune (ctx , filters.Args {})
222
- if err != nil {
223
- d .logger .Error ("failed to prune containers" ,
224
- zap .Error (err ),
225
- )
226
- }
230
+ select {
231
+ case <- ctx .Done ():
232
+ d .logger .Info ("stopping the zombie container cleanup routine" )
233
+ return nil
234
+ case <- ticker .C :
235
+ pruneResults , err := d .client .ContainersPrune (ctx , filters.Args {})
236
+ if err != nil {
237
+ d .logger .Error ("failed to prune containers" ,
238
+ zap .Error (err ),
239
+ )
240
+ }
227
241
228
- d .logger .Info ("successfully pruned the containers:" ,
229
- zap .Int ("#Pruned containers" , len (pruneResults .ContainersDeleted )),
230
- )
242
+ d .logger .Info ("successfully pruned the containers:" ,
243
+ zap .Int ("#Pruned containers" , len (pruneResults .ContainersDeleted )),
244
+ )
231
245
232
- deleteStaleFiles (config .GetHostLanguageCodePath (config .Cpp ), d .logger )
233
- deleteStaleFiles (config .GetHostLanguageCodePath (config .Golang ), d .logger )
246
+ if err = deleteStaleFiles (config .GetHostLanguageCodePath (config .Cpp ), d .logger ); err != nil {
247
+ d .logger .Error ("failed to delete stale files" ,
248
+ zap .Error (err ),
249
+ )
250
+ }
234
251
235
- time .Sleep (GarbageCollectionTimeWindow )
252
+ if err = deleteStaleFiles (config .GetHostLanguageCodePath (config .Golang ), d .logger ); err != nil {
253
+ d .logger .Error ("failed to delete stale files" ,
254
+ zap .Error (err ),
255
+ )
256
+ }
257
+ }
236
258
}
237
259
}
238
260
0 commit comments