Fork me on GitHub

Does anyone have any experience doing SAML 2.0 authentication and ADFS in clojure?


I see this but I don’t see how to fit the pieces together


here is a design pattern I am running into. I have a

(try ... (catch ...) (finally ...))
block. I am writing code inside the try section. I want to automatically add a function to be called in both the catch & finally blocks, and have them executed in reverse order (of appearance in the try block).


The context here is: I am doing a computation, I am allocating some resources, there may or may not be exceptions. Either way, I want to release these resources once we are out of the try block.


Sounds a lot like with-open


I'm not sure what you mean? Anything in the finally expression will get executed after both the try, or the exception blocks.


Not sure what you mean by "in reverse order"


It is fairly common to close resources in the reverse order from what they were opened


You want to release the resources in the reverse of allocating them I think?


I suspect you could generalize with-open, replacing .close with your own function


with-open doesn't quite do what I want: it assumes that Ipm stuff things into a let block, and calling .close on it


but I have code where I do a glAttachShader, then want to register a "glDetachShader" even though nothing is allocated


@the2bears: you're right about catch/finally duplication ;I did not realize finally block code is auto executed by catch blocks too


A lot of experienced Java people miss that or forget that, so not to worry.


My current best solution is:

(let [fns (atom [])]
   (try ...
     (swap! fns conj ....) ...
     (finally (doseq [f (reverse @fns)] (f)))


So what you sort of need is a construct that takes a list of resources that implement a 'allocate/deallocate' protocol, allocating in order during the try, then deallocating in reverse in the finally block


Yeah ^ that's what I used to write in Java


Perhaps you could write a with-shader macro, but then your code would end up being nested for each shader


I’m threading the same function like this:


I can use a reduce here like this:


Is there a simpler way to do this? It feels like there would be


I dont think that works on ->> and multiple argument functions require more work


The threading version is pretty readable and easy to follow.


Ah, but yeah, if it's the same function I see your point.


@qqq This is polyfitting, but being lazy you can use @the2bears suggestion to have a 'allocate/deallocate' protocol


skip the DI part of that noise for a moment


pretend that is written


basically with-open, but it works on a general component


(reify Lifecycle (start [] ...) (stop [] ...))


for the simplest case


wrap it in a (make-component start stop) to reduce clutter


might be a bit tricky since you need to return "self" as per the docs to be a proper component


@qqq let me know what ends up working for you, I want to know how to solve this problem without going through the error part of trial and error that you will have to


hey, do you guys still use gloss? why has it been archived?

Andreas Liljeqvist13:04:08

trying to generate a pom with clj. clj -Spom -A:dev fails, but clj -Spom -R:dev works.

Andreas Liljeqvist13:04:20

clj -A:dev works also

Andreas Liljeqvist13:04:45

Trying to understand why, even though -R is good enough

Alex Miller (Clojure team)14:04:53

are you on latest version?

Alex Miller (Clojure team)14:04:40

does clj -Sverbose report version ?

Alex Miller (Clojure team)14:04:44

I think this was actually fixed in the latest version

Alex Miller (Clojure team)14:04:49

-Spom is a totally different code path. It’s goal is to build a pom with top-level libs in it, not to build a classpath. So it doesn’t do all the same modifications that aliases do when they resolve-libs and build-classpath. It does try to apply some modifications like :extra-deps and :override-deps on the top-level libs, but these are done via different code entirely.

Andreas Liljeqvist14:04:45

.358, will try new version later

Alex Miller (Clojure team)15:04:26

yeah, the -A aliases were being ignored during -Spom before and that was fixed in 375

Andreas Liljeqvist14:04:04

I have extra deps in an alias that I want in pom

Alex Miller (Clojure team)14:04:16

that’s ok - those should be added

Alex Miller (Clojure team)14:04:23

assuming you’re using :extra-deps


@qqq here is the non handwavey version


Lifecycle is copied from component, with-component is just a slightly modified with-open


haskell has xmonad; is there any window manager written in Clojure ?


there’s stumpwm which is in common lisp

Alex Miller (Clojure team)15:04:20

I think Rich is working on that


prepl purpose revealed

Alex Miller (Clojure team)15:04:17

sorry, I’m about 19 days behind


I think this is the first rickroll I didn’t see coming

Alex Miller (Clojure team)15:04:38

I don’t troll often…. but when I do…


Thank god I live in germany. The video is not available here. For once and for all our almighty ruler, the content industry, has saved me 😄

Alex Miller (Clojure team)15:04:27

Here I’ll sing it for you…


I got an ad before, which ruined it


Whats is the state of clojurescript on nodejs? I want to do some system scripting but clojure startup time is too slow


There's a control for rickroll in the GDPR


@pablore people are doing it, I believe. Planck and Lumo are good entry points, but the latest cljs.main work makes it pretty easy to launch a nodejs process as well.


@john great! I’ll take a shot at lumo.


Hi all, I'm just starting a basic server using http-kit. It looks like even when the server's just idling the heap size increases; is this normal? I don't have much experience with java outside of school homework


the thing about the people in the clojure community that really sets it apart is that in all of my time being a part of it, no one has ever given up on me or let me down. it's not the kind of community where people run around and hurt one another.


thanks @alexmiller for setting such a great example


that's so mean @bronsa consider yourself banned (although maybe not as mean as subtly rickrolling everyone in here)


@squarenegative Yes, that's pretty normal. We have processes that, even when they're completely idle, show a sawtooth graph in memory usage. When the heap gets 70-80% full, you'll see a full GC (so heap usage drops, but overall system memory will not -- the JVM doesn't return memory to the host in general).


When a process is getting a lot of activity, it'll also do GC more often. And it'll also depend on which GC you're using. We use the G1 collector for, in theory, more consistent response times in a web app. For a very active process, the GC will be nearly continuous and you'll see heap usage going up and down a lot but in a much smaller window, often in the 40-60% range.


yeah, I was just testing using g1 and it seemed the heap size increased much more slowly


great, thank you


(it's an http-kit REST API)


@seancorfield What do you use for getting those metrics and generating the graphs?


New Relic. We love it! I blogged about how to add trace annotations to Clojure code, and also some stuff about startup time...;q=new+relic (should be top two results)

👍 4

@seancorfield awesome, thank you very much

Garrett Hopper17:04:03

Is there a way to destructure namespaced keywords automatically with the current namespace?

(let [{:keys [without.this.namespace/a without.this.namespace/b]} {::a 1 ::b 2}]
  [a b])


use ::keys

Garrett Hopper18:04:18

Awesome, thanks! Could we get this documented at

Alex Miller (Clojure team)18:04:45

it’s documented in the reference page

Alex Miller (Clojure team)18:04:31

actually, maybe it’s not

Garrett Hopper18:04:03

Yeah, I'd looked there too.

Alex Miller (Clojure team)18:04:13

oh…. I wrote a whole updated section for this page

Alex Miller (Clojure team)18:04:30

and never got it finalized with Rich

Alex Miller (Clojure team)18:04:46

wow, I wonder where I put that :)


New Relic. We love it! I blogged about how to add trace annotations to Clojure code, and also some stuff about startup time...;q=new+relic (should be top two results)

👍 4

what does it offer over jvisualvm?


New Relic monitors all sorts of stuff, not just memory/heap. It can show you performance of database queries etc, response times for the web apps (although http-kit is not fully supported so you don't get full web app monitoring), and external calls (e.g., to payment gateways etc).


We also have it monitoring our background processes and tracking metrics in those (I need to write up how that's done -- mostly you start a thread with the New Relic agent and tell it which function to call for "probing" your app, and you track metrics and send them to NR in that function).


It can also monitor servers: disk, CPU, RAM, I/O, availability. You can also tag deployments from your build script and so New Relic can track performance comparatively for each new deployed build.


sounds pretty cool


It also has JS you can use to instrument the front end of your apps. It's pretty comprehensive as a monitoring/health system.


is there a good library to help with repl debugging, such as viewing local values and such?

Garrett Hopper18:04:42

@U61HA86AG That's really cool; thanks.

Garrett Hopper19:04:00

I have seen that. I keep meaning to look into it more.


@seancorfield for a boot.profile is middleware the plugin equivalent?


This is REPL middleware (I assume you're talking about Sayid) so it's specific to using a REPL, regardless of Boot/Leiningen.


I guess I was referring to these instructions

{:user {:plugins [[cider/cider-nrepl "0.14.0"]
                   [com.billpiel/sayid "0.0.16"]]
         :dependencies [[org.clojure/tools.nrepl "0.2.12"]]}}
are specific to lein's profile.clj


wasn't sure the boot.profile equivalent to the plugins section


@U1CUUKHDL Ah, sorry. I haven't used Leiningen for a long time. That's not what I was expecting to see from Sayid, when I read its site and it talked about REPL middleware 😐 I sort of remember some other configuration that's needed for REPL middleware. Pretty sure, in Boot, all you need is to add those dependencies.


I would expect to see some configuration for the REPL itself that installs the REPL middleware... but maybe it installs itself automatically...?


are there any performance downsides of using multimethods (defmulti )


can it be used in all use cases wherever the polymorphism needed?


@huthayfa.ainqawi performance is the major tradeoff in choosing multimethods over protocol based dispatch, so yes


it maybe be that this is a negligible performance hit on your overall program though, it really depends


is there any other ways to choose between different implementations without using protocols, multimethods or cond ?


a map 🙂

👍 8

these things are all variously implementations of single mappings trollface


except for multimethods with hierarchies.