internal/relui: set a deadline on artifact presence checks

We saw some signs of requests hanging when we tried it out. Make sure we
don't get stuck forever.

For golang/go#51797.

Change-Id: I24994105beee643b915dd17d520eb08843b0d864
Reviewed-on: https://go-review.googlesource.com/c/build/+/411895
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/internal/relui/workflows.go b/internal/relui/workflows.go
index 426510c..c3a7098 100644
--- a/internal/relui/workflows.go
+++ b/internal/relui/workflows.go
@@ -5,6 +5,7 @@
 package relui
 
 import (
+	"context"
 	"crypto/sha256"
 	"fmt"
 	"io"
@@ -25,6 +26,7 @@
 	"golang.org/x/build/internal/relui/db"
 	"golang.org/x/build/internal/task"
 	"golang.org/x/build/internal/workflow"
+	"golang.org/x/net/context/ctxhttp"
 )
 
 // DefinitionHolder holds workflow definitions.
@@ -735,11 +737,14 @@
 
 	for {
 		for _, a := range artifacts {
-			resp, err := http.Head(tasks.DownloadURL + "/" + a.Filename)
-			if err != nil {
+			ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
+			defer cancel()
+			resp, err := ctxhttp.Head(ctx, http.DefaultClient, tasks.DownloadURL+"/"+a.Filename)
+			if err != nil && err != context.DeadlineExceeded {
 				return err
 			}
 			resp.Body.Close()
+			cancel()
 			if resp.StatusCode == http.StatusOK {
 				delete(todo, a)
 			}