mirror of
https://github.com/penpot/penpot.git
synced 2025-05-19 09:36:11 +02:00
🎉 Add initial redis client foundation.
This commit is contained in:
parent
96472b6cd2
commit
6ba3a28143
5 changed files with 153 additions and 0 deletions
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
;; TODO: vendorize pgclient under `vertx-clojure/vertx-pgclient`
|
;; TODO: vendorize pgclient under `vertx-clojure/vertx-pgclient`
|
||||||
io.vertx/vertx-pg-client {:mvn/version "4.0.0-milestone4"}
|
io.vertx/vertx-pg-client {:mvn/version "4.0.0-milestone4"}
|
||||||
|
io.lettuce/lettuce-core {:mvn/version "5.2.2.RELEASE"}
|
||||||
|
|
||||||
vertx-clojure/vertx
|
vertx-clojure/vertx
|
||||||
{:local/root "vendor/vertx"
|
{:local/root "vendor/vertx"
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
:database-uri "postgresql://127.0.0.1/uxbox"
|
:database-uri "postgresql://127.0.0.1/uxbox"
|
||||||
:database-username "uxbox"
|
:database-username "uxbox"
|
||||||
:database-password "uxbox"
|
:database-password "uxbox"
|
||||||
|
|
||||||
|
:redis-uri "redis://redis/0"
|
||||||
:media-directory "resources/public/media"
|
:media-directory "resources/public/media"
|
||||||
:assets-directory "resources/public/static"
|
:assets-directory "resources/public/static"
|
||||||
:media-uri "http://localhost:6060/media/"
|
:media-uri "http://localhost:6060/media/"
|
||||||
|
@ -44,6 +46,7 @@
|
||||||
(s/def ::database-username (s/nilable ::us/string))
|
(s/def ::database-username (s/nilable ::us/string))
|
||||||
(s/def ::database-password (s/nilable ::us/string))
|
(s/def ::database-password (s/nilable ::us/string))
|
||||||
(s/def ::database-uri ::us/string)
|
(s/def ::database-uri ::us/string)
|
||||||
|
(s/def ::redis-uri ::us/string)
|
||||||
(s/def ::assets-uri ::us/string)
|
(s/def ::assets-uri ::us/string)
|
||||||
(s/def ::assets-directory ::us/string)
|
(s/def ::assets-directory ::us/string)
|
||||||
(s/def ::media-uri ::us/string)
|
(s/def ::media-uri ::us/string)
|
||||||
|
|
49
backend/src/uxbox/redis.clj
Normal file
49
backend/src/uxbox/redis.clj
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
;; 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) 2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
|
(ns uxbox.redis
|
||||||
|
(:refer-clojure :exclude [run!])
|
||||||
|
(:require
|
||||||
|
[clojure.tools.logging :as log]
|
||||||
|
[lambdaisland.uri :refer [uri]]
|
||||||
|
[mount.core :as mount :refer [defstate]]
|
||||||
|
[promesa.core :as p]
|
||||||
|
[uxbox.common.exceptions :as ex]
|
||||||
|
[uxbox.config :as cfg]
|
||||||
|
[uxbox.core :refer [system]]
|
||||||
|
[uxbox.util.redis :as redis]
|
||||||
|
[uxbox.util.data :as data]
|
||||||
|
[vertx.util :as vu])
|
||||||
|
(:import
|
||||||
|
java.lang.AutoCloseable))
|
||||||
|
|
||||||
|
;; --- Connection Handling & State
|
||||||
|
|
||||||
|
(defn- create-client
|
||||||
|
[config]
|
||||||
|
(let [uri (:redis-uri config "redis://redis/0")]
|
||||||
|
(log/info "creating redis client with" uri)
|
||||||
|
(redis/client uri)))
|
||||||
|
|
||||||
|
(defstate client
|
||||||
|
:start (create-client cfg/config)
|
||||||
|
:stop (.close ^AutoCloseable client))
|
||||||
|
|
||||||
|
(defstate conn
|
||||||
|
:start (redis/connect client)
|
||||||
|
:stop (.close ^AutoCloseable conn))
|
||||||
|
|
||||||
|
;; --- API FORWARD
|
||||||
|
|
||||||
|
(defmacro with-conn
|
||||||
|
[& args]
|
||||||
|
`(redis/with-conn ~@args))
|
||||||
|
|
||||||
|
(defn run!
|
||||||
|
[conn cmd params]
|
||||||
|
(let [ctx (vu/get-or-create-context system)]
|
||||||
|
(-> (redis/run! conn cmd params)
|
||||||
|
(vu/handle-on-context ctx))))
|
99
backend/src/uxbox/util/redis.clj
Normal file
99
backend/src/uxbox/util/redis.clj
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
;; 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) 2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
|
(ns uxbox.util.redis
|
||||||
|
"Asynchronous posgresql client."
|
||||||
|
(:refer-clojure :exclude [get set run!])
|
||||||
|
(:require
|
||||||
|
[promesa.core :as p])
|
||||||
|
(:import
|
||||||
|
io.lettuce.core.RedisClient
|
||||||
|
io.lettuce.core.RedisURI
|
||||||
|
io.lettuce.core.codec.StringCodec
|
||||||
|
io.lettuce.core.api.async.RedisAsyncCommands
|
||||||
|
io.lettuce.core.api.StatefulRedisConnection
|
||||||
|
))
|
||||||
|
|
||||||
|
(defrecord Client [conn uri]
|
||||||
|
java.lang.AutoCloseable
|
||||||
|
(close [_]
|
||||||
|
(.shutdown ^RedisClient conn)))
|
||||||
|
|
||||||
|
(defrecord Connection [cmd conn]
|
||||||
|
java.lang.AutoCloseable
|
||||||
|
(close [_]
|
||||||
|
(.close ^StatefulRedisConnection conn)))
|
||||||
|
|
||||||
|
(defn client
|
||||||
|
[uri]
|
||||||
|
(->Client (RedisClient/create) (RedisURI/create uri)))
|
||||||
|
|
||||||
|
(defn connect
|
||||||
|
[client]
|
||||||
|
(let [^RedisURI uri (:uri client)
|
||||||
|
^RedisClient conn (:conn client)
|
||||||
|
^StatefulRedisConnection conn' (.connect conn StringCodec/UTF8 uri)]
|
||||||
|
(->Connection (.async conn') conn')))
|
||||||
|
|
||||||
|
(declare impl-with-conn)
|
||||||
|
|
||||||
|
(defmacro with-conn
|
||||||
|
[[csym sym] & body]
|
||||||
|
`(impl-with-conn ~sym (fn [~csym] ~@body)))
|
||||||
|
|
||||||
|
(defn impl-with-conn
|
||||||
|
[client f]
|
||||||
|
(let [^RedisURI uri (:uri client)
|
||||||
|
^RedisClient conn (:conn client)]
|
||||||
|
(-> (.connectAsync conn StringCodec/UTF8 uri)
|
||||||
|
(p/then (fn [^StatefulRedisConnection conn]
|
||||||
|
(let [cmd (.async conn)
|
||||||
|
conn (->Connection cmd conn)]
|
||||||
|
(-> (p/do! (f conn))
|
||||||
|
(p/handle (fn [v e]
|
||||||
|
(.close conn)
|
||||||
|
(if e
|
||||||
|
(throw e)
|
||||||
|
v))))))))))
|
||||||
|
|
||||||
|
(defn- resolve-to-bool
|
||||||
|
[v]
|
||||||
|
(if (= v 1)
|
||||||
|
true
|
||||||
|
false))
|
||||||
|
|
||||||
|
(defmulti impl-run (fn [conn cmd parmas] cmd))
|
||||||
|
|
||||||
|
(defn run!
|
||||||
|
[conn cmd params]
|
||||||
|
(let [^RedisAsyncCommands conn (:cmd conn)]
|
||||||
|
(impl-run conn cmd params)))
|
||||||
|
|
||||||
|
(defmethod impl-run :get
|
||||||
|
[conn _ {:keys [key]}]
|
||||||
|
(.get ^RedisAsyncCommands conn ^String key))
|
||||||
|
|
||||||
|
(defmethod impl-run :set
|
||||||
|
[conn _ {:keys [key val]}]
|
||||||
|
(.set ^RedisAsyncCommands conn ^String key ^String val))
|
||||||
|
|
||||||
|
(defmethod impl-run :smembers
|
||||||
|
[conn _ {:keys [key]}]
|
||||||
|
(-> (.smembers ^RedisAsyncCommands conn ^String key)
|
||||||
|
(p/then' #(into #{} %))))
|
||||||
|
|
||||||
|
(defmethod impl-run :sadd
|
||||||
|
[conn _ {:keys [key val]}]
|
||||||
|
(let [keys (into-array String [val])]
|
||||||
|
(-> (.sadd ^RedisAsyncCommands conn ^String key ^"[S;" keys)
|
||||||
|
(p/then resolve-to-bool))))
|
||||||
|
|
||||||
|
(defmethod impl-run :srem
|
||||||
|
[conn _ {:keys [key val]}]
|
||||||
|
(let [keys (into-array String [val])]
|
||||||
|
(-> (.srem ^RedisAsyncCommands conn ^String key ^"[S;" keys)
|
||||||
|
(p/then resolve-to-bool))))
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
[promesa.exec :as px]
|
[promesa.exec :as px]
|
||||||
[uxbox.migrations]
|
[uxbox.migrations]
|
||||||
[uxbox.db :as db]
|
[uxbox.db :as db]
|
||||||
|
[uxbox.redis :as rd]
|
||||||
[uxbox.util.storage :as st]
|
[uxbox.util.storage :as st]
|
||||||
[uxbox.util.time :as tm]
|
[uxbox.util.time :as tm]
|
||||||
[uxbox.util.blob :as blob]
|
[uxbox.util.blob :as blob]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue