From 7e11ebbc439b00df821154a65869e2b426702c84 Mon Sep 17 00:00:00 2001 From: Mike Brown <brownwm@us.ibm.com> Date: Tue, 7 Dec 2021 11:57:54 -0600 Subject: [PATCH 1/2] run setup on networks in parallel Signed-off-by: Mike Brown <brownwm@us.ibm.com> --- cni.go | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/cni.go b/cni.go index 923c280..8b970e8 100644 --- a/cni.go +++ b/cni.go @@ -154,16 +154,39 @@ func (c *libcni) Setup(ctx context.Context, id string, path string, opts ...Name return c.createResult(result) } +type asynchAttachResult struct { + res *types100.Result + err error +} + +func asynchAttach(ctx context.Context, n *Network, ns *Namespace, wg *sync.WaitGroup, rc chan asynchAttachResult) { + defer wg.Done() + r, err := n.Attach(ctx, ns) + rc <- asynchAttachResult{res: r, err: err} +} + func (c *libcni) attachNetworks(ctx context.Context, ns *Namespace) ([]*types100.Result, error) { + var wg sync.WaitGroup + var lastError error var results []*types100.Result + rc := make(chan asynchAttachResult) + for _, network := range c.Networks() { - r, err := network.Attach(ctx, ns) - if err != nil { - return nil, err + wg.Add(1) + go asynchAttach(ctx, network, ns, &wg, rc) + } + + for range c.Networks() { + rs := <-rc + if rs.err != nil { + lastError = rs.err + } else { + results = append(results, rs.res) } - results = append(results, r) } - return results, nil + wg.Wait() + + return results, lastError } // Remove removes the network config from the namespace From 9caf1de13f34a506d1e8e31cafa9388eeb006fe2 Mon Sep 17 00:00:00 2001 From: Mike Brown <brownwm@us.ibm.com> Date: Tue, 14 Dec 2021 11:45:38 -0600 Subject: [PATCH 2/2] switch to direct index Signed-off-by: Mike Brown <brownwm@us.ibm.com> --- cni.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cni.go b/cni.go index 8b970e8..f26a6ee 100644 --- a/cni.go +++ b/cni.go @@ -155,38 +155,38 @@ func (c *libcni) Setup(ctx context.Context, id string, path string, opts ...Name } type asynchAttachResult struct { - res *types100.Result - err error + index int + res *types100.Result + err error } -func asynchAttach(ctx context.Context, n *Network, ns *Namespace, wg *sync.WaitGroup, rc chan asynchAttachResult) { +func asynchAttach(ctx context.Context, index int, n *Network, ns *Namespace, wg *sync.WaitGroup, rc chan asynchAttachResult) { defer wg.Done() r, err := n.Attach(ctx, ns) - rc <- asynchAttachResult{res: r, err: err} + rc <- asynchAttachResult{index: index, res: r, err: err} } func (c *libcni) attachNetworks(ctx context.Context, ns *Namespace) ([]*types100.Result, error) { var wg sync.WaitGroup - var lastError error - var results []*types100.Result + var firstError error + results := make([]*types100.Result, len(c.Networks())) rc := make(chan asynchAttachResult) - for _, network := range c.Networks() { + for i, network := range c.Networks() { wg.Add(1) - go asynchAttach(ctx, network, ns, &wg, rc) + go asynchAttach(ctx, i, network, ns, &wg, rc) } for range c.Networks() { rs := <-rc - if rs.err != nil { - lastError = rs.err - } else { - results = append(results, rs.res) + if rs.err != nil && firstError == nil { + firstError = rs.err } + results[rs.index] = rs.res } wg.Wait() - return results, lastError + return results, firstError } // Remove removes the network config from the namespace