This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-08-31
Channels
- # admin-announcements (9)
- # announcements (2)
- # beginners (16)
- # boot (18)
- # cider (22)
- # cljs-dev (10)
- # clojure (154)
- # clojure-denmark (5)
- # clojure-dev (5)
- # clojure-nl (2)
- # clojure-russia (13)
- # clojurescript (161)
- # cursive (3)
- # datomic (9)
- # editors (5)
- # emacs (25)
- # hoplon (57)
- # immutant (19)
- # instaparse (1)
- # ldnclj (2)
- # liberator (19)
- # off-topic (7)
- # re-frame (12)
- # reagent (10)
@amacdougall: 2 points.
What would be the best way to calculate an etag for a ring resource? Is using the built in hash function in Clojure strong enough, or is there a faster/better way?
casperc: Thats almost certainly not strong enough -- that returns the objects hashCode... which is used by java to store objects in hashmaps
hashcodes aren't cryptographic - and can get a lot of collisions
better to use a sha1/md5 etc...
depending on your usecase
lein uberjar works locally but fails with "Uberjar aborting because jar failed: Subprocess failed" when run by dokku. Any ideas how to debug?
@afhammad: chances are the process it runs is java
, right?
so maybe there's an issue about (the correct) java
not being in the PATH
or, indeed, jar
@pesterhazy: So I tried this locally on a freshly installed dokku on vagrant, and it went smoothly, however its failing on digitalocean's default dokku setup
@afhammad: any way to get better debug logs (console output of the failed jar
command)?
@pesterhazy: the output looks normal (as compared to running locally) and just before it would normally finish it ends with: Uberjar aborting because jar failed: Subprocess failed ! Failed to build. To <mailto:[email protected]|[email protected]>:app ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to '<mailto:[email protected]|[email protected]>:app'
@pesterhazy: digitalocean support's first response are claiming it might be a RAM issue, and that i should upgrade..
@afhammad: that sounds like a pluasible explanation
you can try GNU time to measure the peak RAM usage of a process
@rickmoynihan: Sorry, I missed your response. I know the hash function is not cryptographic, but it could be “good enough”, since you are basically just trying to avoid a collision with the last version of the resource served. It doesn’t need to be globally unique. md5 is a good option, but it is going to take some more CPU time to produce (I would suspect).
@casperc: the hashes won't be unique or identical across process restarts either
@casperc: hashCodes are really only for putting objects in collections - you can't rely on the quality of the hashCode implementation
@pesterhazy: Really? I thought they were created from the input only.
@pesterhazy: they should definitely be the same across process restarts
@casperc: regardless use a digest -- hashcodes can get a lot of collisions - depending on the object
@rickmoynihan: according to wikipedia, "[t]here's no requirement that hash values be consistent between different Java implementations, or even between different execution runs of the same program"
you'll get really hard to track bugs otherwise... for example object foo
and foo1
could easily generate the same hashcode... sure its unlikely -- but the 1 in a thousand time it does things will be very broken
@casperc: if you json'ify anyway, why not use the JSON representation as a base for the cryptographic hash?
@pesterhazy: more for practical reasons. We use liberator, and that has a stream in the ring response at the point where we can hook into the request itself, so I would have to consume it.
@pesterhazy: the contract is equal objects MUST have equal hashcodes... yes different JVM implementations may implement hashcode differently and I guess different executions might generate different hashcodes if they use e.g. object identity... so yeah when I said definitely I guess I meant 'usually'
regardless hashcodes should only be used for putting things in collections
"Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application."
Oh, I see @pesterhazy already mentioned that.
not sure what the JVM does, but some VMs base the hashcode of objects on their memory address, so they're definitely not consistent across runs
@pesterhazy: I guess they were right, upgrading to 1GB RAM fixed it..
@afhammad: uberjar shouldn't really consume that much RAM, but people probably just haven't run into this problem often because it's a short-lived process
This one by Ierusalimschy? http://www.inf.puc-rio.br/~roberto/docs/peg.pdf
Hi. If I need to have map with like 10 mln keys, would be in-memory Datomic DB more performant than just Clojure map? Just got java.lang.OutOfMemoryError: GC overhead limit exceeded, so, what rather should I use?
I'm building a project with a client/server architecture, i.e. a jetty server and a browser UI to work with it. I need the user through UI to select an arbitrary file and pass it over to the server. How is this done? If I understand correctly the server only sees stuff on its classpath. Does the file need to be POST
ed to the server?
xifi, Yes, you want a POST request. You’ll also need to use a multipart enctype form with an input tag using the type=“file” attribute. The backend just needs to handle that sort of request so that it can save the file somewhere
@xifi: in ring this is done via: https://ring-clojure.github.io/ring/ring.middleware.multipart-params.html
Hi. How do I sent Clojure vec like ["foo", "bar"} via Clojure JNA to function that excepts char**?
thanks @csmith and @borkdude . Yes I am using ring-defaults so I have the middleware running. Now just to tackle the form. Will the uploaded file be available on the classpath?
From there you save it to where you want, which could be on the classpath but you probably don’t want to upload code this way?
@xifi: I'm copy pasting this from a project where I handle an uploaded file where input has name = "excel":
excel is a hash-map where the file is available under the key :tempfile, just inspect it
@andrewboltachev: for the in-memory map, http://www.mapdb.org/ might be worth checking out
@pesterhazy: thanks!
alternatively, sqlite is always good, or h2
I wonder if Datomic would be good for 10mln
overkill if you're not using >1 clients
Just noticed that metosin/compojure-api allows this:
(DELETE* "/user/:id" []
:middlewares [audit-support (for-roles :admin)]
(ok {:name "Pertti"}))
...so if your authorization logic is route-specific, it might make sense to reference it there.@amacdougall: Here is also an example of using Buddy-auth with compojure-api: https://gist.github.com/Deraen/ef7f65d7ec26f048e2bb
Oh, thanks! This is good stuff. ...I get it, compojure.api.meta/restructure-param
lets you define your own params in terms of existing ones, so this ends up being a nicer syntax for using access rules as route-specific middlewares.
@pesterhazy: That looks pretty perfect, yep. Thanks.
Hi. How do I install library like this to use from Clojure? https://github.com/dren-dk/HunspellJNA I've installed it by "mvn install" but (import 'dk.dren.hunspell.Hunspell) raises java.lang.ClassNotFoundException
@andrewboltachev: if you're using leiningen, it will nee to be in your project.clj
in order to be added to the classpath
@bostonaholic: thanks, worked after adding to :dependencies
@martinklepsch: #C053K90BR
What's your usual technique on having multiple versions of a service, (e.g. email), with an in-memory version for when running tests and a live version (e.g. AWS-SES) for production?
build some impls of a protocol like EmailProvider and make your namespace's functions take it as the first arugment
The solution we have now is that there's a default in-memory implementation, just made up of normal vars, like (defn send-email [to from subject body] ...)
, and there's an alternative implementation in an adjacent namespace that actually uses SES, along with a function go-live!
which just uses alter-var-root
to replace the default implementation with this one.
I ran (jetty/run-jetty #'my-handler {:port 8080}) and now inside CIDER I evaluated (defn my-handler [] {:status 200 :body "ok so far"}) with C-x C-e and refreshed my browser but the change is not visible. What am I missing or doing wrong?
it looks like in the source it’s this guy? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java
I felt like the “file” lookup was essentially get
so I wanted to try not duplicating names
implementing ilookup implies you're passing things around to code that already uses get generically
like, I implemented IOFactory on hadoop paths so slurp could work on hadoop input-streams, for example.
Yea, i don't quite understand the api, but my first inclination would be to write the new functions anyway, then delegate Ilookup impls to those if convenient.
yeah, given the complexity I’ve already stepped into I agree with the approach you advise here
but I would certainly not cry if “local” work could be performed naturally by anything which expects a hashmap
@gtrak: also, whats an x-y problem? I’ve heard the term before but I’m not exactly sure what it means
so i have a list of maps that look something like this {:key “value” :type :type1 :some-other-random-key “another value"} and i want to end up with a list of lists like what partition-by returns, but i’m not sure how to construct my predicate so that the interior lists are grouped by :key and :type, but the overall order is maintained
For those of you who play League of Legends, I worked with Pepijn de Vos to make an item set builder in pure ClojureScript: http://pepijndevos.nl/2015/08/30/generating-league-of-legends-item-sets.html
awesome @aengelberg