I have a bug against Racket Mode that was very surprising and confusing to me: #768. A situation with many instantiate-linklet: mismatch errors in color-lexers.
I believe I finally boiled it down concurrency when using read-language, as well as calling the returned get-info procedure with e.g. a color-lexer key, which loads modules.
At first I fixed (?) this using a general purpose semaphore. Then I remembered something about a module registry lock, i.e. namespace-call-with-registry-lock, which also fixes it (AFAICT).
Here's a minimal-ish example:
#lang racket/base
(define source "#lang rhombus\ndef value = 1\n")
(define (read-language-and-get-color-lexer)
(define get-info (read-language (open-input-string source)))
(get-info 'color-lexer #f))
(define (read-language-and-get-color-lexer/with-lock)
(namespace-call-with-registry-lock (current-namespace)
read-language-and-get-color-lexer))
;; Change this to see many errors, or not. Note that, after running
;; with #t, a given REPL session may produce errors even with
;; #f, until you refresh the session and get a new namespace.
(define want-to-see-many-instantiate-linklet-errors? #t) ;; <====
(for ([_ 5])
(thread (if want-to-see-many-instantiate-linklet-errors?
read-language-and-get-color-lexer
read-language-and-get-color-lexer/with-lock)))
(sleep 1)
;; Background story:
;; https://github.com/greghendershott/racket-mode/issues/768
The concurrency vulnerable spot seems to be between calling read-language and calling the returned get-info procedure value -- another thread could muck with the namespace's module registry, there?
Beside sharing the experience, I guess my questions are:
-
Is this as-expected -- use of
read-languageby multiple threads should be guarded by the module registry lock? (Or, using a distinctcurrent-namespacefor each thread.) IOW does it sound like I finally arrived at the likely solution? -
If so, should I do a doc PR for
read-languageto point this out, as a hint (or is that considered too obvious, and/or the consumers of this documentation too few, to make it worthwhile)?