unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: Christopher Baines <mail@cbaines.net>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: 47288@debbugs.gnu.org
Subject: [bug#47288] [PATCH] guix: http-client: Tweak http-multiple-get error handling.
Date: Thu, 25 Mar 2021 11:09:04 +0000	[thread overview]
Message-ID: <87zgyra3sg.fsf@cbaines.net> (raw)
In-Reply-To: <87pmzoeh3p.fsf_-_@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 3664 bytes --]


Ludovic Courtès <ludo@gnu.org> writes:

> As discussed at <https://issues.guix.gnu.org/47283>, I’m still unsure
> these exceptions need to be caught within ‘http-multiple-get’ and at
> each iteration.
>
> Just minor comments:
>
> Christopher Baines <mail@cbaines.net> skribis:
>
>> +               (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)
>> +                        (list 'connect
>> +                              #f
>>                                (drop requests (+ 1 processed))
>>                                result))
>> -                   (apply throw key args))))))))))
>> +                       (_
>> +                        (list 'loop tail (+ 1 processed) 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)
>> +                         (list 'connect
>> +                               #f
>> +                               requests
>> +                               result))
>> +                       (apply throw key args))))
>> +             (('connect . args)
>> +              (apply connect args))
>> +             (('loop . args)
>> +              (apply loop args)))))))))
>
> This is not new to this patch, but I think the whole exception handling
> bit should be factorized and written in such a way that
> ‘http-multiple-get’ still first on a horizontal screen (even though mine
> is actually vertical :-)).  Otherwise one might easily overlook the core
> logic of the function.

I've sent a v3 now, which makes a few changes to the original patch, and
includes a second patch for a potential refactoring.

I tested three variants for performance, http-multiple-get with no error
handling, the first v3 patch and the first and second v3 patches, and at
least with the test I'm using, the performance seems similar. Assuming
the performance is lower with error handling, the impact seems to be
within the margin of error, at least for test I was using.


[-- Attachment #1.2: http-multiple-get-perf.scm --]
[-- Type: text/plain, Size: 1406 bytes --]

(use-modules (ice-9 binary-ports)
             (srfi srfi-19)
             (web uri)
             (web request)
             (web response)
             (guix http-client))

(define (call-with-time-logging requests thunk)
  (let ((start   (current-time time-utc)))
    (call-with-values
        thunk
      (lambda vals
        (let* ((end     (current-time time-utc))
               (elapsed (time-difference end start)))
          (display
           (format #f
                   "~f seconds (~f microseconds per request)~%"
                   (+ (time-second elapsed)
                      (/ (time-nanosecond elapsed) 1e9))
                   (* (/ (+ (time-second elapsed)
                            (/ (time-nanosecond elapsed) 1e9))
                         requests)
                      1e6)))
          (apply values vals))))))

(define requests
  (map (lambda _
         (build-request (string->uri "http://localhost/does-not-exist")
                        #:method 'GET))
       (iota 200000)))

(call-with-time-logging
 (length requests)
 (lambda ()
   (http-multiple-get (string->uri "http://localhost/")
                      (lambda (request response port result)
                        (get-bytevector-n
                         port
                         (response-content-length response))
                        '())
                      '()
                      requests)))

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 987 bytes --]

  reply	other threads:[~2021-03-25 11:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-21  0:43 [bug#47288] [PATCH] guix: http-client: Tweak http-multiple-get error handling Christopher Baines
2021-03-21  0:56 ` [bug#47288] [PATCH v2] " Christopher Baines
2021-03-24 14:55   ` [bug#47288] [PATCH] " Ludovic Courtès
2021-03-25 11:09     ` Christopher Baines [this message]
2021-03-24 14:55   ` Ludovic Courtès
2021-03-21  8:36 ` Maxime Devos
2021-03-25 11:03 ` [bug#47288] [PATCH v3 1/2] " Christopher Baines
2021-03-25 11:03   ` [bug#47288] [PATCH v3 2/2] guix: http-client: Refactor http-multiple-get Christopher Baines
2021-03-25 22:20   ` [bug#47288] [PATCH] guix: http-client: Tweak http-multiple-get error handling Ludovic Courtès
2021-03-26  8:39     ` Christopher Baines
2021-03-27 17:15       ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zgyra3sg.fsf@cbaines.net \
    --to=mail@cbaines.net \
    --cc=47288@debbugs.gnu.org \
    --cc=ludo@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).