diff options
author | Arun Isaac | 2023-09-25 23:43:23 +0100 |
---|---|---|
committer | Arun Isaac | 2023-09-25 23:49:38 +0100 |
commit | 4b0ce31c5f139d371af1b063f83cf980e06fabaf (patch) | |
tree | 91166071aecdf4ccc38b7edba4c12ef68ccde554 | |
parent | cc386c2765e0fd705fee8f26fcb13aa9907f84db (diff) | |
download | rent-in-london-4b0ce31c5f139d371af1b063f83cf980e06fabaf.tar.gz rent-in-london-4b0ce31c5f139d371af1b063f83cf980e06fabaf.tar.lz rent-in-london-4b0ce31c5f139d371af1b063f83cf980e06fabaf.zip |
Ensure atomic writes to cache.
* rent.scm (call-with-atomic-output-file): New function.
(http-get*): Use call-with-atomic-output-file instead of
call-with-output-file.
-rw-r--r-- | rent.scm | 20 |
1 files changed, 18 insertions, 2 deletions
@@ -1,5 +1,5 @@ ;;; rent-in-london --- Shortlist houses to rent in London -;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net> +;;; Copyright © 2022, 2023 Arun Isaac <arunisaac@systemreboot.net> ;;; ;;; This program is free software: you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as @@ -61,6 +61,22 @@ (define %tfl-base-url "https://api.tfl.gov.uk") +(define (call-with-atomic-output-file filename proc) + "Open @var{filename} for output and pass the open port to +@var{proc}. Writes to @var{filename} are guaranteed to be atomic." + (let* ((temporary-port (mkstemp "rent-XXXXXX")) + (temporary-filename (port-filename temporary-port))) + (dynamic-wind + (const #t) + (lambda () + (call-with-port temporary-port + (lambda _ + (proc temporary-port) + (fsync temporary-port))) + (rename-file temporary-filename filename)) + (lambda () + (false-if-exception (delete-file temporary-filename)))))) + (define (json-ref scm . keys) (match keys ((key other-keys ...) @@ -207,7 +223,7 @@ (> (current-time) (+ (stat:mtime (stat cache-file)) cache-live-time)))) - (call-with-output-file cache-file + (call-with-atomic-output-file cache-file (cut put-bytevector <> (http-get-follow uri)))) ;; Return contents of cache. (call-with-input-file cache-file |