Fork me on GitHub
#clojure
<
2015-08-25
>
cigitia00:08:15

@bmay: I think I figured out the IllegalStateException: I/O in transaction problem from yesterday, which has a bunch of factors: 1. clojure.java.jdbc/db-do-commands uses clojure.core/io! (unless its transaction? parameter is false). 2. clojure.core/require apparently causes a Clojure transaction to occur, somewhere, which prohibits any io! blocks from being called. 3. I was using the REPL to directly require a namespace that directly called jdbc/db-do-commands. Apparently, you are not allowed to require any namespace that somehow invokes io! at the top level. (ns foo.bar) (io! (println "Test")) then (require 'foo.bar) will thus throw a similar IllegalStateException.

cigitia00:08:12

The solution was to change my code to not call db-do-commands (and thus the io! block inside) at the top level of the namespace.

danielcompton01:08:52

@cigitia: causing side effects of any kind when requiring a namespace is generally discouraged

bmay01:08:11

glad to hear you figured it out

bmay01:08:02

is there a way to expand the error window i get when reloading cider using C-c C-x?

bmay01:08:14

when i try to scroll through or click, it just disappears

bmay01:08:30

also, does clojure not allow numbers in function names?

bmay01:08:40

i was getting an eval error when i had one in there

angelini03:08:00

can prismatic/schema be used to describe function parameters or fields? [a :- s/Int callback :- s/Fn]

voxdolo04:08:37

Any suggestions for SaaS application performance monitoring for clojure? I'm not loving Newrelic.

tel05:08:42

angelini: yeah, with something like (s/=> s/Any s/Any) but the schema won’t have it’s args checked unless it arises from an s/defn form.

ricardo06:08:59

Anyone using bidi and ran into an odd error where just adding it to the project causes a NRE on ring on start?

ricardo06:08:19

I expect it’s a library conflict, trying to narrow it down right now.

ricardo06:08:43

(Currently going through the logbot archives)

ricardo07:08:06

Hmm, yeah, that one was more helpful. Seems that it’s because bidi depends on ring-core 1.3.2, and I have 1.4 elsewhere on the project. Excluding 1.3.2 from bidi fixes it.

mihailt12:08:19

does somebody have a clue? can’t figure troubles with resource file having in project.clj

:resource-path "resources"
having file in
resources/android-service-account.p12
in code
(def service-account-key (->> "android-service-account.p12" io/resource io/file))
works when id do lein run or lein repl, but when i build an uberjar i throws java.lang.IllegalArgumentException: Not a file exception, if i look inside a jar file is there

nberger12:08:41

io/resource when in the jar returns a URL, not a file. See (shameless plug) http://stackoverflow.com/a/30873594/1389573 for more details. td;dr: use slurp or create an io/reader

mihailt13:08:44

@nberger: don’t need slurp, need io.file to pass it to java fn via interop

nberger13:08:58

Ok, I thought you were asking why it was complaining about being "Not a file", and I think that's the explanation simple_smile

nberger13:08:10

As of how to workaround it? I guess there are multiple ways... one could be to copy the resource to a file and use it from there

nberger13:08:36

Another could be to "hack" the url removing the "jar:file:" part and use it as a file... I don't know what are the risks of doing that

nberger14:08:47

@danielcompton @bostonaholic: Finally made the fork of ring.middleware.logger and refactored it so it can be used with tools.logging (now the default), onelog or timbre. PR: https://github.com/pjlegato/ring.middleware.logger/pull/17. There might be many rough edges, because I added just what I needed (well, I dont really need tools.logging now but added it as the default option)

nberger14:08:21

if you want to give it a try, use the 0.6.0 branch from my repo, there you'll find the clojars coordinates for 0.6.0-SNAPSHOT: https://github.com/nberger/ring.middleware.logger/tree/0.6.0

pupeno15:08:50

How do I get the current URL in compojure?

voxdolo15:08:35

pupeno: it's parsed into pieces, but available inside the request that's passed to the routed functions. You'll be most interested in :uri, :query-string and [:headers "host"]

voxdolo15:08:11

oh, and :scheme

voxdolo15:08:34

That's a ring thing too, rather than strictly compojure

pupeno15:08:39

So, I have to re-construct it from the pieces. sigh

pupeno15:08:12

It feels like I’m re-building basic information that existed to begin with:

pupeno15:08:15

(GET "*" {uri :uri query-string :query-string} (render-app (str uri "?" query-string)))

zentrope16:08:03

At least you can add some middleware that attaches it to the request for all subsequent handlers.

cfleming16:08:39

Hi all, 5 years too late I’m exploring the world of web-apps with Component, Ring etc

cfleming16:08:16

One thing that I can’t figure out is a clean way to pass Component dependencies into Ring handlers defined with Compojure

cfleming16:08:26

Is there an example of a nice way to do this anywhere?

zentrope16:08:01

@cfleming: One way to do it is via middleware. Just attach a :db <ref> to all requests.

zentrope16:08:39

Another way is to not use the defroutes macro, but just call (routes …) from within a function, and use closures.

zentrope16:08:01

(defn make-routes [db ldap hub] (routes (GET “/foo” …..))

nberger16:08:17

@cfleming: also, if you are going to use compojure-api, there's wrap-components. See: https://github.com/metosin/compojure-api#passing-components-via-request

cfleming16:08:32

@zentrope: Nice, thanks, I think I like option 2 better

rauh16:08:11

@pupeno: ring.util.request/request-url does the assembling for you

zentrope16:08:20

@cfleming: The prob I have with the 2nd option is that I end up having to restart the http-runner when I change functions.

pupeno16:08:40

@rauh: thanks, I’ll look into it.

zentrope16:08:20

Adding components to the request seems, somehow, wrong, I admit.

cfleming16:08:32

It seems like I should be defining my endpoints as components somehow

zentrope16:08:39

But then the request itself is a big map of “params” (so to speak).

zentrope16:08:14

It’s nice to (defn whatever-handler [{:keys [db ldap]}] or what have you. At least it’s clear (ish).

cfleming16:08:31

Yeah, I can see that.

cfleming16:08:36

Ok, I’ll go with that for now.

zentrope16:08:24

But @nberger’s link seems interesting.

cfleming16:08:24

So then you have a component for your app which creates the routes and adds a middleware assoc’ing in the deps?

zentrope16:08:22

Yes. Something like: (defn make-app [db ldap] (-> (make-routes) (afix-db fb) (afix-ldap ldap)) ...

cfleming16:08:47

@zentrope: @nberger: It does look interesting, but I think that’s more deps and magic than I need to just do this right now.

zentrope16:08:22

Right! I keep experimenting. I’m using Aleph, not Compojure, and made my own system for routing.

cfleming16:08:42

Nice, it’s good to understand what’s going on under there

zentrope16:08:59

I have a hash-map of handlers {:method :get :handler fn :mw etc}, then just have a single handler that takes that map and figures out how to route.

nberger16:08:18

@cfleming yes, I agree, it includes a ton of stuff that you might want, or not

zentrope16:08:19

Clunky, but I love trying to be more data driven, figure out what works for a given type of app, etc.

cfleming16:08:42

I feel like if I understood Ring (or perhaps Compojure) better I’d be publishing the individual endpoints as components and combining them into a handler in some way.

cfleming16:08:04

Looks like duct does something like this.

nberger16:08:01

I used it in a project to add validation of params given a schema and also generate a swagger.json and ui from the same schema

cfleming16:08:20

Yeah, for API endpoints it looks really nice

zentrope16:08:25

What’s really fun is when you get into web-sockets.

noisesmith16:08:05

I made a component setup such that our kafka communications, websockets, and http are all routed, and then each is capable of sending messages on the others

noisesmith16:08:15

without using top level vars to bind any of these

noisesmith16:08:45

(well "each is capable" except http - you can't send arbitrary messages via your http server of course)

timvisher17:08:07

i have a bunch of services that all use lein uberjar to build an uberjar that is capable of starting an http listener and an nrepl listener. all of them produce an uberjar that works as expected, except for one which is claiming that it can’t find the nrepl server class on the classpath. lein deps :tree reports that the ones that work are depending on tools.nrepl 0.2.10 and also that the one that’s not working is depending on tools.nrepl 0.2.10. what could be going wrong here?

timvisher17:08:19

i can’t see any relevant differences between the different project.cljs

timvisher17:08:37

adding tools.nrepl as a direct dependency on the service that won’t build works

timvisher17:08:49

and running the service with lein run works (without adding the dependency)

timvisher17:08:11

for all of the projects, tools.nrepl is pulled in as a transitive dependency

nberger17:08:30

@timvisher have you tried lein with-profile uberjar deps :tree?

chris_johnson17:08:39

I would expect lein deps :tree to show you this, but the only thing that springs immediately to mind is that one of the direct dependencies of the outlier project explicity excludes tools.nrepl and that’s affecting the runtime classpath

timvisher17:08:37

@nberger: good idea. i’ll give that a go now

nberger17:08:16

Humm, perhaps I'm totally wrong about lein with-profile.... Not sure really, so please let me know :)

timvisher17:08:16

@nberger: bingo. shows up in one and not the other.

timvisher17:08:24

hmm… even more confusing though, is that the project that it doesn’t show up in is the one that works, and the one that it does show up in is the one that doesn’t work…

timvisher17:08:01

@chris_johnson: meaning another of the direct dependencies?

timvisher17:08:16

hmm… struggling to ascii diagram this but you’re saying that A → B → tools.nrepl and A → C :exclusions tools.nrepl will knock tools.nrepl off the classpath?

timvisher17:08:20

just for an uberjar?

timvisher17:08:01

@nberger: one word for it. 😉

nberger17:08:07

Or not so cool, as I'm reading all the details :P

timvisher17:08:11

oh jeez. i’m realizing what might be happening. doesn’t lein inject tools.nrepl into one of the default profiles by default?

timvisher17:08:13

yeah. i think that’s what’s happening. i think i thought i was pulling tools.nrepl in via cider-nrepl, which doesn’t depend on tools.nrepl, but was instead pulling it in from elsewhere or getting the default tools.nrepl. didn’t lein used to warn about this?

cigitia18:08:31

Which is more idiomatic: (= string "") or (empty? string)?

darwin18:08:49

@cigitia: empty? version will return true for nil string

potetm19:08:32

@cigitia: I almost universally actually want clojure.string/blank? when I’m checking empty string.

potetm19:08:55

But of the two, I find the = version more explicit.

timvisher19:08:02

@potetm: does blank? snag whitespace only strings as well?

potetm19:08:30

I usually end up wanting that once I consider it.

timvisher19:08:33

does lein have internal support for echoing the version of the project?

timvisher19:08:36

maybe with lein pprint?

timvisher19:08:19

oh nice lein pprint :version

wunsch19:08:40

When I use Emacs+Cider and I call C-c C-x to refresh the project, for some reason I lose access to the pprint fn. Anyone know why this is?

wunsch19:08:10

oh sorry, didn’t realize there was an Emacs channel

sveri19:08:37

anyone seen this message: AssertionError Assert failed: (not (fr/NoFilter? f1)) clojure.core.typed.subtype/subtype-filter? (subtype.clj:1114) from core.typed and knows what might be wrong?

michaeldrogalis20:08:12

Is there a Lein command that one could run to get the project.clj version printed to stdout?

michaeldrogalis20:08:45

Oh ha, @timvisher. I see you asked just a few lines above simple_smile

danielcompton20:08:10

@nberger: I don’t have time to look at this in detail atm, but did you see that Timbre has a tool.logging facade?

noisesmith20:08:45

timvisher: not quite the same, but I have a plugin designed to be used as an uberjar :prep-task which puts the current state of your git repo into an edn file in resources/ (with the idea that resources/ gets put in your jar of course) https://clojars.org/org.noisesmith/git-info-edn

noisesmith20:08:30

@timvisher: with that plugin one can then use tar -t to extract deploy-info.edn from the uberjar

noisesmith20:08:55

helps disambiguate what's running in staging for example

nberger20:08:23

@danielcompton: I saw that time a while ago, but didn't thought about it for the PR... what would be the advantage of using the facade? To not provide the timbre implementation in the library but explain how to use from timbre by using the facade?

nberger20:08:16

The timbre logger implementation is very short (https://github.com/nberger/ring.middleware.logger/blob/refactor-decouple-onelog/src/ring/middleware/logger/timbre.clj) and it will not pull timbre as a transitive dep, so if you don't use it, you are fine

nberger20:08:34

But perhaps I'm missing something @danielcompton

danielcompton20:08:18

@nberger: there’s not an especially great advantage, but it gives one fewer codepath to go through

nberger20:08:35

By the way, I can't find out how to use the tools.logging facade from timbre from the README, apart from a mention saying "tools.logging support (optional, useful when integrating with legacy logging systems)"

nberger20:08:30

Also, I like it that I can use ring.logger.middleware with timbre with just (logger/wrap-with-logger app :logger-impl (ring.middleware.logger.timbre/make-timbre-logger) instead of (logger/wrap-with-logger app)

nberger20:08:57

(also thinking about adding a helper like (logger/wrap-with-timbre-logger app) to do the same)

nberger20:08:03

Anyways, thanks, and please share if you have more thoughts about it, here or in the PR