http-client: Add 'http-fetch/cached'.
* guix/utils.scm (cache-directory): New procedure. * guix/http-client.scm (%http-cache-ttl): New variable. (http-fetch/cached): New procedure.
This commit is contained in:
parent
34a7bfb049
commit
739ab68bac
|
@ -23,6 +23,8 @@
|
||||||
#:use-module ((web client) #:hide (open-socket-for-uri))
|
#:use-module ((web client) #:hide (open-socket-for-uri))
|
||||||
#:use-module (web response)
|
#:use-module (web response)
|
||||||
#:use-module (srfi srfi-11)
|
#:use-module (srfi srfi-11)
|
||||||
|
#:use-module (srfi srfi-19)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
#:use-module (srfi srfi-34)
|
#:use-module (srfi srfi-34)
|
||||||
#:use-module (srfi srfi-35)
|
#:use-module (srfi srfi-35)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
|
@ -30,6 +32,8 @@
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
#:use-module (guix utils)
|
#:use-module (guix utils)
|
||||||
|
#:use-module ((guix build utils)
|
||||||
|
#:select (mkdir-p dump-port))
|
||||||
#:use-module ((guix build download)
|
#:use-module ((guix build download)
|
||||||
#:select (open-socket-for-uri resolve-uri-reference))
|
#:select (open-socket-for-uri resolve-uri-reference))
|
||||||
#:re-export (open-socket-for-uri)
|
#:re-export (open-socket-for-uri)
|
||||||
|
@ -39,7 +43,10 @@
|
||||||
http-get-error-code
|
http-get-error-code
|
||||||
http-get-error-reason
|
http-get-error-reason
|
||||||
|
|
||||||
http-fetch))
|
http-fetch
|
||||||
|
|
||||||
|
%http-cache-ttl
|
||||||
|
http-fetch/cached))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
|
@ -229,4 +236,51 @@ Raise an '&http-get-error' condition if downloading fails."
|
||||||
(&message
|
(&message
|
||||||
(message "download failed"))))))))))
|
(message "download failed"))))))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Caching.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (%http-cache-ttl)
|
||||||
|
;; Time-to-live in seconds of the HTTP cache of in ~/.cache/guix.
|
||||||
|
(make-parameter
|
||||||
|
(* 3600 (or (and=> (getenv "GUIX_HTTP_CACHE_TTL")
|
||||||
|
string->number*)
|
||||||
|
36))))
|
||||||
|
|
||||||
|
(define* (http-fetch/cached uri #:key (ttl (%http-cache-ttl)) text?)
|
||||||
|
"Like 'http-fetch', return an input port, but cache its contents in
|
||||||
|
~/.cache/guix. The cache remains valid for TTL seconds."
|
||||||
|
(let* ((directory (string-append (cache-directory) "/http/"
|
||||||
|
(uri-host uri)))
|
||||||
|
(file (string-append directory "/"
|
||||||
|
(basename (uri-path uri)))))
|
||||||
|
(define (update-cache)
|
||||||
|
;; Update the cache and return an input port.
|
||||||
|
(let ((port (http-fetch uri #:text? text?)))
|
||||||
|
(mkdir-p directory)
|
||||||
|
(call-with-output-file file
|
||||||
|
(cut dump-port port <>))
|
||||||
|
(close-port port)
|
||||||
|
(open-input-file file)))
|
||||||
|
|
||||||
|
(define (old? port)
|
||||||
|
;; Return true if PORT has passed TTL.
|
||||||
|
(let* ((s (stat port))
|
||||||
|
(now (current-time time-utc)))
|
||||||
|
(< (+ (stat:mtime s) ttl) (time-second now))))
|
||||||
|
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
(let ((port (open-input-file file)))
|
||||||
|
(if (old? port)
|
||||||
|
(begin
|
||||||
|
(close-port port)
|
||||||
|
(update-cache))
|
||||||
|
port)))
|
||||||
|
(lambda args
|
||||||
|
(if (= ENOENT (system-error-errno args))
|
||||||
|
(update-cache)
|
||||||
|
(apply throw args))))))
|
||||||
|
|
||||||
;;; http-client.scm ends here
|
;;; http-client.scm ends here
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
fold-tree
|
fold-tree
|
||||||
fold-tree-leaves
|
fold-tree-leaves
|
||||||
split
|
split
|
||||||
|
cache-directory
|
||||||
|
|
||||||
filtered-port
|
filtered-port
|
||||||
compressed-port
|
compressed-port
|
||||||
|
@ -703,6 +704,12 @@ elements after E."
|
||||||
((head . tail)
|
((head . tail)
|
||||||
(loop tail (cons head acc))))))
|
(loop tail (cons head acc))))))
|
||||||
|
|
||||||
|
(define (cache-directory)
|
||||||
|
"Return the cache directory for Guix, by default ~/.cache/guix."
|
||||||
|
(or (getenv "XDG_CONFIG_HOME")
|
||||||
|
(and=> (getenv "HOME")
|
||||||
|
(cut string-append <> "/.cache/guix"))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Source location.
|
;;; Source location.
|
||||||
|
|
Loading…
Reference in New Issue