mirror of
https://github.com/penpot/penpot.git
synced 2025-06-12 22:11:39 +02:00
♻️ Remove all usage of graalvm js runtime
And replace it with a commandline call to nodejs for execute a custom svgo based command line script.
This commit is contained in:
parent
15b33488c6
commit
cc6e071f48
17 changed files with 576 additions and 40723 deletions
|
@ -41,6 +41,7 @@
|
|||
[app.common.types.shape.path :as ctsp]
|
||||
[app.common.types.shape.text :as ctsx]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.db.sql :as sql]
|
||||
[app.features.fdata :as fdata]
|
||||
|
@ -1381,7 +1382,9 @@
|
|||
(defn get-optimized-svg
|
||||
[sid]
|
||||
(let [svg-text (get-sobject-content sid)
|
||||
svg-text (svgo/optimize *system* svg-text)]
|
||||
svg-text (if (contains? cf/flags :backend-svgo)
|
||||
(svgo/optimize *system* svg-text)
|
||||
svg-text)]
|
||||
(csvg/parse svg-text)))
|
||||
|
||||
(def base-path "/data/cache")
|
||||
|
@ -1484,11 +1487,6 @@
|
|||
:file-id (str (:id fdata))
|
||||
:id (str (:id mobj)))
|
||||
|
||||
(instance? org.graalvm.polyglot.PolyglotException cause)
|
||||
(l/inf :hint "skip processing media object: invalid svg found"
|
||||
:file-id (str (:id fdata))
|
||||
:id (str (:id mobj)))
|
||||
|
||||
(= (:type edata) :not-found)
|
||||
(l/inf :hint "skip processing media object: underlying object does not exist"
|
||||
:file-id (str (:id fdata))
|
||||
|
|
|
@ -319,7 +319,6 @@
|
|||
::mtx/metrics (ig/ref ::mtx/metrics)
|
||||
::mbus/msgbus (ig/ref ::mbus/msgbus)
|
||||
::rds/redis (ig/ref ::rds/redis)
|
||||
::svgo/optimizer (ig/ref ::svgo/optimizer)
|
||||
|
||||
::rpc/climit (ig/ref ::rpc/climit)
|
||||
::rpc/rlimit (ig/ref ::rpc/rlimit)
|
||||
|
@ -430,9 +429,6 @@
|
|||
;; module requires the migrations to run before initialize.
|
||||
::migrations (ig/ref :app.migrations/migrations)}
|
||||
|
||||
::svgo/optimizer
|
||||
{}
|
||||
|
||||
:app.loggers.audit.archive-task/handler
|
||||
{::setup/props (ig/ref ::setup/props)
|
||||
::db/pool (ig/ref ::db/pool)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.storage.fs
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uri :as u]
|
||||
|
|
|
@ -7,36 +7,32 @@
|
|||
(ns app.svgo
|
||||
"A SVG Optimizer service"
|
||||
(:require
|
||||
[app.common.jsrt :as jsrt]
|
||||
[app.common.logging :as l]
|
||||
[app.worker :as-alias wrk]
|
||||
[integrant.core :as ig]
|
||||
[promesa.exec.semaphore :as ps]
|
||||
[promesa.util :as pu]))
|
||||
[app.util.shell :as shell]
|
||||
[datoteka.fs :as fs]
|
||||
[promesa.exec.semaphore :as ps]))
|
||||
|
||||
(def ^:dynamic *semaphore*
|
||||
"A dynamic variable that can optionally contain a traffic light to
|
||||
appropriately delimit the use of resources, managed externally."
|
||||
nil)
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(defn optimize
|
||||
[{pool ::optimizer} data]
|
||||
[system data]
|
||||
(try
|
||||
(some-> *semaphore* ps/acquire!)
|
||||
(jsrt/run! pool
|
||||
(fn [context]
|
||||
(jsrt/set! context "svgData" data)
|
||||
(jsrt/eval! context "penpotSvgo.optimize(svgData, {plugins: ['safeAndFastPreset']})")))
|
||||
(let [script (fs/join fs/*cwd* "scripts/svgo-cli.js")
|
||||
cmd ["node" (str script)]
|
||||
result (shell/exec! system
|
||||
:cmd cmd
|
||||
:in data)]
|
||||
(if (= (:exit result) 0)
|
||||
(:out result)
|
||||
(do
|
||||
(l/raw! :warn (str "Error on optimizing svg, returning svg as-is." (:err result)))
|
||||
data)))
|
||||
|
||||
(finally
|
||||
(some-> *semaphore* ps/release!))))
|
||||
|
||||
(defmethod ig/init-key ::optimizer
|
||||
[_ _]
|
||||
(l/inf :hint "initializing svg optimizer pool")
|
||||
(let [init (jsrt/resource->source "app/common/svg/optimizer.js")]
|
||||
(jsrt/pool :init init)))
|
||||
|
||||
(defmethod ig/halt-key! ::optimizer
|
||||
[_ pool]
|
||||
(l/info :hint "stopping svg optimizer pool")
|
||||
(pu/close! pool))
|
||||
|
|
71
backend/src/app/util/shell.clj
Normal file
71
backend/src/app/util/shell.clj
Normal file
|
@ -0,0 +1,71 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.util.shell
|
||||
"A penpot specific, modern api for executing external (shell)
|
||||
subprocesses"
|
||||
(:require
|
||||
[app.worker :as-alias wrk]
|
||||
[datoteka.io :as io]
|
||||
[promesa.exec :as px])
|
||||
(:import
|
||||
java.io.InputStream
|
||||
java.io.OutputStream
|
||||
java.util.List
|
||||
org.apache.commons.io.IOUtils))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(defn- read-as-bytes
|
||||
[in]
|
||||
(with-open [^InputStream input (io/input-stream in)]
|
||||
(io/read input)))
|
||||
|
||||
(defn- read-as-string
|
||||
([in] (read-as-string in "UTF-8"))
|
||||
([in enc]
|
||||
(IOUtils/toString ^InputStream in ^String enc)))
|
||||
|
||||
(defn- read-with-enc
|
||||
[stream enc]
|
||||
(if (= enc :bytes)
|
||||
(read-as-bytes stream)
|
||||
(read-as-string stream enc)))
|
||||
|
||||
(defn- set-env
|
||||
[penv k v]
|
||||
(.put ^java.util.Map penv
|
||||
^String k
|
||||
^String v))
|
||||
|
||||
(defn exec!
|
||||
[system & {:keys [cmd in out-enc in-enc env]
|
||||
:or {out-enc "UTF-8"
|
||||
in-enc "UTF-8"}}]
|
||||
(assert (vector? cmd) "a command parameter should be a vector")
|
||||
(assert (every? string? cmd) "the command should be a vector of strings")
|
||||
|
||||
(let [executor (::wrk/executor system)
|
||||
builder (ProcessBuilder. ^List cmd)
|
||||
env-map (.environment ^ProcessBuilder builder)
|
||||
_ (reduce-kv set-env env-map env)
|
||||
process (.start builder)]
|
||||
|
||||
(if in
|
||||
(px/run! executor
|
||||
(fn []
|
||||
(with-open [^OutputStream stdin (.getOutputStream ^Process process)]
|
||||
(io/write stdin in :encoding in-enc))))
|
||||
(io/close (.getOutputStream ^Process process)))
|
||||
|
||||
(with-open [stdout (.getInputStream ^Process process)
|
||||
stderr (.getErrorStream ^Process process)]
|
||||
(let [out (px/submit! executor (fn [] (read-with-enc stdout out-enc)))
|
||||
err (px/submit! executor (fn [] (read-as-string stderr)))
|
||||
ext (.waitFor ^Process process)]
|
||||
{:exit ext
|
||||
:out @out
|
||||
:err @err}))))
|
Loading…
Add table
Add a link
Reference in a new issue