This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-08
Channels
- # announcements (5)
- # aws (15)
- # babashka (7)
- # beginners (138)
- # bristol-clojurians (2)
- # chlorine-clover (11)
- # cider (9)
- # clara (4)
- # clj-kondo (17)
- # cljsrn (20)
- # clojars (1)
- # clojure (73)
- # clojure-europe (17)
- # clojure-italy (1)
- # clojure-nl (9)
- # clojure-spec (4)
- # clojure-uk (9)
- # clojurescript (43)
- # data-science (1)
- # datomic (87)
- # emacs (2)
- # figwheel-main (30)
- # fulcro (71)
- # helix (2)
- # hugsql (4)
- # jackdaw (5)
- # jobs (3)
- # jobs-discuss (31)
- # juxt (5)
- # kaocha (6)
- # lein-figwheel (16)
- # leiningen (1)
- # luminus (4)
- # malli (2)
- # meander (54)
- # music (8)
- # nrepl (12)
- # observability (28)
- # off-topic (85)
- # pathom (11)
- # re-frame (99)
- # reitit (9)
- # ring (1)
- # rum (6)
- # sci (11)
- # shadow-cljs (102)
- # sql (22)
- # tools-deps (10)
- # vim (65)
- # xtdb (14)
I've been playing with @borkdude's carve, and I've started using it as a basis for building code rewriting tools. Mostly one-off things. But the code (and the clever loop that borkdude came up with) is great for rewriting old functions to new ones in an automatic way.
I'm looking for a graph database that's easy to set up and has a mature Clojure client library, any suggestions?
Highly recommend Crux. https://opencrux.com/docs
here's an example of how to get a single node setup: https://github.com/dvingo/my-clj-utils/blob/master/src/main/dv/crux_node.clj
@U051V5LLP Just worked through the tutorial for Crux, seems really solid.
Indeed this looks really cool! Side note: def think there is some startup idea, to build a firebase-like offering, but with something like crux backing it. You can do more complex queries, remember past information, maybe a dsl that a user can use to add permissions, and bam
ha, it's def in the adjacent possible - here's a good start already: https://findka.com/biff/#introduction
@U051V5LLP You around?
I wrote a CLI script which downloads all or subsets of a public image archive, and inserts the metadata into Crux
very cool! when I was starting out with crux I ran into data retention issues, it turned out to be 2 issues: ā¢ in memory tx-logs instead of being persisted ā¢ all tx's are async by default I ended up using this helper to make all tx's synchronous for my app code https://github.com/dvingo/my-clj-utils/blob/master/src/main/dv/crux_util.clj#L60 and making sure all writes are fsync'd on the node https://github.com/dvingo/my-clj-utils/blob/master/src/main/dv/crux_node.clj#L20
The crux source has some gems as well. Here are 2 more node config examples https://github.com/juxt/crux/blob/master/dev/user.clj#L29
and a bunch more here: https://github.com/juxt/crux/blob/master/crux-bench/src/crux/bench.clj#L206
I have a code in namespace X, that code has caching via memoize. So in I have X: (def get-val (memoize load-val)) (def some-map (get-val)) (def some-key (:key some-map). Now when I import namespace X into namespace Y and try and call (prn X/some-key) - > I am getting: #object[clojure.core$constantly$fn__5394 0x50ecef36 "clojure.core$constantly$fn__5394@50ecef36"] While if I call in the same namespace, its just a plain value.
try calling it (X/some-key)
- that will return the same thing no matter how many args it is given
sounds like your namespaces are out of sync
what you provide there isn't enough to know what's wrong, as it's not how clojure behaves, something else is up on your local repl state
I'd start with a full shutdown of the repl and clean up of any cache
(eg. class files you might have generated under target/)
you(or some tool you are using) is deleting clojure namespaces, and defining them without redefining the namespaces they depend on
and in the time in between other side effecting (var value changing) code is running
and depending, your test mocking may be stepping on itself, a lot of mocking code that mutates vars is not thread safe, and may not be safe to nest
Question about writing libraries wrapping java libraries:
It makes sense (to me) to map enums to keywords and use utility functions to transform POJOs to maps. I don't want my users to .getThis
and .getThat
every time they want to work with Just Data.
Would you rather the keywords be namespace qualified?
i.e. :state
vs. :domain.object/state
. The first option looks like it might be easier to work with, at the cost of information and context loss.
What do you think?
I think it's best not to wrap things unless the API is designed to waste your time or be error prone
I guess there's also the use case of portability but that usually doesn't work as well as planned
I mean not to wrap them unless there's an urgency, in the long run it's usually causes more problems than it solves (wrappers are incomplete, the author didn't really understand the API, ...)
but that's very generic advice, and I don't mean to be combative
there might be a valid reason to make your wrapper, I just want people to consider the question carefully
I'd usually use non-namespaced keys if there is a reason to wrap, but in the big picture there's less reason to wrap a POJO, and more reason to wrap things that require inheritance (clumsy in clojure) or factories (very easy to simplify in clojure)
@ben.sless Also, when dealing with POJOs, look at clojure.core/bean
for simple cases and org.clojure/java.data
library for more complex stuff.
The latter handles the builder syntax as well as the bean syntax, and knows how to handle constructors and various other things.
LMK if you have specific questions about it.
What am I doing wrong with buddy here?
(require '[buddy.hashers]
'[buddy.auth.backends :as backends]
'[buddy.auth.middleware :refer [wrap-authentication]])
(defn authfn [request {:keys [username password]}]
(when-let [password-hash (get {"admin" (buddy.hashers/derive "admin")} username)]
(buddy.hashers/check password password-hash)))
(authfn {} {:username "admin" :password "admin"}) ; => true
(authfn {} {:username "admin" :password "wrong"}) ; => false
(defn handler [request]
{:status 200 :body "ok" :req request})
(let [backend (buddy.auth.backends/http-basic {:authfn authfn} )
app (-> handler
(buddy.auth.middleware/wrap-authorization backend)
(buddy.auth.middleware/wrap-authentication backend))
request {:headers {"Authorization" "incorrect password"}}]
(app request)) ; should return a 403, but returns the 200 response
(defn handler [request]
(if (buddy.auth/authenticated? request)
{:status 200 :body "ok" :req request}
(buddy.auth/throw-unauthorized)))