From ee6f508799e7c0e23eb0534c4f139b9e0f3d6760 Mon Sep 17 00:00:00 2001
From: Kyle Evans <kevans@FreeBSD.org>
Date: Tue, 5 May 2020 22:37:12 -0500
Subject: [PATCH] repo: archive: make GET endpoint synchronous again

If the request isn't complete, this endpoint will now submit the request and
wait for completion using the new API. This may still be susceptible to
timeouts for larger repos, but other endpoints now exist that the web
interface will use to negotiate its way through larger archive processes.
---
 routers/repo/repo.go | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 95d4701be9..3f18f36721 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -480,23 +480,19 @@ func Download(ctx *context.Context) {
 	aReq := archiver_service.DeriveRequestFrom(ctx, uri)
 
 	downloadName := ctx.Repo.Repository.Name + "-" + aReq.GetArchiveName()
+	if !aReq.IsComplete() {
+		aReq = archiver_service.ArchiveRepository(aReq)
+		archiver_service.LockQueue()
+		for !aReq.IsComplete() {
+			archiver_service.WaitForCompletion()
+		}
+		archiver_service.UnlockQueue()
+	}
+
 	if aReq.IsComplete() {
 		ctx.ServeFile(aReq.GetArchivePath(), downloadName)
 	} else {
-		// We'll wait up to two seconds for the request to be satisfied, before we just return
-		// a 200 Accepted to indicate that we're processing.
-		archiver_service.ArchiveRepository(aReq)
-		timeout := time.Now().Add(2 * time.Second)
-		for {
-			if aReq.IsComplete() || time.Now().After(timeout) {
-				break
-			}
-		}
-		if aReq.IsComplete() {
-			ctx.ServeFile(aReq.GetArchivePath(), downloadName)
-		} else {
-			ctx.Error(202, "Request accepted, processing archive.")
-		}
+		ctx.Error(404)
 	}
 }
 
@@ -513,7 +509,7 @@ func InitiateDownload(ctx *context.Context) {
 
 	complete := aReq.IsComplete()
 	if !complete {
-		archiver_service.ArchiveRepository(aReq)
+		aReq = archiver_service.ArchiveRepository(aReq)
 		// As with the standard Download, we'll wait up to two seconds for the request
 		// to be completed.  The difference is that we'll never download the file from a POST
 		// request, only indicate the current status.  If we did manage to complete the request