Skip to content

Commit a38bb65

Browse files
fixed leaking goroutines (#399)
Signed-off-by: Aleksey Gavrilov <[email protected]>
1 parent 69aa630 commit a38bb65

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

auth_server/authz/acl.go

+45-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package authz
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"net"
@@ -11,7 +12,6 @@ import (
1112
"strings"
1213

1314
"github.com/cesanta/glog"
14-
"github.com/schwarmco/go-cartesian-product"
1515

1616
"github.com/cesanta/docker_auth/auth_server/api"
1717
)
@@ -180,21 +180,63 @@ func matchStringWithLabelPermutations(pp *string, s string, vars []string, label
180180
}
181181
}
182182
if len(labelSets) > 0 {
183-
for permuation := range cartesian.Iter(labelSets...) {
183+
ctx, cancel := context.WithCancel(context.Background())
184+
defer cancel()
185+
186+
for permuation := range IterWithContext(ctx, labelSets...) {
184187
var labelVars []string
185188
for _, val := range permuation {
186189
labelVars = append(labelVars, val.([]string)...)
187190
}
188191
matched = matchString(pp, s, append(vars, labelVars...))
189192
if matched {
190-
break
193+
return matched
191194
}
192195
}
193196
}
194197
}
195198
return matched
196199
}
197200

201+
func IterWithContext(ctx context.Context, params ...[]interface{}) <-chan []interface{} {
202+
c := make(chan []interface{})
203+
204+
if len(params) == 0 {
205+
close(c)
206+
return c
207+
}
208+
209+
go func() {
210+
defer close(c) // Ensure the channel is closed when the goroutine exits
211+
212+
iterate(ctx, c, params[0], []interface{}{}, params[1:]...)
213+
}()
214+
215+
return c
216+
}
217+
218+
func iterate(ctx context.Context, channel chan []interface{}, topLevel, result []interface{}, needUnpacking ...[]interface{}) {
219+
if len(needUnpacking) == 0 {
220+
for _, p := range topLevel {
221+
select {
222+
case <-ctx.Done():
223+
return // Exit if the context is canceled
224+
case channel <- append(append([]interface{}{}, result...), p):
225+
}
226+
}
227+
return
228+
}
229+
230+
for _, p := range topLevel {
231+
select {
232+
case <-ctx.Done():
233+
return // Exit if the context is canceled
234+
default:
235+
iterate(ctx, channel, needUnpacking[0], append(result, p), needUnpacking[1:]...)
236+
}
237+
}
238+
}
239+
198240
func matchIP(ipp *string, ip net.IP) bool {
199241
if ipp == nil {
200242
return true

0 commit comments

Comments
 (0)