From 5a563d2d57a854e216d05263fe299cc6ad1e57cb Mon Sep 17 00:00:00 2001 From: Ambrose Bonnaire-Sergeant Date: Tue, 1 Aug 2023 11:56:01 -0400 Subject: [PATCH] fix memory leaks in multimethod default dispatch caches --- .github/workflows/clojure.yml | 83 ++++++++++++++++++++++++++++ .travis.yml | 10 ---- CHANGELOG.md | 4 ++ project.clj | 13 +++-- src/ring/swagger/coerce.clj | 12 +++- test/ring/swagger/extension_test.clj | 6 +- 6 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/clojure.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/clojure.yml b/.github/workflows/clojure.yml new file mode 100644 index 00000000..687986c8 --- /dev/null +++ b/.github/workflows/clojure.yml @@ -0,0 +1,83 @@ +--- +name: Run tests + +on: + push: + branches: [master] + pull_request: + branches: [master] + +env: + ACTIONS_CACHE_VERSION: 0 + +jobs: + test: + strategy: + matrix: + jdk: [8, 11, 17, 20] + + name: Java ${{ matrix.jdk }} + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup Java ${{ matrix.jdk }} + uses: actions/setup-java@v3.11.0 + with: + distribution: temurin + java-version: ${{ matrix.jdk }} + - name: Maven Cache + id: maven-cache + uses: actions/cache@v3 + with: + path: | + ~/.m2/repository + ~/.gitlibs + key: m2-cache-${{ env.ACTIONS_CACHE_VERSION }}-${{ hashFiles('project.clj') }}-${{ matrix.jdk }} + restore-keys: | + m2-cache-${{ env.ACTIONS_CACHE_VERSION }}-${{ hashFiles('project.clj') }}- + m2-cache-${{ env.ACTIONS_CACHE_VERSION }}- + - name: Setup Clojure + uses: DeLaGuardo/setup-clojure@master + with: + lein: latest + - name: Run tests + run: lein do clean, all midje, all check + deploy: + concurrency: deploy + needs: test + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/project.clj') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Prepare java + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: '11' + - name: deploy + env: + CLOJARS_USER: 'threatgrid-clojars' + CLOJARS_TOKEN: ${{ secrets.CLOJARS_TOKEN }} + COMMIT_MSG: ${{ github.event.head_commit.message }} + run: | + git config --global user.email "threatgrid@cisco.com" + git config --global user.name "Threatgrid" + if [[ "$COMMIT_MSG" == "Release :major" ]]; then + lein release :major + elif [[ "$COMMIT_MSG" == "Release :minor" ]]; then + lein release :minor + elif [[ "$COMMIT_MSG" == "Release :patch" ]]; then + lein release :patch + else + lein deploy snapshot + fi diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ef08218d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -sudo: false -language: clojure -lein: 2.9.1 -script: lein do clean, all midje, all check -jdk: - - openjdk8 - - oraclejdk11 -cache: - directories: - - $HOME/.m2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0875ab7e..31224ec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [threatgrid] 0.26.3 (?) + +* Fix memory leaks via multimethods caching default dispatch values + ## 0.26.2 (1.4.2019) * `s/eq` is mapped into enum by [Joel Kaasinen](https://github.com/opqdonut). diff --git a/project.clj b/project.clj index 1bf319e3..8d994167 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/ring-swagger "0.26.2" +(defproject io.github.threatgrid/ring-swagger "0.26.3-SNAPSHOT" :description "Swagger Spec for Ring Apps" :url "https://github.com/metosin/ring-swagger" :license {:name "Eclipse Public License" @@ -20,18 +20,21 @@ [lein-ring "0.12.5"] [lein-midje "3.2.1"] [funcool/codeina "0.5.0"]] - :dependencies [[org.clojure/clojure "1.8.0"] + :dependencies [[org.clojure/clojure "1.11.1"] [midje "1.9.6" :exclusions [org.clojure/clojure commons-codec]] [ring-mock "0.1.5"] [metosin/ring-swagger-ui "3.20.1"] [javax.servlet/javax.servlet-api "4.0.1"]]} :1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]} - :1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]}} + :1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]} + :1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]} + :1.10 {:dependencies [[org.clojure/clojure "1.10.1"]]} + :1.12 {:dependencies [[org.clojure/clojure "1.12.0-alpha4"]]}} :codeina {:sources ["src"] :target "gh-pages/doc" - :src-uri "http://github.com/metosin/ring-swagger/blob/master/" + :src-uri "https://github.com/threatgrid/ring-swagger/blob/master/" :src-uri-prefix "#L"} :deploy-repositories [["releases" :clojars]] - :aliases {"all" ["with-profile" "dev:dev,1.7:dev,1.9"] + :aliases {"all" ["with-profile" "dev:dev,1.7:dev,1.8:dev,1.9:dev,1.10:dev,1.12"] "test-ancient" ["midje"]}) diff --git a/src/ring/swagger/coerce.clj b/src/ring/swagger/coerce.clj index dcd4992d..9f571bfe 100644 --- a/src/ring/swagger/coerce.clj +++ b/src/ring/swagger/coerce.clj @@ -26,7 +26,9 @@ (declare custom-matcher) -(defmulti time-matcher identity) +(defmulti time-matcher (if (= "true" (System/getProperty "ring.swagger.coerce.identity-time-matcher-dispatch")) + identity + #(when (class? %) %))) (defn coerce-if-string [f] (fn [x] (if (string? x) (f x) x))) @@ -175,10 +177,14 @@ ;; Public Api ;; -(defmulti custom-matcher identity) +(defmulti custom-matcher (if (= "true" (System/getProperty "ring.swagger.coerce.identity-custom-matcher-dispatch")) + identity + #(when (class? %) %))) (defmethod custom-matcher :default [_] nil) -(defmulti coercer identity) +(defmulti coercer (if (= "true" (System/getProperty "ring.swagger.coerce.identity-coercer-dispatch")) + identity + #(when (keyword? %) %))) (defmethod coercer :json [_] json-schema-coercion-matcher) (defmethod coercer :query [_] query-schema-coercion-matcher) diff --git a/test/ring/swagger/extension_test.clj b/test/ring/swagger/extension_test.clj index f891fe06..dc2a19a4 100644 --- a/test/ring/swagger/extension_test.clj +++ b/test/ring/swagger/extension_test.clj @@ -22,7 +22,8 @@ (fact "undefined vars/classes are ignored in disabled extensions" (resolve 'a) => nil (disabled (a)) =not=> (throws Exception) - (resolve 'dummy.Class) => (throws ClassNotFoundException) + (try (resolve 'dummy.Class) + (catch ClassNotFoundException _)) => nil (disabled (dummy.Class)) =not=> (throws Exception))) (fact "java-time extension" @@ -34,4 +35,5 @@ (extension/java-time :a) => :a) (fact "skips the enclosed form" (extension/java-time :a) => nil - (resolve 'java.time.Instant) => (throws ClassNotFoundException))))) + (try (resolve 'java.time.Instant) + (catch ClassNotFoundException _)) => nil))))