This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-25
Channels
- # announcements (1)
- # beginners (338)
- # calva (41)
- # cider (19)
- # cljdoc (10)
- # cljsrn (6)
- # clojure (116)
- # clojure-europe (15)
- # clojure-italy (25)
- # clojure-nl (5)
- # clojure-spec (19)
- # clojure-uk (52)
- # clojurescript (99)
- # clojurex (14)
- # cursive (47)
- # data-science (1)
- # datomic (5)
- # duct (1)
- # figwheel (13)
- # fulcro (58)
- # graalvm (93)
- # jobs (3)
- # joker (9)
- # luminus (4)
- # nrepl (21)
- # off-topic (41)
- # pathom (25)
- # re-frame (7)
- # reitit (8)
- # ring-swagger (13)
- # tools-deps (13)
I want to run an nrepl alias and spawn a jetty server in another thread so I can hold a reference to it to .start and .stop it but when I try to do so using a future (def server (future (run-jetty #'my-app {:port 3000})))
I don't think it is working. The main reason I want to do it this way is to spawn the jetty server and run the nrepl in one alias rather than start an nrepl and then another alias for the server.
:nrepl {:extra-deps {nrepl {:mvn/version "0.6.0"}
cider/cider-nrepl {:mvn/version "0.21.1"}}
:main-opts ["-m" "nrepl.cmdline"
"--middleware" "[cider.nrepl/cider-middleware]"
"--port" "9000"]}
:dev-server {:main-opts ["-e" "((requiring-resolve,'))"]}
this are my two aliases, but kind of want to combine themLike described here: https://github.com/clojure-emacs/cider-nrepl#via-embedding-nrepl-in-your-app
I think I'll add htat to my dev-server code, one question though is still launching the dev server and having a reference to it in the repl.
Well, the REPL will have access to whatever. So if you keep a reference of the dev server anywhere, like just a global def, you should be able to access it
ah, I htink this puts me on the right track. Is the user.clj where generally run-scripts for tools.deps ususally kept?
yeah, if I start it in a repl, it blocks input
but running it as a future doesn't seem to work either. If I do something like (.stop @server)
nothing happens
Hum... what is run-jetty? I mean, do you expect it to return an object which has a .stop method on it?
Yes, run-jetty is a function that should return the server instance
https://stackoverflow.com/questions/2706044/how-do-i-stop-jetty-server-in-clojure
Did you try with that option, then you shouldn't need a future at all, and your thread shouldn't block
ugh, I just saw that, very important it seems lol
So, if you wanted that in all your repl sessions, you could put that line in your user.clj
. Or in your run-dev-server alias as you were doing, and also add the nRepl code in there. So then when running that alias, you would get both nRepl and jetty started. You can then connect to nRepl, and access the jetty variable as normal.
perfect, I think this and the user.clj would work like a charm
thanks for the help!
also you mentioned it's only for developement. So If I had an alias for the real server that called clojure.main and did an -e that ran the real server, user.clj wouldn't be called?
If you use -m
then it would skip user.clj, and unless you required it yourself, it wouldn't load
What some people do is that, they don't bundle user.clj when they deploy their app. So it is only available in development,
ok I got it
(ns user
(:require [ :as app]))
(defonce server (app/run-dev-server))
(defn stop [] (.stop server))
(defn start [] (.start server))
And others maybe don't care to have it bundled, but they bootstrap the prod Clojure app either with -m
or some other custom launcher that doesn't load user.clj
I ended up putting user.clj in a dev folder so I could do clj -A:nrepl:dev
https://github.com/dantheobserver/parrot-api/blob/develop/deps.edn#L21
that way it's purely for a dev flow
https://github.com/dantheobserver/parrot-api/blob/develop/dev/user.clj
yeah, I'll experiment with a "prod" alias and just use m for the server function
night, thanks again
Is it a #clojure-dev problem or a #liquid problem?
~ java --version
openjdk 12.0.1 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode)
~ clj -Sdeps '{:deps {mogenslund/liquid {:mvn/version "1.1.3"}}}' -m dk.salza.liq.core --jframe
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x0000000800231840 (file:/home/souenzzo/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar) to method sun.java2d.SunGraphics2D.setFont(java.awt.Font)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x0000000800231840
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
It has become an FAQ, if I am pattern matching correctly: https://clojure.org/guides/faq#illegal_access
I’m struggling to figure proper use of the various io functions (input streams, output streams) to make sure I’m not doing anything silly or leaving things in memory etc. Here’s what I have (which is working):
(defn- save-workbook-gridfs [db workbook]
(with-open [bas (java.io.ByteArrayOutputStream.)
buf (io/output-stream bas)]
(docjure/save-workbook-into-stream! buf workbook)
(.flush buf)
(gridfs-store-file db (.toByteArray bas)
{:filename "report.xlsx"
:metadata {:expires (expiration-time 1)}})))
I need to create an OutputStream (`bas`) which I wrap into a BufferedOutputStream (`buf`) (not sure if necessary). Then I flush the buf
to make sure the changes make it into bas
, and then I get a byte array and pass that down to the thing that expects either a byte array or an InputStream.
Java's a bit rusty, but you might be able to get away without buf
, since its buffer is another byte-array! You'd be avoiding repeatable small writes to a byte-array by writing to another (albeit smaller) byte-array
Makes sense — I guess the buffering is needed when the main output stream is backed by a file or network or something like that, right?
Yup, something more expensive than the buffer! Doesn't even have to go that far... printing to a terminal can be surprisingly slow
I believe everything is OK but it does seem complicated. I found the Piped*
stuff but it seems like they might cause deadlock?
When requiring things when is :as
preferred and when is :refer
preferred?
I almost always prefer :as
because I’m a big fan of explicit code. I make a few exceptions for major, well-known stuff like deftest
and core.async’s <!!
etc.

Based on my experience - the only case when I use :refer
is (:require [clojure.test :refer :all])
- aliasing imports or pulling in individual functions from namespaces gets confusing very quickly when working in a team, we tend to always alias a whole namespace and use it as -is (e.g. (:require [clojure.string :as s])
and then (s/replace ....)
)
What are some of the best talks/resources about using Clojure macros? I heard @alexmiller to talk about the idea of "modeling domain as data, using functions to manipulate them and adding a thin layer of macro sugar " before (also mentioned here https://medium.com/@puredanger/hello-anders-just-a-few-points-to-consider-regarding-clojure-222cd0d7d4e7 ) I'm wondering which talks/resources do a really good job when it comes to explaining when/where/how to do that.
presume you meant "macros" -- don't know about best, but one thing i found helpful was: https://blog.brunobonacci.com/2015/04/19/dead-simple-introduction-to-clojure-macros/
Yeah, sorry for the typo and thanks for the link 🙂. However, I was more interested in learning about real-world use cases and how to use them effectively rather than just explaining basic macro mechanics.
The first chapter of Clojure Applied is about that. I’d probably change some of that now but still maybe useful

^ While this is being discussed, I'll take this opportunity to thank Alex and Ben for the wonderfully tasteful book. Just finished reading my tree version. Is there a next version in the works with spec, socket REPL and possibly other stuff?
does anyone use tap>
as a production logger? I’m afraid of the 1024 buffer size dropping log messages
I would not use it as a production logger. it's intended for debugging.
I use it instead of print in my prepl. Tangent: A shame it only takes one arg but makes sense, I usually end up passing a map with a bunch of values inside it. I have a vim macro to wrap the current form in a (doto ... tap>)
which is really handy.
Discovering tap>
returned true (which again, makes sense) was jarring the first time. tap->
would be neat! Totally get not adding it to avoid bloat though since there's ways around it.
I went ahead one more step:
(defn spytap [x]
(tap> x)
x)
(defn spytap> [x m]
(tap> (assoc m :spytap>/value x)
x))
(defn spytap>> [m x]
(tap> (assoc m :spytap>>/value x)
x))
This way you can associate any context (usually local binding) via a map in a threading.@ghadi I forgot to reply in #graalvm and I see you just left. I think compiling clojure proper with GraalVM is quite ambitious, I would be surprised if that would work, but solving the 'locking' problem, so anyone doesn't run into that, is great.
It'd be nice if it worked out of the box, but I'm not going to expend too much effort trying to put a square peg (clojure- open-world assumption) in a round hole (native-image - closed-world assumption) @borkdude
I don't expect all clojure programs to work out of the box, but only a subset of clojure. and if it works, it's nice for command line applications
has anyone gotten graal native-image to compile Clojure 1.10.1 + with the locking change patch?
@ghadi do you maybe have a gist or something that describes how to build clojure + spec with this patch? I've tried it before and it was pretty involved, since spec itself is also AOT-ed
I have a branch of a project where I ran into this issue. I can retry it with your patch, once I know what steps to do
https://github.com/ghadishayban/clj1472 change deps.edn to point to the jar in the local directory and then call ./make
@ghadi I tested the 1.10.0 jar with the repro code to build a binary and I'm getting the locking error. Now I'm trying 1.10.1.jar. Do you have any steps where I can reproduce how you built those jars?
no, I'm testing your clojure.jar files to see if I can build a binary using the repro code, because that's what ultimately should work with the locking fix in place
I didn't succeed in executing make, because I'm not familiar with using the agent stuff from graalvm
I went ahead one more step:
(defn spytap [x]
(tap> x)
x)
(defn spytap> [x m]
(tap> (assoc m :spytap>/value x)
x))
(defn spytap>> [m x]
(tap> (assoc m :spytap>>/value x)
x))
This way you can associate any context (usually local binding) via a map in a threading.