From patchwork Sun Mar 21 00:43:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Baines X-Patchwork-Id: 27994 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 6BEBF27BC58; Sun, 21 Mar 2021 00:44:21 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS,UNPARSEABLE_RELAY autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id B880F27BC57 for ; Sun, 21 Mar 2021 00:44:20 +0000 (GMT) Received: from localhost ([::1]:56830 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lNmCZ-0002Ue-Ss for patchwork@mira.cbaines.net; Sat, 20 Mar 2021 20:44:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58076) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lNmCI-0002UJ-Hf for guix-patches@gnu.org; Sat, 20 Mar 2021 20:44:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:41809) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lNmCI-000305-AJ for guix-patches@gnu.org; Sat, 20 Mar 2021 20:44:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lNmCI-0003GW-7s for guix-patches@gnu.org; Sat, 20 Mar 2021 20:44:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#47288] [PATCH] guix: http-client: Tweak http-multiple-get error handling. Resent-From: Christopher Baines Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 21 Mar 2021 00:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 47288 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 47288@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.161628743112526 (code B ref -1); Sun, 21 Mar 2021 00:44:02 +0000 Received: (at submit) by debbugs.gnu.org; 21 Mar 2021 00:43:51 +0000 Received: from localhost ([127.0.0.1]:53355 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lNmC6-0003Fx-IX for submit@debbugs.gnu.org; Sat, 20 Mar 2021 20:43:50 -0400 Received: from lists.gnu.org ([209.51.188.17]:58442) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lNmC3-0003Fn-EB for submit@debbugs.gnu.org; Sat, 20 Mar 2021 20:43:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58066) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lNmC2-0002SU-JG for guix-patches@gnu.org; Sat, 20 Mar 2021 20:43:46 -0400 Received: from mira.cbaines.net ([2a01:7e00:e000:2f8:fd4d:b5c7:13fb:3d27]:38847) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lNmBy-0002t7-De for guix-patches@gnu.org; Sat, 20 Mar 2021 20:43:46 -0400 Received: from localhost (unknown [IPv6:2a02:8010:68c1:0:8ac0:b4c7:f5c8:7caa]) by mira.cbaines.net (Postfix) with ESMTPSA id 0954327BC57 for ; Sun, 21 Mar 2021 00:43:40 +0000 (GMT) Received: from localhost (localhost [local]) by localhost (OpenSMTPD) with ESMTPA id 886c814a for ; Sun, 21 Mar 2021 00:43:38 +0000 (UTC) From: Christopher Baines Date: Sun, 21 Mar 2021 00:43:38 +0000 Message-Id: <20210321004338.31867-1-mail@cbaines.net> X-Mailer: git-send-email 2.30.1 MIME-Version: 1.0 Received-SPF: pass client-ip=2a01:7e00:e000:2f8:fd4d:b5c7:13fb:3d27; envelope-from=mail@cbaines.net; helo=mira.cbaines.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches This isn't meant to change the way errors are handled, and arguably makes the code harder to read, but it's a uninformed attempt to improve the performance (following on from a performance regression in 205833b72c5517915a47a50dbe28e7024dc74e57). I'm guessing something about Guile internals makes calling (loop ...) within the catch bit less performant than avoiding this and calling (loop ...) after the catch bit has finished. Since this happens lots, this seems to be sufficient to make guix weather a lot slower than it was before. Anecdotal testing of guix weather suggests this change might work. * guix/http-client.scm (http-multiple-get): Tweak how the second catch statement works. --- guix/http-client.scm | 77 +++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/guix/http-client.scm b/guix/http-client.scm index 4b4c14ed0b..a189cceecf 100644 --- a/guix/http-client.scm +++ b/guix/http-client.scm @@ -219,42 +219,47 @@ returning." (remainder (connect p remainder result)))) ((head tail ...) - (catch #t - (lambda () - (let* ((resp (read-response p)) - (body (response-body-port resp)) - (result (proc head resp body result))) - ;; The server can choose to stop responding at any time, - ;; in which case we have to try again. Check whether - ;; that is the case. Note that even upon "Connection: - ;; close", we can read from BODY. - (match (assq 'connection (response-headers resp)) - (('connection 'close) - (close-port p) - (connect #f ;try again - (drop requests (+ 1 processed)) - result)) - (_ - (loop tail (+ 1 processed) result))))) ;keep going - (lambda (key . args) - ;; If PORT was cached and the server closed the connection - ;; in the meantime, we get EPIPE. In that case, open a - ;; fresh connection and retry. We might also get - ;; 'bad-response or a similar exception from (web response) - ;; later on, once we've sent the request, or a - ;; ERROR/INVALID-SESSION from GnuTLS. - (if (or (and (eq? key 'system-error) - (= EPIPE (system-error-errno `(,key ,@args)))) - (and (eq? key 'gnutls-error) - (eq? (first args) error/invalid-session)) - (memq key - '(bad-response bad-header bad-header-component))) - (begin - (close-port p) - (connect #f ; try again - (drop requests (+ 1 processed)) - result)) - (apply throw key args)))))))))) + (match + (catch #t + (lambda () + (let* ((resp (read-response p)) + (body (response-body-port resp)) + (result (proc head resp body result))) + ;; The server can choose to stop responding at any time, + ;; in which case we have to try again. Check whether + ;; that is the case. Note that even upon "Connection: + ;; close", we can read from BODY. + (match (assq 'connection (response-headers resp)) + (('connection 'close) + (close-port p) + 'try-again-with-new-connection) + (_ + result)))) + (lambda (key . args) + ;; If PORT was cached and the server closed the connection + ;; in the meantime, we get EPIPE. In that case, open a + ;; fresh connection and retry. We might also get + ;; 'bad-response or a similar exception from (web response) + ;; later on, once we've sent the request, or a + ;; ERROR/INVALID-SESSION from GnuTLS. + (if (or (and (eq? key 'system-error) + (= EPIPE (system-error-errno `(,key ,@args)))) + (and (eq? key 'gnutls-error) + (eq? (first args) error/invalid-session))1 + (memq key + '(bad-response + bad-header + bad-header-component))) + (begin + (close-port p) + 'try-again-with-new-connection) + (apply throw key args)))) + ('try-again-with-new-connection + (connect #f + (drop requests (+ 1 processed)) + result)) + (result + (loop tail (+ 1 processed) result))))))))) ;;;