<commit_before>#lang scheme/base

(require scheme/file)

;; This module should be invoked when we're in the server directory
(provide server-dir)
(define server-dir
  (let ([dir (or (getenv "PLT_HANDINSERVER_DIR") (current-directory))])
    (if (directory-exists? dir)
      dir
      (error 'config "handin server directory does not exist: ~e" dir))))

(define config-file (path->complete-path "config.ss" server-dir))

(define poll-freq 2000.0) ; poll at most once every two seconds

(define last-poll     #f)
(define last-filetime #f)
(define raw-config    #f)
(define config-cache  #f)

(provide get-conf)
(define (get-conf key)
  (unless (and raw-config
               (< (- (current-inexact-milliseconds) last-poll) poll-freq))
    (set! last-poll (current-inexact-milliseconds))
    (let ([filetime (file-or-directory-modify-seconds config-file)])
      (unless (and filetime (equal? filetime last-filetime))
        (set! last-filetime filetime)
        (set! raw-config
              (with-handlers ([void (lambda (e)
                                      (error 'get-conf
                                             "could not read conf (~a): ~a"
                                             config-file
                                             (exn-message e)))])
                (when raw-config
                  ;; can't use log-line from logger, since it makes a cycle
                  (fprintf (current-error-port)
                           (format "loading configuration from ~a\n"
                                   config-file)))
                (with-input-from-file config-file read)))
        (set! config-cache (make-hasheq)))))
  (hash-ref config-cache key
    (lambda ()
      (let*-values ([(default translate) (config-default+translate key)]
                    ;; translate = #f => this is a computed value<commit_msg>* A little better layout for configuration reading code * Improved comment about it * Use `raise-user-error' to avoid redundant context printout * Check that the configuration content is a proper alist<commit_after>#lang scheme/base

(require scheme/file)

;; This module should be invoked when we're in the server directory
(provide server-dir)
(define server-dir
  (let ([dir (or (getenv "PLT_HANDINSERVER_DIR") (current-directory))])
    (if (directory-exists? dir)
      dir
      (error 'config "handin server directory does not exist: ~e" dir))))

(define config-file (path->complete-path "config.ss" server-dir))

(define poll-freq 2000.0) ; poll at most once every two seconds

(define last-poll     #f)
(define last-filetime #f)
(define raw-config    #f)
(define config-cache  #f)

(provide get-conf)
(define (get-conf key)
  (unless (and raw-config
               (< (- (current-inexact-milliseconds) last-poll) poll-freq))
    (set! last-poll (current-inexact-milliseconds))
    (let ([filetime (file-or-directory-modify-seconds config-file)])
      (unless (and filetime (equal? filetime last-filetime))
        (set! last-filetime filetime)
        (with-handlers
            ([void (lambda (e)
                     (raise-user-error 'get-conf "could not read conf (~a): ~a"
                                       config-file (exn-message e)))])
          (when raw-config
            ;; can't use log-line from logger, since it makes a cycle,
            ;; but make sure it's written in one shot; in any case, don't
            ;; write anything if this is the first read, since the logger
            ;; is not initialized yet (and if there's an error at this
            ;; stage, the server will exit)
            (fprintf (current-error-port)
                     (format "reloading configuration from ~a\n"
                             config-file)))
          (let ([c (with-input-from-file config-file read)])
            (if (and (list? c)
                     (andmap (lambda (x)
                               (and (pair? x) (symbol? (car x))))
                             c))
              (set! raw-config c)
              (error "malformed configuration file content"))))
        (set! config-cache (make-hasheq)))))
  (hash-ref config-cache key
    (lambda ()
      (let*-values ([(default translate) (config-default+translate key)]
                    ;; translate = #f => this is a computed value
{'fraction_non_alphanumeric': 0.11843027330063069, 'fraction_numerical': 0.00233590282644242, 'mean_word_length': 2.0091356289529165, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3211500', 'n_tokens_mistral': 1227, 'n_tokens_neox': 1176, 'n_words': 392}