Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[java] Remove orchard.java.parser #298

Merged
merged 3 commits into from
Oct 25, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[misc] Add with-lock macro
alexander-yakushev committed Oct 25, 2024
commit 4cca2e1d7492893c7e2487f97b30220e7be4b7f1
25 changes: 12 additions & 13 deletions src/orchard/clojuredocs.clj
Original file line number Diff line number Diff line change
@@ -6,14 +6,15 @@
[clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.string :as string]
[orchard.misc :refer [with-lock]]
[orchard.util.os :as os])
(:import
(java.net URI)
(javax.net.ssl HttpsURLConnection)
(java.util.concurrent.locks ReentrantLock)))

(def cache (atom {}))
(def ^:private ^ReentrantLock lock
(def ^:private lock
"Lock to prevent concurrent loading and parsing of Clojuredocs data and writing
it into cache. This lock provides only efficiency benefits and is not
necessary for correct behavior as accessing atom that contains immutable data
@@ -66,14 +67,13 @@
{:added "0.5"}
[]
;; Prevent multiple threads from trying to load the cache simultaneously.
(.lock lock)
(try (when (empty? @cache)
(let [cache-file (io/file cache-file-name)]
(load-cache-file!
(if (.exists cache-file)
cache-file
(io/resource "clojuredocs/export.edn")))))
(finally (.unlock lock))))
(with-lock lock
(when (empty? @cache)
(let [cache-file (io/file cache-file-name)]
(load-cache-file!
(if (.exists cache-file)
cache-file
(io/resource "clojuredocs/export.edn")))))))

(defn update-cache!
"Load exported docs file from ClojureDocs, and store it as a cache.
@@ -84,10 +84,9 @@
(update-cache! default-edn-file-url))
([export-edn-url]
(let [cache-file (io/file cache-file-name)]
(.lock lock)
(try (write-cache-file! export-edn-url)
(load-cache-file! cache-file)
(finally (.unlock lock))))))
(with-lock lock
(write-cache-file! export-edn-url)
(load-cache-file! cache-file)))))

(defn clean-cache!
"Clean the cached ClojureDocs export file and the in memory cache."
5 changes: 3 additions & 2 deletions src/orchard/java/parser_next.clj
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
(com.sun.source.doctree BlockTagTree DocCommentTree EndElementTree
LinkTree LiteralTree ParamTree ReturnTree
StartElementTree TextTree ThrowsTree)
(java.util.concurrent.locks ReentrantLock)
(javax.lang.model.element Element ElementKind ExecutableElement TypeElement VariableElement)
(javax.lang.model.type ArrayType TypeKind TypeVariable)
(jdk.javadoc.doclet DocletEnvironment)))
@@ -298,7 +299,7 @@
(parse-info* [o env]
(parse-variable-element o env)))

(def lock (Object.))
(def ^:private lock (ReentrantLock.))

(defn source-info
"If the source for the Java class is available on the classpath, parse it
@@ -307,7 +308,7 @@
same structure as that of `orchard.java/reflect-info`."
[klass]
{:pre [(symbol? klass)]}
(locking lock ;; the jdk.javadoc.doclet classes aren't meant for concurrent modification/access.
(misc/with-lock lock ;; the jdk.javadoc.doclet classes aren't meant for concurrent modification/access.
(when-let [path (source-path klass)]
(when-let [^DocletEnvironment root (parse-java path (module-name klass))]
(try
12 changes: 11 additions & 1 deletion src/orchard/misc.clj
Original file line number Diff line number Diff line change
@@ -4,7 +4,9 @@
(:require
[clojure.java.io :as io]
[clojure.string :as string]
[orchard.util.io :as util.io]))
[orchard.util.io :as util.io])
(:import
(java.util.concurrent.locks ReentrantLock)))

(defn os-windows? []
(.startsWith (System/getProperty "os.name") "Windows"))
@@ -68,6 +70,14 @@
(as-sym n)
sym))

(defmacro with-lock
"Like `clojure.core/locking`, but for java.util.concurrent.locks.Lock."
[lock & body]
`(let [^ReentrantLock l# ~lock]
(.lock l#)
(try ~@body
(finally (.unlock l#)))))

(defn update-vals
"Update the values of map `m` via the function `f`."
[f m]