Skip to content

Commit 5f41ca6

Browse files
tonistiigicrazy-max
authored andcommitted
llbsolver: fix possible deadlock in history listen
The events for currently active builds were sent through pubsub channel instead of directly to the current request, like it was done for completed builds for example. This meant that if there are more active builds running than the pubsub channel buffer (32) the sends will block. Because the history API mutex is held in this process it will eventually block the requests for builds that try to update their history records. Signed-off-by: Tonis Tiigi <[email protected]> (cherry picked from commit 1ed9931)
1 parent 646e71a commit 5f41ca6

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

solver/llbsolver/history.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,21 +762,30 @@ func (h *HistoryQueue) Listen(ctx context.Context, req *controlapi.BuildHistoryR
762762
}()
763763
}
764764

765+
// make a copy of events for active builds so we don't keep a lock during grpc send
766+
actives := make([]*controlapi.BuildHistoryEvent, 0, len(h.active))
767+
765768
for _, e := range h.active {
766769
if req.Ref != "" && e.Ref != req.Ref {
767770
continue
768771
}
769772
if _, ok := h.deleted[e.Ref]; ok {
770773
continue
771774
}
772-
sub.send(&controlapi.BuildHistoryEvent{
775+
actives = append(actives, &controlapi.BuildHistoryEvent{
773776
Type: controlapi.BuildHistoryEventType_STARTED,
774777
Record: e,
775778
})
776779
}
777780

778781
h.mu.Unlock()
779782

783+
for _, e := range actives {
784+
if err := f(e); err != nil {
785+
return err
786+
}
787+
}
788+
780789
if !req.ActiveOnly {
781790
events := []*controlapi.BuildHistoryEvent{}
782791
if err := h.opt.DB.View(func(tx *bolt.Tx) error {

0 commit comments

Comments
 (0)