This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-10-20
Channels
- # announcements (33)
- # aws (1)
- # babashka (8)
- # beginners (100)
- # calva (59)
- # clara (4)
- # clj-kondo (33)
- # cljdoc (9)
- # cljs-dev (30)
- # cljsrn (1)
- # clojure (28)
- # clojure-australia (1)
- # clojure-boston (1)
- # clojure-dev (4)
- # clojure-europe (14)
- # clojure-france (5)
- # clojure-italy (7)
- # clojure-nl (1)
- # clojure-uk (36)
- # clojurescript (13)
- # clojureverse-ops (6)
- # conjure (2)
- # cursive (2)
- # datahike (11)
- # datalevin (1)
- # datomic (106)
- # graphql (3)
- # helix (10)
- # holy-lambda (24)
- # kaocha (2)
- # lambdaisland (3)
- # lsp (199)
- # malli (35)
- # off-topic (16)
- # pathom (7)
- # polylith (38)
- # portal (16)
- # quil (2)
- # re-frame (18)
- # reagent (57)
- # shadow-cljs (11)
- # testing (3)
- # xtdb (9)
app.event('app_home_opened', (
this java api (nvm) has the signature this java.lang.Class...
what do I pass there in the place of 'single_quoted_stuff' ? (fixed)
nvm the snippet was javascript. The java api wanted a class and I achieved that by putting the class symbol name
Hey everyone, I'm having some trouble understanding how I should use core.async after having read some doc on it. I am coding a program that is long running and I'm trying to make it repl friendly so that I can have access to the marvels of interactive coding
I have a start
and a stop
function. The start
function initialize a jetty handler to listen to http requests and also run an infinite loop running the rest of the logic of the program. I run this infinite loop with (thread (run-loop))
so that it doesn't hang the repl. My question is, how should I communicate with this new thread to be able to tell it to stop for example?
I currently have a shared atom (def loop-running (atom false))
that I set to true when I run start
and to false when I run stop
interactively, the loop check that value in order to decide whether to recur or do nothing and exit.
This doesn't sound very optimal though and can lead to errors in some cases so I'm wondering if there is a better way? I am aware of chan
s but it seems like there is no way to check if a signal arrived on the channel without blocking the loop
either the run-loop
actively checks for a signal to change like in your case an atom, or run-loop
has to be passively signaled to stop. i dont think there can be much magic here...
I guess the atom solution isn't so bad then. What do you mean "has to be passively signaled to stop" though?
never mind. now that i think about it again, eventually it's some code checking some variable and decides to staying running or quit, be the code on the caller side of callee side it's the same essentially.
Am I missing something with channels? Or is there another more idiomatic way to make the loop not hang the repl without another thread?
Hi, I'm building my first clojure(script) app and I'm having trouble debugging my backend. I'm trying to place printlines in a handler to see what's going on. Whenever I evaluate this hanlder-function from my editor it does print the values into the repl as expected. When I call my backends rest-api from the frontend it doesn't print any values. A response is returned and there's only one possible handler that could be called in this scenario, so I'm really sure the handler must have been called. Does anyone have an idea what's going on here? Please let me know if I should supply more information.
Sure. I didn't include any as I suspect I'm missing a high-level/conceptual point, not so much wrong implementation. But here is an example of a handler function I would like to print some value of:
(defn update-wall-by-id
[{{{:keys [wall-id holdmarkings]} :body} :parameters :as request}]
(prn request)
(create-or-update-holdmarkings {:wall-id wall-id :holdmarkings holdmarkings})
{:status 200
`:body (db-api/get-wall-by-id wall-id)})`
"Whenever I evaluate this hanlder-function from my editor it does print the values into the repl as expected" how did you do this part?
I call the function from a comment block within the same file/namespace where the handler-function is defined. This is the code:
(update-wall-by-id {:parameters {:body {:wall-id 1
:name "Modified Wall"
:image-url "test.jpg"
:holdmarkings [{:hold-id 1
:points [{:x 1 :y 1}]}
`{:hold-id 2`
:points [{:x 2 :y 2}]}]}}})
Im getting a response and there's only one possible handler for this route, so Im pretty sure this part works as well. But here's the code.
Relevant part of routes:
["/:wall-id"
{:parameters {:path {:wall-id s/Int}}
`:get get-wall-by-id`
`:put {:parameters {:body {:wall-id s/Int`
`:name s/Str`
`:image-url s/Str`
`:holdmarkings [{:hold-id s/Int`
`:points [{:x s/Num`
`:y s/Num}]}]}}`
`:handler update-wall-by-id}}]`
I started to suspect the app uses a different output for the printline then my running repl when called from "outside", but I've no idea if that makes sense, Im new to working with repls so Im not sure what behaviour to expect.
the prn output has to showup somewhere, either in your editor where repl is or the cli where repl is started.
seems like this is routit make sure your frontend is testing the right url and routit is properly routing to that handler
I start my repl from my editor (VSC/Calva) so I guess that means the printline should show up in the same repl where I see the results of my in-editor evaluations.
Yes, I use reitit. The app is actually completely working, so Im pretty sure routing is fine.
If I talk between 2 clojure applications is there any reason to use transit instead of edn? (performance is not critical in my use case)
Hi, want make functions spit out what sort of data they are expecting and what sort of data they output, maybe by adding logging lines via with-redefs
(?) but I also want the function to do what it does normally. does it make sense to wrap it in a macro that tells me things and then just invokes the function?
you can use alter-var-root
to wrap functions with what the lisp peeps unsed to call advice ... which sounds a bit like what you want to do??
Oh hey that looks like a perfect fit. Gracias mucho
(defn my-func [arg]
arg)
(alter-var-root #'my-func (fn [orig-fn] (fn [& args] (prn '> args) (apply orig-fn args))))
actually ... you could add the orig fn as metadata just in case you want to undo it later
(alter-var-root #'my-func (fn [orig-fn] (with-meta (fn [& args] (prn '> args) (apply orig-fn args)) {:orig-fn orig-fn})))
??Hmmm interesting idea
what is an algorithm that will "raise" arbitrarly nested :bar
in my map? {:foo1 {:foo2 {:bar 'baz}}}
=> {:foo1 {:foo2 'baz}}
, while preserving the rest of the map structure
perhaps (update m :foo :bar)
might do the trick (except the arbitrarily nested part, where update-in
might help..)
Something like this might do it (using clojure.walk
...
(defn pull-up-bar [m]
(walk/postwalk
(fn [{:keys [bar] :as x}]
(if bar
bar
x))
m))
I'm not clear why one would want to do that...short of it really lending itself to a fn named "pull-up-bar". 😂
Thanks for the suggestions, will check it.
The use case is actually that I have a config map and I'd like to do something simple for defining things :prod
and :dev
next to each other or something not sure yet.
The idea was that I could then do (get-in config {endpoint})
but yea not sure anymore if that's such a great idea
-> what is a simple way to have 2 configs just 2 files?
I think that works - if I understood you correctly, it’s similar to the approach taken by https://github.com/juxt/aero#profile
i like to have a config slurped into a map, then the prod config can be (merge config prd-config)
so that prd-config only has to override things that are specific to prod.
Hi there. I have a bit of weirdness in my REPL, and I'm having a problem making it go away. I'm needing Java 1.8 now for a particular application.
scotto@Scotts-MBP ~ % lein version
Leiningen 2.9.7 on Java 1.8.0_292 OpenJDK 64-Bit Server VM
scotto@Scotts-MBP ~ % lein repl
nREPL server started on port 53638 on host 127.0.0.1 -
REPL-y 0.5.1, nREPL 0.8.3
Clojure 1.10.3
OpenJDK 64-Bit Server VM 1.8.0_292-b10
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (System/getProperty "Java.version")
nil
user=> quit
Bye for now!
scotto@Scotts-MBP ~ % java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.292-b10, mixed mode)
Would anyone know why (System/getProperty "Java.version")
is evaluating to nil
? How can I get it to recognize Java 1.8?carp 🐟
I've been driving myself crazy. All for a capital letter! 🤪
been there just about every day this week xD
Concurrency question, what is a more common path? Threads or async? Async seems like a big buy-in, as you have to use nonblocking io etc. Is async default nowadays in clojure or do you typically start project with threads?
i consider core.async to be a coordination and communication library and not really an alternative to threads.
Could you elaborate on this?
channels are communication channels. and you can lock up the threadpool used for go blocks if you hog the execution time. There are pipeline functions but those just use standard threads and have mechanism to use channels to communicate. core.async just doesn't really offer these kinds of primitives and is just communication (imo)
It is very much an alternative to threads, it is just that there are not good alternative to threads for heavy compute or blocking operations. But you can use its fibers effectively for async programming.
future
submits functions to be executed to clojure.lang.Agent/soloExecutor
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L53 which is created per https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/Executors.html#newCachedThreadPool(java.util.concurrent.ThreadFactory) so it is unbounded
> Creates a thread pool that creates new threads as needed, Is there any path towards discovering this number 🙂?
As I said: unbounded.
if a new task is created and there is no thread already existing to run it a new threaded is created
More importantly, why are you asking?
If you run (future (Thread/sleep 10000))
in a loop, you'll likely get an OoM error based on not being able to create any new threads.
@U11BV7MTK I linked to that above and @US9EF3BGU was quoting from that text.
(so I guess the javadoc page is not clear enough about it being unbounded?)
asking to know if there is a limit in futures, or they can be invoked freely until they reach threadpool size (given they take time)
@US9EF3BGU See my comment about creating threads in a loop. It is unbounded and you will simply run out of threads and hit an OoM error.
there is no limit on the threadpool size, but you will run into other limits, os limits on threads or running out of memory for all the stacks of the threads, etc
yes, asking due to worry around backpressure from system, so can the threadpool from future be limited?
user=> (dotimes [n 10000] (future (Thread/sleep 10000)))
[35.261s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 4k, detached.
Execution error (OutOfMemoryError) at java.lang.Thread/start0 (Thread.java:-2).
unable to create native thread: possibly out of memory or process/resource limits reached
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html has some really great documentation about the way to think about them
i.e., don't use a bare future
call. Use a specific executor and submit tasks to it.
and the jvm has some concept of a default executor these days so it also may have two such
(the jvm's is the fork join common pool, and there is just the one, which would the equiv of the bounded executor case)
ok, so the question now, how would i run future(or something looking like a future) over a pool rather than unbound
As I said "Use a specific executor and submit tasks to it."
I would strongly suggest sitting down with something like Java Concurrency in Practice, which is old, but very good
also you can swap out the executor pool under futures with your own pool, but I would recommend making your own pool as they say https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-agent-send-off-executor!
the reason being that you don't know what other lib may also be using that pool and limiting it could violate those assumptions
Perhaps the docstring of set-agent-send-off-executor!
should mention that it also affects future
? And perhaps future
's docstring could mention that it uses the agent send-off
executor? Or is that considered an implementation detail that shouldn't be relied on @U064X3EF3?
(I was this week old when I discovered this connection -- courtesy of @U0NCTKEV8 at work this week 🙂 )
On future, I'd say that's an implementation detail, and on the setter, if you're messing with this, you should be intimately familiar with the impl details
https://github.com/TheClimateCorporation/claypoole is a library that gives you more control over these things (including pmap and more).
@US9EF3BGU This article: https://purelyfunctional.tv/guide/clojure-concurrency/ is really good to introduce you to all the options you have for concurrency.
This is the section you probably want: https://purelyfunctional.tv/guide/clojure-concurrency/#executorservice
That said, since you mentioned being worried about backpressure. That's a bit of a different concern in my opinion. Core.async handles backpressure really well. ExecutorService can handle backpressure, but it requires you to create the ExecutorService carefully. They are often backed by a queue where tasks sit until there is a thread available. This queue can also be unbounded. For backpressure, you'll want to limit the size of that queue, but then you need a strategy for what should happen if someone tries to submit a task and the queue is full? Should the task be dropped? Should the caller thread block until there is room in the queue again? Should an exception be thrown?