[lxc-devel] [lxd/master] support canceling with parallel downloads

albertodonato on Github lxc-bot at linuxcontainers.org
Mon Oct 9 10:16:05 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 313 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171009/03616999/attachment.bin>
-------------- next part --------------
From 59e42cfb65698248a1d77e7eb08f9aae6e957898 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Mon, 9 Oct 2017 12:15:18 +0200
Subject: [PATCH] support canceling with parallel downloads

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 lxd/daemon_images.go      |  2 +-
 shared/cancel/canceler.go | 22 +++++++++++++++-------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/lxd/daemon_images.go b/lxd/daemon_images.go
index 06bb5fd4a..b3a3e12c8 100644
--- a/lxd/daemon_images.go
+++ b/lxd/daemon_images.go
@@ -360,7 +360,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 
 	var canceler *cancel.Canceler
 	if op != nil {
-		canceler = &cancel.Canceler{}
+		canceler = cancel.NewCanceler()
 		op.canceler = canceler
 	}
 
diff --git a/shared/cancel/canceler.go b/shared/cancel/canceler.go
index 83c58992f..6a27347a0 100644
--- a/shared/cancel/canceler.go
+++ b/shared/cancel/canceler.go
@@ -7,20 +7,28 @@ import (
 
 // A struct to track canceleation
 type Canceler struct {
-	chCancel chan struct{}
+	reqChCancel map[*http.Request]chan struct{}
+}
+
+func NewCanceler() *Canceler {
+	c := Canceler{}
+	c.reqChCancel = make(map[*http.Request]chan struct{})
+	return &c
 }
 
 func (c *Canceler) Cancelable() bool {
-	return c.chCancel != nil
+	return len(c.reqChCancel) > 0
 }
 
 func (c *Canceler) Cancel() error {
-	if c.chCancel == nil {
+	if !c.Cancelable() {
 		return fmt.Errorf("This operation cannot be canceled at this time")
 	}
 
-	close(c.chCancel)
-	c.chCancel = nil
+	for req, ch := range c.reqChCancel {
+		close(ch)
+		delete(c.reqChCancel, req)
+	}
 	return nil
 }
 
@@ -28,14 +36,14 @@ func CancelableDownload(c *Canceler, client *http.Client, req *http.Request) (*h
 	chDone := make(chan bool)
 	chCancel := make(chan struct{})
 	if c != nil {
-		c.chCancel = chCancel
+		c.reqChCancel[req] = chCancel
 	}
 	req.Cancel = chCancel
 
 	go func() {
 		<-chDone
 		if c != nil {
-			c.chCancel = nil
+			delete(c.reqChCancel, req)
 		}
 	}()
 


More information about the lxc-devel mailing list