I would like to understand all of this Clojure error message (not just the first line)
class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long
is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed
module of loader 'app')
The error is from evaluating (1)
as an expression, which I expect to fail as 1
is not defined as a function anywhere in the code. So this explains the java.lang.Long is not a clojure.lang.IFn part of the message.
I assume the second line is referring to the name of the class loader used to include java.lang
in the JVM of the REPL.
Is app
a specific class loader for all code in the REPL?
I see this last part of the message in many error messages and its about time I understood what it means :)that's correct
it's also including module information - since Java 9, there is a module loading system in Java and the java.base module includes the core set of modules needed to start Java (other modules can be added as needed). for backwards compatibility you can still mostly ignore the module stuff but then you're loading stuff in the "unnamed" module
https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/ClassLoader.html lots of info about the classloader chain here ^
I have a scenario, where my function will execute more than 10 mins which is expected, I want to stop the execution if it reaches more than 10 mins, How can I achieve it in clojure ?
what does it depend on exactly whether (future-cancel)
works or not? current thread state?
I linked the Thread.interrupt docs above (future-cancel uses that method): > If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. > > If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. > > If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. > > If none of the previous conditions hold then this thread's interrupt status will be set
it always "works" in that if the thread in question doesn't invoke any of the specific methods mentioned there, a flag is set and you can check the flag
it "doesn't work" in that if you are doing work that never uses any of those methods, and don't check that flag, it has no effect on the thread's execution
there's a more powerful method to force stop a thread (which some code shared above uses), but there are no guarantees about safety when you use that, and it can crash the vm or leave objects in inconsistent states or leave locks that can't be unlocked
the code shared above is arguably OK, because it's for a IRC bot that's mainly there for entertainment and education and if it crashes it auto restarts
your code might deal with something more serious where those risks are not OK
thank you! so as plain function doesnt have an periodic interrupt check, if it is busy inside intensive computation interrupt does nothing — while if io is happening an exception will be raised (but still possible it will be swallowed i guess?)
What is your function doing? Listening on a socket, processing data in a loop?
My function doing caluclation on huge data, if it take more time I need to return nil , - which is my requirement
https://clojuredocs.org/clojure.core/future-cancel
(def job (future (Thread/sleep 10000)))
(future-cancel job)
cancelling threads preemptively is technically possible but risks crashing the vm
if your job periodically sleeps, or waits on IO, or explicitly checks the cancellation status of its thread and exits if cancelled, future-cancel
will work, but it won't do anything to a "hot loop"
(future-cancel is not using a preemptive cancellation, it's relying on one of the "cancellable" methods being called)
also the deref
function (what @
expands to) takes an optional time-out number and an alternative value to return if the time-out is exceeded
which might match what you want
https://stackoverflow.com/questions/6694530/executing-a-function-with-a-timeout how about example given here/
also, on some operating systems, it might be simpler to spawn a second vm, and force that vm to shut down
the "accepted answer" is from a source I usually trust - amalloy is a smart guy I learned a lot from (we were both very active on IRC back in the day), but this answer is dangerously wrong. it uses the stop
method on Thread
, which is extremely dangerous and can crash the vm:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#stop()
future-cancel
is safe, you just need to make sure the code you are cancelling is inside a future
and that it periodically waits on IO, or calls Thread/sleep
, or in some other way makes itself cancellable
details here:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#interrupt()
to be extra safe you could make sure the loop executing in the thread checks the return value of the interrupted
method
how about writing similar code https://github.com/flatland/clojail/blob/master/src/clojail/core.clj#L24
again, Thread.stop is not safe
oh yeah!
what is your work doing for more than 10 minutes?
if it's IO, it can be interrupted()
My function doing caluclation on huge data, if it take more time I need to return nil , - which is my requirement
writing code like that is a lot more complex than just using a future and calling future-cancel after some time period, that code you linked is what I was referring to being unsafe because of stop
please describe the calculation?
pure math? I/O?
it calls the lambda service
then it's waiting on IO (network)
then future-cancel will work
is the Lambda the thing you're trying to stop? or are you trying to stop the thing calling the lambda?
lamda taking more time to perform calculation. my requirement is timeout if more than 10 mis
Is str/index-of
the best way to see if a string contains a char (represented as a string)? I love writing if "a" in "casablanca"
in Python
for a simple character check, index-of
is your best bet, unlike python clojure values simplicity of syntax over intuitive / natural language like syntax
I felt like contains?
sounded like it could have done the job, but it is for associative structures.
I guess you could do (contains? (set "casablanca") \a)
but I don't think that really addresses your needs
and it does a lot of work you don't need to do
Agreed. But I felt like checking the value of an int was a bit... C-like?
you could also do (first (filter (set "a")) "casablanca")
but that still does a lot of work you don't need to do
There’s str/includes? That has a name that indicates what it does similar to your expectation for contains?
AWS Lambda?
@endrebak85 one nitpick: it's not c-like in that (if (str/index-of "casablanca" "a") :yes :no)
actually works direcly - it returns nil which if treats as false, on failure
yes
Thanks! It did not show in lein rebl
for some reason
So I assumed it did not exist
@noisesmith future-cancel
how to pas the minutes?
what clojure version?
True! I just assumed that it would return -1 instead of false. But that would have been extremely unclojuric.
you need something else (eg. (future (Thread/sleep (* 10 60 1000)) (future-cancel worker))
)
Bad habits (assumptions?) die hard. Should have tested in the REPL.
apropos and find-doc and dir are your friends here
worker is function-name here?
why not just let the lambda timeout and be killed?
here (* 10 60 1000)
turns minutes into seconds (multiply by 60), then turns seconds into ms (multiply by 1000)
worker would be the thing being cancelled
[org.clojure/clojure "1.10.3"]
where i can pass my function name
@ghadi makes a good point - lambda already has facilities to shut down after a time-out, that's the expensive resource here, it can just shut down the whole vm
Wow! Thanks for the tip about clojure.repl/find-doc
@popeyepwr you would need to use future
to start it and use the return value of future, but the way @ghadi is suggesting is better since this is running in its own vm on a lambda
oh, let me search on it! all the above conversation really helped
Leveraging the queryable nature of clojure with the built in tools will serve you well. I use those constantly. After you’re comfortable with them, learn if your editor has some integrations on top of them. Many do
in C, simple type consistency is valued over semantic clarity, the jvm's comparitive complexity allows things that are closer to the intent of the code to be expressed
I frequently use find-doc
and apropos
and javadoc
to answer questions here - I usually start with a good hunch of what should be there (or a vague memory) and let the built in introspection in the language do the rest of the work
and those tools are much more direct and helpful than google
looking up the most poetic doc string in the clojure codebase:
(ins)user=> (find-doc #"if possible")
-------------------------
clojure.core.protocols/interface-or-naive-reduce
([coll f val])
Reduces via IReduceInit if possible, else naively.
-------------------------
clojure.core/future-cancel
([f])
Cancels the future, if possible.
nil
Hi team how can I query current timestamp from database in Clojure project using Korma? "select current_timestamp"
(defn foo []
(select my_table
(fields (raw "CURRENT_TIMESTAMP"))))
@vnazaryan Korma isn't very maintained anymore I think, but I could be wrong. Instead I would recommend taking a look at #honeysql which is, if you ask me, one of the the best SQL generation libraries for Clojure,
thanks for suggestion, will take a look.
In addition to the #honeysql channel for HoneySQL, there's also a more general #sql channel for general SQL questions -- and that also tends to be where folks ask about next.jdbc
which is the replacement for clojure.java.jdbc
. Also #hugsql if you like your SQL in separate files, outside of your Clojure code.
is there a canonical way to parallel parse/process a large file based on a regex to split up the chunks? instaparse
was overkill - all the backtracking it kept blew up the memory. I was thinking iota
and reducers
but each ‘chunk’ of the file is processed as a whole, not line by line, and marked with clear begin/end blocks. It’s a super regular unambiguous grammar, but not XML or such.
you can use re-seq
to get a lazy seq of matches of a charsequence, there's at least one lib out there that implements charsequence over very large files https://github.com/fge/largetext - may or may not work for you
but for the use case where it applies it's probably the most straightforward approach
(charsequence is the superclass of string, and you can do most "string ops" on a charsequence, they are more abstract eg. unlike string don't need to promise to exist in memory all at once)
Whats the (better?) Clojure equivalent of a SAX parser + lots of messy Java code? I know there are several ways to parse XML, and a bunch of ways to traverse the result but haven’t tried any so far.
Probably zippers.
At work, we use clojure.data.xml
(`org.clojure/data.xml`) to parse XML and clojure.zip
to navigate/modify https://clojure.github.io/clojure/clojure.zip-api.html
Thanks! 👍
actually, i recently just wanted to count some elements in a jvm with 512mb heap with a ~30Mb xml. i got an out of memory error (with zippers as well), and went with plain java stax. any idea what could have been a clean clojure solution?
(->> "huge.xml"
io/resource
io/input-stream
xml/parse
xml-seq
(filter #(= (:tag %) :Event))
count)
Execution error (OutOfMemoryError) at clojure.data.xml/seq-tree$fn (xml.clj:183).
Java heap space
@ban.istvan I wonder if this would work:
(x/count
(comp
xml-seq*
(filter #(= (:tag %) :Event)))
(-> "huge.xml"
io/resource
io/input-stream
xml/parse))
where
1. xml
is clojure.data.xml
2. x/count
is from https://github.com/cgrand/xforms
3. transducer version of xml-seq, something like:
(def xml-seq*
(fn [rf]
(fn
([] (rf))
([result] (rf result))
([result input]
(rf result (xml/xml-seq input))))))
(I have not actually tested this code ;))
So, speaking of - can anyone point to code, or pseudo-code, or any inspiration on how to idiomatically traverse a tree (SAX-style), where you obviously sometimes need to keep track of the depth or other data to figure out what to do with leaf nodes.
(Slowly trying to leave my Java/imperative brain behind, but it’s… sticky.)
SAX style is awful because it presumes mutation and accumulators
StAX is a bit nicer, IMHO, and lends itself to a more functional handling
Ah, hadn’t even heard of StAX. Will study and catch up with the times…
non-lazy xml -> clojure data routine
🍻
I noticed there are two libraries: clojure.xml
and clojure.data.xml
. What's the difference between them?
clojure.xml
is built-in but it is old/deprecated and should not be used. clojure.data.xml
is a Contrib lib that is well-maintained, more modern, more feature-rich.
Ok, thanks @seancorfield
Could something like pipeline
and partition-by
from clojure.core.async
be an idea? Read the file line by line onto a channel, partition into chunks which then get further processed in a pipeline.
It allows for a nice decoupling between reading, splitting into chunks and parsing.