From b79a7890d9114f262b136f70d7a8e65f47ed8826 Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
Date: Mon, 29 Jun 2020 13:26:02 +0200
Subject: [PATCH] [backend] chunk binaryversion requests when querying a remote
 server

Those requests can get very big for package builds, and many remote
servers cannot deal with overlong GET requests.

(cherry picked from commit ae77dd48a1371257dad1046a7fcc75dc85d1edd6)
---
 src/backend/BSSrcServer/Remote.pm | 34 +++++++++++++++++++++++++++++++
 src/backend/bs_srcserver          |  5 +++++
 2 files changed, 39 insertions(+)

diff --git a/src/backend/BSSrcServer/Remote.pm b/src/backend/BSSrcServer/Remote.pm
index f504b4fe4b..c5e651e00b 100644
--- a/src/backend/BSSrcServer/Remote.pm
+++ b/src/backend/BSSrcServer/Remote.pm
@@ -669,6 +669,40 @@ sub getremotebinaryversions {
   return $binaryversions;
 }
 
+sub getpackagebinaryversionlist {
+  my ($proj, $projid, $repoid, $arch, $packages, $view) = @_;
+  my $xmldtd = $BSXML::packagebinaryversionlist;
+  my $elname = 'binaryversionlist';
+  my $jev = $BSServerEvents::gev;
+  my $binaryversionlist;
+  $binaryversionlist = $jev->{'binaryversionlist'} if $BSStdServer::isajax;
+  $binaryversionlist ||= {};
+  $jev->{'binaryversionlist'} = $binaryversionlist if $BSStdServer::isajax;
+  my @missing = grep {!exists $binaryversionlist->{$_}} @$packages;
+  while (@missing) {
+    # chunk it
+    my $chunkl = 0;
+    for (splice @missing) {
+      $chunkl += 9 + length($_);
+      last if @missing && $chunkl > 1900;
+      push @missing, $_;
+    }
+    my $param = {
+     'uri' => "$proj->{'remoteurl'}/build/$proj->{'remoteproject'}/$repoid/$arch",
+     'proxy' => $proj->{'remoteproxy'},
+    };
+    my @args = ("view=$view");
+    push @args, map {"package=$_"} @missing;
+    my $pbvl = BSWatcher::rpc($param, $xmldtd, @args);
+    return undef if $BSStdServer::isajax && !$pbvl;
+    for (@{$pbvl->{$elname} || []}) {
+      $binaryversionlist->{$_->{'package'}} = $_;
+    }
+    $binaryversionlist->{$_} ||= undef for @missing;
+    @missing = grep {!exists $binaryversionlist->{$_}} @$packages;
+  }
+  return { $elname => [ map {$binaryversionlist->{$_}} grep {$binaryversionlist->{$_}} @$packages ] };
+}
 
 sub getremotebinaries_cache {
   my ($projid, $repoid, $arch, $binaries, $binarylist) = @_;
diff --git a/src/backend/bs_srcserver b/src/backend/bs_srcserver
index e4adfcc10c..86aace276c 100755
--- a/src/backend/bs_srcserver
+++ b/src/backend/bs_srcserver
@@ -3950,6 +3950,11 @@ sub getpackagelist_build {
       if (!$BSStdServer::isajax) {
 	BSHandoff::handoff("/build/$projid/$repoid/$arch", undef, @args);
       }
+      my $view = $cgi->{'view'};
+      if (@{$cgi->{'package'} || []} && ($view eq 'binaryversions' || $view eq 'binaryversionscode')) {
+	my $pbvl = BSSrcServer::Remote::getpackagebinaryversionlist($proj, $projid, $repoid, $arch, $cgi->{'package'}, $view);
+	return ($pbvl, $BSXML::packagebinaryversionlist);
+      }
       $param->{'uri'} = "$proj->{'remoteurl'}/build/$proj->{'remoteproject'}/$repoid/$arch";
       $param->{'proxy'} = $proxy;
     }
-- 
GitLab