incorporate timeout into download process
diff --git a/bundle.go b/bundle.go
index 6f0c208..95fb3f6 100644
--- a/bundle.go
+++ b/bundle.go
@@ -18,10 +18,10 @@
 )
 
 var (
-	bundleRetryDelay      time.Duration = time.Second
-	bundleDownloadTimeout time.Duration = 10 * time.Minute
-	downloadQueue                       = make(chan *DownloadRequest, downloadQueueSize)
-	workerQueue                         = make(chan chan *DownloadRequest, concurrentDownloads)
+	bundleRetryDelay      = time.Second
+	bundleDownloadTimeout = 10 * time.Minute
+	downloadQueue         = make(chan *DownloadRequest, downloadQueueSize)
+	workerQueue           = make(chan chan *DownloadRequest, concurrentDownloads)
 )
 
 // simple doubling back-off
@@ -55,42 +55,23 @@
 
 	retryIn := bundleRetryDelay
 	maxBackOff := 5 * time.Minute
+	timeoutAfter := time.Now().Add(bundleDownloadTimeout)
 	req := &DownloadRequest{
-		dep:         dep,
-		hashWriter:  hashWriter,
-		bundleFile:  getBundleFile(dep),
-		backoffFunc: createBackoff(retryIn, maxBackOff),
+		dep:          dep,
+		hashWriter:   hashWriter,
+		bundleFile:   getBundleFile(dep),
+		backoffFunc:  createBackoff(retryIn, maxBackOff),
+		timeoutAfter: timeoutAfter,
 	}
 	downloadQueue <- req
-
-	// timeout and mark deployment failed (but retries will continue)
-	timeout := time.NewTimer(bundleDownloadTimeout)
-	go func() {
-		<-timeout.C
-		log.Debugf("bundle download timeout. marking deployment %s failed. will keep retrying: %s", dep.ID, dep.BundleURI)
-		var errMessage string
-		if err != nil {
-			errMessage = fmt.Sprintf("bundle download failed: %s", err)
-		} else {
-			errMessage = "bundle download failed"
-		}
-		setDeploymentResults(apiDeploymentResults{
-			{
-				ID:        dep.ID,
-				Status:    RESPONSE_STATUS_FAIL,
-				ErrorCode: ERROR_CODE_TODO,
-				Message:   errMessage,
-			},
-		})
-	}()
-
 }
 
 type DownloadRequest struct {
-	dep         DataDeployment
-	hashWriter  hash.Hash
-	bundleFile  string
-	backoffFunc func()
+	dep          DataDeployment
+	hashWriter   hash.Hash
+	bundleFile   string
+	backoffFunc  func()
+	timeoutAfter time.Time
 }
 
 func (r *DownloadRequest) downloadBundle() {
@@ -104,6 +85,8 @@
 		return
 	}
 
+	r.checkTimeout()
+
 	r.hashWriter.Reset()
 	tempFile, err := downloadFromURI(dep.BundleURI, r.hashWriter, dep.BundleChecksum)
 
@@ -137,6 +120,25 @@
 	deploymentsChanged <- dep.ID
 }
 
+func (r *DownloadRequest) checkTimeout() {
+
+	if !r.timeoutAfter.IsZero() {
+		if time.Now().After(r.timeoutAfter) {
+			r.timeoutAfter = time.Time{}
+			log.Debugf("bundle download timeout. marking deployment %s failed. will keep retrying: %s",
+				r.dep.ID, r.dep.BundleURI)
+			setDeploymentResults(apiDeploymentResults{
+				{
+					ID:        r.dep.ID,
+					Status:    RESPONSE_STATUS_FAIL,
+					ErrorCode: ERROR_CODE_TODO,
+					Message:   "bundle download failed",
+				},
+			})
+		}
+	}
+}
+
 func getBundleFile(dep DataDeployment) string {
 
 	// the content of the URI is unfortunately not guaranteed not to change, so I can't just use dep.BundleURI
diff --git a/bundle_test.go b/bundle_test.go
index 009eba6..cb76219 100644
--- a/bundle_test.go
+++ b/bundle_test.go
@@ -5,6 +5,9 @@
 	"net/url"
 	"time"
 
+	"net/http"
+	"net/http/httptest"
+
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
@@ -13,11 +16,26 @@
 
 	Context("download", func() {
 
-		It("should timeout, mark status as failed, then finish", func() {
+		FIt("should timeout, mark status as failed, then finish", func() {
+
+			proceed := make(chan bool)
+			failedOnce := false
+			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				if failedOnce {
+					proceed <- true
+					time.Sleep(bundleDownloadTimeout)
+					w.Write([]byte("/bundles/longfail"))
+				} else {
+					failedOnce = true
+					time.Sleep(bundleDownloadTimeout)
+					w.WriteHeader(500)
+				}
+			}))
+			defer ts.Close()
 
 			deploymentID := "bundle_download_fail"
 
-			uri, err := url.Parse(testServer.URL)
+			uri, err := url.Parse(ts.URL)
 			Expect(err).ShouldNot(HaveOccurred())
 
 			uri.Path = "/bundles/longfail"
@@ -63,8 +81,7 @@
 
 			queueDownloadRequest(dep)
 
-			// give download time to timeout
-			time.Sleep(bundleDownloadTimeout + (100 * time.Millisecond))
+			<-proceed
 
 			// get error state deployment
 			deployments, err := getDeployments("WHERE id=$1", deploymentID)