Skip to content

Commit 4410310

Browse files
committed
testing cluster mode
1 parent 19cac44 commit 4410310

File tree

11 files changed

+64
-45
lines changed

11 files changed

+64
-45
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ You can see the spike in CPU and bandwidth on the droplet, but the CPU never sat
252252
These are by no means comprehensive benchmarks but give you a sense of what a PCP server can withstand for simple use case.
253253
Going above 400 req/s generally results in bad things happening. You can test your own site using [k6](https://k6.io/) with the instructions in [loadtest.js](./loadtest.js)
254254

255-
# Roadmap
255+
# Roadmap & releases
256256

257257
## Release 0.0.1
258258
- [x] Run arbitrary scripts
@@ -268,6 +268,10 @@ Going above 400 req/s generally results in bad things happening. You can test yo
268268
- [x] Document PCP
269269
- [x] Load test a production deployment
270270

271+
## Release 0.0.2
272+
- [ ] Perfomance improvements
273+
- [ ] Cluster mode
274+
271275
## Release 0.1.0
272276
- [ ] Store passphrases with [konserve](https://github.com/replikativ/konserve)
273277
- [ ] Add sponsorship button
@@ -285,6 +289,7 @@ For the guidance and examples, special thanks to
285289

286290
- [@BrunoBonacci](https://github.com/BrunoBonacci)
287291
- [@borkdude](https://github.com/borkdude)
292+
- [@Baeldung](https://twitter.com/Baeldung)
288293

289294
## License
290295

install.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ mv -f "$download_dir/pcp-server.jar" "$PWD/pcp-server.jar"
5353
rm -rf "$PWD/pcp-templates"
5454
mv -f "$download_dir/pcp-templates" "$PWD"
5555

56+
if [ ! -e "$PWD/pcp.conf" ] ; then
57+
echo "PCP_CLUSTER=-c" > "$PWD/pcp.conf"
58+
fi
59+
5660
case "$(uname -s)" in
5761
Linux*)
5862
mv -f "$download_dir/pcp.service" "/etc/systemd/system/pcp.service"

project.clj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defproject pcp "0.0.2-beta.1"
1+
(defproject pcp "0.0.2-beta.2"
22
:description "PCP: Clojure Processor - A Clojure replacement for PHP"
33
:url "https://github.com/alekcz/pcp"
44
:license {:name "The MIT License"
@@ -7,6 +7,7 @@
77
:dependencies [ ;core
88
[org.clojure/clojure "1.10.3"]
99
[org.clojure/tools.cli "1.0.194"]
10+
[org.clojure/core.async "1.3.618"]
1011
[borkdude/sci "0.2.5"]
1112
[byte-streams "0.2.4"]
1213
[http-kit "2.5.0-RC1"]

resources/PCP_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.0.2-beta.1
1+
v0.0.2-beta.2

resources/pcp.service

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
Description= pcp scgi server
33

44
[Service]
5-
ExecStart=/usr/bin/java -jar /usr/local/bin/pcp-server.jar
5+
EnvironmentFile=/usr/local/bin/pcp.conf
6+
ExecStart=/usr/bin/java -jar /usr/local/bin/pcp-server.jar $PCP_CLUSTER
67
Restart=always
78

89
[Install]

src/pcp/core.clj

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@
8989
(catch Exception _ nil)))
9090

9191
(defn valid-path? [parent target]
92-
(let [parent-path (-> parent io/file (.getParentFile) (.getCanonicalPath))
93-
target-path (-> target io/file (.getCanonicalPath))]
92+
(let [parent-path (-> parent ^File io/file (.getParentFile) (.getCanonicalPath))
93+
target-path (-> target ^File io/file (.getCanonicalPath))]
9494
(str/starts-with? target-path parent-path)))
9595

9696
(def persist ^:sci/macro
@@ -105,9 +105,9 @@
105105
(defn run-script [url-path &{:keys [root request]}]
106106
(let [path (URLDecoder/decode url-path "UTF-8")
107107
source (read-source path)
108-
file (io/file path)
109-
root (or root (-> file (.getParentFile) (.getCanonicalPath)))
110-
parent (longer root (-> file (.getParentFile) (.getCanonicalPath)))
108+
^File file (io/file path)
109+
root (or root (-> ^File file (.getParentFile) (.getCanonicalPath)))
110+
parent (longer root (-> ^File file (.getParentFile) (.getCanonicalPath)))
111111
response (atom nil)
112112
keygen (fn [path k] (keyword (str (h/uuid [path k]))))]
113113
(if (string? source)
@@ -200,7 +200,16 @@
200200
([path]
201201
(let [scgi-port (Integer/parseInt (or (System/getenv "SCGI_PORT") "9000"))]
202202
(case path
203-
"" (scgi/serve scgi-handler scgi-port)
203+
""
204+
(scgi/serve scgi-handler scgi-port)
205+
206+
"-c"
207+
(do
208+
(scgi/serve scgi-handler scgi-port)
209+
(scgi/serve scgi-handler 9007)
210+
(scgi/serve scgi-handler 9014)
211+
(scgi/serve scgi-handler 9021))
212+
204213
(run-script path)))))
205214

206215

src/pcp/resp.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
:.bmp "image/bmp"
5252
:.bz "application/x-bzip"
5353
:.bz2 "application/x-bzip2"
54+
:.cljs "application/x-scittle"
5455
:.csh "application/x-csh"
5556
:.css "text/css"
5657
:.csv "text/csv"

src/pcp/scgi.clj

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,29 @@
1717
(let [data (str/split (:header req) #"\u0000")
1818
keys (map #(-> % (str/replace "_" "-") str/lower-case keyword) (take-nth 2 data))
1919
values (take-nth 2 (rest data))
20-
h (zipmap keys values)]
20+
h (transient (zipmap keys values))]
2121
;make the ring linter happy.
2222
(-> h
23-
(update :server-port #(Integer/parseInt (if (str/blank? %) "0" %)))
24-
(update :content-length #(Integer/parseInt (if (str/blank? %) "0" %)))
25-
(update :request-method #(-> % str str/lower-case keyword))
26-
(assoc :headers { "sec-fetch-site" (-> h :http-sec-fetch-site)
27-
"host" (-> h :http-host)
28-
"user-agent" (-> h :http-user-agent)
29-
"cookie" (-> h :http-cookie)
30-
"sec-fetch-user" (-> h :http-sec-fetch-user)
31-
"connection" (-> h :hhttp-connection)
32-
"upgrade-insecure-requests" (-> h :http-sec-fetch-site)
33-
"accept" (-> h :http-accept)
34-
"accept-language" (-> h :http-accept-language)
35-
"sec-fetch-dest" (-> h :http-sec-fetch-dest)
36-
"accept-encoding" (-> h :http-accept-encoding)
37-
"sec-fetch-mode" (-> h :http-sec-fetch-mode)
38-
"cache-control" (-> h :http-cache-control)})
39-
(assoc :headers {})
40-
(assoc :uri (:request-uri h))
41-
(assoc :scheme (-> h :request-scheme keyword))
42-
(assoc :body (:body req)))))
23+
(assoc! :server-port (Integer/parseInt (if (str/blank? (:server-port h)) "0" (:server-port h))))
24+
(assoc! :content-length (Integer/parseInt (if (str/blank? (:content-length h)) "0" (:content-length h))))
25+
(assoc! :request-method (-> (:request-method h) str str/lower-case keyword))
26+
(assoc! :headers { "sec-fetch-site" (-> h :http-sec-fetch-site)
27+
"host" (-> h :http-host)
28+
"user-agent" (-> h :http-user-agent)
29+
"cookie" (-> h :http-cookie)
30+
"sec-fetch-user" (-> h :http-sec-fetch-user)
31+
"connection" (-> h :hhttp-connection)
32+
"upgrade-insecure-requests" (-> h :http-sec-fetch-site)
33+
"accept" (-> h :http-accept)
34+
"accept-language" (-> h :http-accept-language)
35+
"sec-fetch-dest" (-> h :http-sec-fetch-dest)
36+
"accept-encoding" (-> h :http-accept-encoding)
37+
"sec-fetch-mode" (-> h :http-sec-fetch-mode)
38+
"cache-control" (-> h :http-cache-control)})
39+
(assoc! :uri (:request-uri h))
40+
(assoc! :scheme (-> h :request-scheme keyword))
41+
(assoc! :body (:body req))
42+
(persistent!))))
4343

4444
(defn on-accept [^SelectionKey key]
4545
(let [^ServerSocketChannel channel (.channel key)

src/pcp/utility.clj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[taoensso.nippy :as nippy]
1111
[environ.core :refer [env]])
1212
(:import [java.net Socket]
13-
[java.io File ByteArrayOutputStream InputStream]
13+
[java.io File ByteArrayOutputStream InputStream BufferedWriter]
1414
[org.apache.commons.io IOUtils]
1515
[org.apache.commons.codec.digest DigestUtils])
1616
(:gen-class))
@@ -19,7 +19,7 @@
1919

2020
(def root (atom nil))
2121
(def scgi (atom "9000"))
22-
(def version "v0.0.2-beta.1")
22+
(def version "v0.0.2-beta.2")
2323

2424
(defn keydb []
2525
(or (env :pcp-keydb) "/usr/local/etc/pcp-db"))
@@ -97,8 +97,8 @@ Options:
9797
(resp/status status)
9898
(resp/content-type mime-type)))
9999

100-
(defn file-response [path ^File file]
101-
(let [code (if (.exists file) 200 404)
100+
(defn file-response [path file]
101+
(let [code (if (.exists ^File file) 200 404)
102102
mime (resp/get-mime-type (re-find #"\.[0-9A-Za-z]{1,7}$" path))]
103103
(-> (resp/response file)
104104
(resp/status code)
@@ -115,14 +115,14 @@ Options:
115115
{:status status :body body :headers headers}))
116116

117117
(defn file-exists? [path]
118-
(-> path io/file .exists))
118+
(-> path ^File io/file .exists))
119119

120120
(defn serve-file [path]
121121
(file-response path (io/file path)))
122122

123123
(defn local-handler [opts]
124124
(fn [request]
125-
(let [root (.getCanonicalPath (io/file (:root opts)))
125+
(let [root (.getCanonicalPath ^File (io/file (:root opts)))
126126
path (str root (:uri request))
127127
slashpath (str path "index.clj")
128128
exists (or (file-exists? path) (file-exists? slashpath))
@@ -141,7 +141,7 @@ Options:
141141

142142
(defn run-file [path port]
143143
(let [path (str/replace (str "/" path) "//" "/")
144-
root (.getCanonicalPath (io/file "./"))
144+
root (.getCanonicalPath ^File (io/file "./"))
145145
scgi-port (Integer/parseInt (or (System/getenv "SCGI_PORT") (str port) "9000"))
146146
request {:document-root root :document-uri path :request-method :get}]
147147
(-> request http-to-scgi (forward scgi-port) create-resp :body)))
@@ -235,7 +235,7 @@ Options:
235235
path (str (keydb) "/" project ".db")]
236236
(io/make-parents (keydb))
237237
(println "adding passphrase for project:" project)
238-
(with-open [w (io/writer path)]
238+
(with-open [^BufferedWriter w (io/writer path)]
239239
(.write w ^String passphrase))
240240
(println "done.")))
241241

@@ -256,7 +256,7 @@ Options:
256256
(spit
257257
(str path "/public/api/info.clj")
258258
(slurp (str (template-path) "/api/info.clj")))
259-
(println (str "Created pcp project `" project-name "` in directory") (.getAbsolutePath (io/file path)))))
259+
(println (str "Created pcp project `" project-name "` in directory") (.getAbsolutePath ^File (io/file path)))))
260260

261261
(defn -main
262262
([]

test/pcp/core_test.clj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
[pcp.resp :as resp]
55
[pcp.core :as core]
66
[clojure.string :as str])
7-
(:import [java.io File]
8-
[java.net Socket InetAddress ConnectException]))
7+
(:import [java.io File]))
98

109
(deftest read-source-test
1110
(testing "Test reading source"
@@ -100,5 +99,4 @@
10099
scgi-request {:document-root root :document-uri uri }
101100
_ (core/scgi-handler scgi-request)
102101
ans (try (core/run-script (str root uri)) (catch Exception _ "error"))]
103-
(is (str/includes? ans "error")))))
104-
102+
(is (str/includes? ans "error")))))

0 commit comments

Comments
 (0)