Merge branch 'main' from workbench2.git
[arvados.git] / lib / controller / federation / conn.go
index 7a9f7cb9990ee30b8af12d150521ec1a586dcc9d..b4b747644061774ef6b4fb6b837e2035ad3774b0 100644 (file)
@@ -178,20 +178,29 @@ func (conn *Conn) tryLocalThenRemotes(ctx context.Context, forwardedFor string,
                        errchan <- fn(ctx, remoteID, be)
                }()
        }
-       all404 := true
+       returncode := http.StatusNotFound
        var errs []error
        for i := 0; i < cap(errchan); i++ {
                err := <-errchan
                if err == nil {
                        return nil
                }
-               all404 = all404 && errStatus(err) == http.StatusNotFound
                errs = append(errs, err)
+               if code := errStatus(err); code >= 500 || code == http.StatusTooManyRequests {
+                       // If any of the remotes have a retryable
+                       // error (and none succeed) we'll return 502.
+                       returncode = http.StatusBadGateway
+               } else if code != http.StatusNotFound && returncode != http.StatusBadGateway {
+                       // If some of the remotes have non-retryable
+                       // non-404 errors (and none succeed or have
+                       // retryable errors) we'll return 422.
+                       returncode = http.StatusUnprocessableEntity
+               }
        }
-       if all404 {
+       if returncode == http.StatusNotFound {
                return notFoundError{}
        }
-       return httpErrorf(http.StatusBadGateway, "errors: %v", errs)
+       return httpErrorf(returncode, "errors: %v", errs)
 }
 
 func (conn *Conn) CollectionCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Collection, error) {
@@ -405,10 +414,6 @@ func (conn *Conn) ContainerUnlock(ctx context.Context, options arvados.GetOption
        return conn.chooseBackend(options.UUID).ContainerUnlock(ctx, options)
 }
 
-func (conn *Conn) ContainerLog(ctx context.Context, options arvados.ContainerLogOptions) (http.Handler, error) {
-       return conn.chooseBackend(options.UUID).ContainerLog(ctx, options)
-}
-
 func (conn *Conn) ContainerSSH(ctx context.Context, options arvados.ContainerSSHOptions) (arvados.ConnectionResponse, error) {
        return conn.chooseBackend(options.UUID).ContainerSSH(ctx, options)
 }
@@ -479,6 +484,10 @@ func (conn *Conn) ContainerRequestDelete(ctx context.Context, options arvados.De
        return conn.chooseBackend(options.UUID).ContainerRequestDelete(ctx, options)
 }
 
+func (conn *Conn) ContainerRequestLog(ctx context.Context, options arvados.ContainerLogOptions) (http.Handler, error) {
+       return conn.chooseBackend(options.UUID).ContainerRequestLog(ctx, options)
+}
+
 func (conn *Conn) GroupCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Group, error) {
        return conn.chooseBackend(options.ClusterID).GroupCreate(ctx, options)
 }