This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-10
Channels
- # announcements (4)
- # babashka (29)
- # beginners (15)
- # calva (4)
- # cljs-dev (1)
- # clojure (28)
- # clojure-dev (13)
- # clojure-europe (3)
- # clojure-india (1)
- # clojure-spec (7)
- # clojure-uk (5)
- # clojurescript (37)
- # component (2)
- # conjure (60)
- # cursive (2)
- # datomic (1)
- # emacs (1)
- # figwheel-main (18)
- # fulcro (38)
- # graalvm (6)
- # graphql (13)
- # helix (14)
- # jobs-discuss (1)
- # joker (5)
- # lein-figwheel (2)
- # nrepl (3)
- # off-topic (15)
- # other-languages (1)
- # other-lisps (1)
- # pedestal (2)
- # reagent (8)
- # reitit (44)
- # shadow-cljs (83)
- # slack-help (8)
- # spacemacs (1)
I'm writing an app that uses the ring-jetty-adapter. I need it to not output any form of logging. It seems to automatically do so to STDERR at startup. I've read that in javaland (of which I have zero knowledge) there's a way by setting
Properties p = new Properties();
p.setProperty("org.eclipse.jetty.LEVEL", "WARN");
org.eclipse.jetty.util.log.StdErrLog.setProperties(p);
But I have no idea how to do something like this in Clojure before the app starts up and auto-writes that first debug line. Any help would be much appreciated!option 1: use java -Dorg.eclipse.jetty.LEVEL=WARN …
option 2: create a resources/jetty-logging.properties
file
option 3: configure a logging framework (e.g. slf4j+logback) and configure logging in the logging properties file
more info at: https://www.eclipse.org/jetty/documentation/current/configuring-logging.html
That JVM property doesn't seem to suppress logging:
$ clj -Sdeps '{:deps {ring {:mvn/version "RELEASE"}}}' -J-Dorg.eclipse.jetty.LEVEL=WARN
Clojure 1.10.1
user=> (require '[ring.adapter.jetty :as j])
2020-05-09 18:32:08.414:INFO::main: Logging initialized @6777ms to org.eclipse.jetty.util.log.StdErrLog
nil
user=>
@noah I assume that's the sort of logging you're trying to suppress?
@seancorfield exactly
I ended up solving it with a little hacking in the logback.xml file created for a similar project with luminus. It's not a perfect solution, as I really only wanted to stop that first line from being output to the screen and then let any additional ones print as normal if the user passed arguments that would start the server. But it's workable. I'm just logging everything to a file now and nothing to the screen. Thanks again for the help.
Is there a way to print the source of user defined functions in the repl? I've googled and found source
but that doesn't print anything but nil
for my functions
No, the source code is not stored in memory (the compiler generates bytecode and the source is thrown away)
The source macro works because sometimes there is enough information to retrieve the source for a given definition from disk again
Question about protocols/records. I managed to not use them, even though I’m full time professionally programming in clojure for 4 years now (always use multimethods) 🙂 Today I want this to change. ;-)
So: given this:
(defrecord MyRecord [this] MyProtocol (my-fn [this] …))
If I have a function that takes a MyProtocol thing, how can I call my-fn?, ie. this doesn’t compile it seems, even if defined in the same namespace:
(defn some-other-fn
[^MyProtocol x]
(my-fn x))
@kah0ona protocol functions like my-fn
already have some type smarts within them, so it is not necessary to type-hint that argument to MyProtocol. (If you extend your protocol to cover Strings, those will not implement that MyProtocol type, so that hint won't be correct)
aaaaah ok then my thinking was kind of correct, but i was a bit confused by my error message
so what I am pondering is this…
Say I have a protocol called Executable
with a start
and a stop
method. Then I have a MyRecord
implementing this protocol, and its start message fires up a thread to do some long running work.
I would like to be able to ‘interrupt’ that through the stop
method (called from ‘outside’). But they don’t share scope right?
How to do such a thing? It probably would mean having some sort of global atom (or something else) I presume?
Would this be an idiomatic way of doing things? I can also imagine instead of a stop
method, just supply a kill-chan
arg to the start
method, which the implementor has to act upon… But not sure if that’s better.
Because I would like to have many implementations (records) of Executable
that can do various long running things, and can be interrupted from the outside based on some business logic.
Do you mean something like below?
(defprotocol IExecutable
(start [this])
(stop [this]))
(defrecord Executable [f future-atom]
IExecutable
(start [_this]
(reset! future-atom (future (f))))
(stop [_this]
(future-cancel @future-atom)))
(defn executable
[f]
(->Executable f (atom nil)))
(def proc (executable #(do (Thread/sleep 10000) (+ 1 2))))
(start proc)
(deref (:future-atom proc))
(stop proc)
Beware that canceling futures could not work correctly, check https://github.com/pfeodrippe/arrudeia/blob/master/src/arrudeia/core.clj#L39
The executable
function creates a Executable
instance. Executable
receives as args a function which will be called and a atom which will be used to store the future created.
The basic structure I use for that kind of thing is start starts a thread that does something, and stop signals that thread to exit, then waits for it to exit
The are different ways to do that, often I use core async channels, and have some channel that is used to signal the thread to stop, and another channel that signals the thread has stopped