Fork me on GitHub
#clojure
<
2017-06-26
>
erwinrooijakkers08:06:33

Does anyone know how to store state in one instance of a simulation in clj-gatling? /edit Answer from the docs: http://i.imgur.com/SISAxzT.png

erwinrooijakkers08:06:49

Hmm looks like the context is passed along in every step. Hopefully I can just assoc.

erwinrooijakkers08:06:30

That’s not it. associng to that context is not persistent

erwinrooijakkers09:06:12

One solution is to keep a separate database, but it is not very clean

erwinrooijakkers09:06:33

Aaah you can send the context forward

erwinrooijakkers09:06:41

Return [result context]

erwinrooijakkers09:06:28

Next question: in clj-gatling my response times are way longer than they actually are. It seems like it is not only counting the time my request takes, but also the time it takes to run on my computer. Is there a way to fix this?

erwinrooijakkers10:06:00

When I time the request

(defn login-request [ctx]
  (go
    (time (let [{:keys [status] :as res} @(http/get ""
                                                    {:headers {"Accept" "text/html"}})]
            [(= status 200) (assoc ctx :state "state")]))))
It prints “Elapsed time: 200ms”. But the end result in the Gatling reports states it lasts longer than 1200ms.

jgeraert10:06:17

why is it wrapped in a go block? Is clj-gatling designed around this

jgeraert10:06:38

cause you're doing a blocking call with @?

erwinrooijakkers11:06:13

If I don’t wrap it in a go-block the same problem occurs

erwinrooijakkers12:06:58

I think if I use

(defn- http-get [url _]
  (let [response (chan)
        check-status (fn [{:keys [status]}]
                       (go (>! response (= 200 status))))]
    (http/get (str base-url url) {} check-status)
response))
like in the example things will work.

erwinrooijakkers14:06:49

Okay not using a go block works!

erwinrooijakkers14:06:16

This works:

(defn login-request [ctx]
  (let [check-result (fn [{:keys [status]}] (= status 200))]
    (http/get ""
              {:headers {"Accept" "text/html"}}
              check-result)))
No problem 🙂 Up to 4000 users

branch1414:06:18

How can I refer to a var inside ns1 when the macro defined in ns1 is called from ns2?

(ns ns1)

(defn a-fn* [] "hello")

(defmacro a-marco []
  `(defn a-fn [] (a-fn*)))

(ns ns2)

(ns1/a-marco) ;=> Can't refer to qualified var that doesn't exist

bronsa14:06:43

that's going to work

bronsa14:06:57

I don't believe you see that error message on a fresh repl, you must have some stale state

bronsa14:06:25

also that macro is slightly wrong, should be

(defmacro a-macro [] `(defn ~'a-fn [] (a-fn*)))

bronsa14:06:35

needless to say macros like that are discouraged in clojure

jcromartie14:06:41

I'm playing with an event sourcing/CQRS style system in Clojure. It involves some number of load-balanced app servers. My idea is to have local in-memory caches, and then "catch up" by applying pending events before any read operations.

jcromartie14:06:03

I'm trying to avoid having any extra pieces like a message queue

jcromartie14:06:26

does that seem sane?

branch1414:06:55

@bronsa It worked, with the unquote-quote. But now I'm pretty discouraged.

bronsa14:06:56

generally, macros that inject global names into a namespace are not idiomatic in clojure

bronsa14:06:47

a slightly better version would be e.g.

(defmacro a-macro [name] `(defn ~name [] (a-fn*)))
but still, this doesn't look like a very useful macro

valyagolev14:06:17

they have their uses, probably finding out what is the goal is a step to take before judging something as not idiomatic

bronsa14:06:18

why would you intern a var in a namespace that just delegates to a var in another? just refer that one directly

bronsa14:06:40

coming off as judgmental was not my intention, if that's how it came across

a1314:06:52

#'ns1/a-marco

branch1414:06:48

delegating is part of if, passing some variables, but not all is the other half (something like partial, but on macro level)

branch1414:06:07

I couldn't use partial because what's passed might be an atom that needs to be derefed later.

branch1414:06:36

Needless to say my example was stripped down to the bare minimum to illustrate the problem I was having. 🙂

dominicm16:06:47

Wondering what people do for translations in their application? The key based stuff puts me off (https://translation.io/blog/gettext-is-better-than-rails-i18n), and I'd like to use industry-accepted systems (PO, XLIFF, MessageFormat). Doing this for cljs & clj.

tianshu16:06:14

How can I extend a type, like java.util.HashMap to support conj. Which is the protocol for that?

bronsa16:06:57

you can't in clojure

bronsa16:06:15

clojure implements its basic operations in terms of interfaces not protocols

bronsa16:06:38

right, you can do that if you're in control of new types but it's simply not possible to retrofit on existing types like java.util.HashMap

bronsa16:06:25

(and even it it could be possible, conj is defined as an operation on persistent colls, so on mutable ones it would be breaking its contract)

tianshu16:06:32

okay, so If I want to wrap something, for example Array[ResultSet] to vector of map. I can't just extend-type, I should iterate it.

tianshu16:06:44

thanks for help!

noisesmith17:06:10

@doglooksgood you could define a multimethod which is identity for vector of hashmap, but uses into to populate clojure datatypes if it gets arrays and java.util.HashMap

alricu18:06:39

Hi all, I am trying to load a keystore file in clojure:

alricu18:06:48

(let [a (try (java.io.FileInputStream. keyObjectFile) (catch Exception e (println (str "1caught exception: " (.getMessage e)))))] (println a) (try (.load keystore a) (catch Exception e (println (str "2caught exception: " (.getMessage e))))))

alricu18:06:04

but I am getting: java.io.FileInputStream cannot be cast to java.security.KeyStore$LoadStoreParameter

robert-stuttaford18:06:17

@alricu

(defn load-key-store [keystore-filename keystore-password]
  (with-open [is ( keystore-filename)]
    (doto (java.security.KeyStore/getInstance "JKS")
      (.load is (.toCharArray keystore-password)))))

alricu18:06:01

mm i do not have the keystore-password

alricu18:06:09

i need only the file

robert-stuttaford18:06:56

check the javadoc of java.security.KeyStore/getInstance maybe there’s a method that doesn’t need a password?

alricu18:06:09

actually, the load does not need a password

jcromartie18:06:18

the password can be null i.e. nil

alricu18:06:21

can I set something like:

alricu18:06:29

(defn load-key-store [keystore-filename]
  (with-open [is ( keystore-filename)]
    (doto (java.security.KeyStore/getInstance "JKS")
      (.load nil))))

jcromartie18:06:02

or you could use the defn from above and just call (load-key-store filename nil)

jcromartie18:06:24

then you won't have to change it when you do have a password on the keystore

alricu18:06:55

ok perfect I am gonna try and let you know what happens!!!

alricu18:06:34

mmm now I have a problem when I put in the jetty configuration the Keystore object it send me this error in the browser

alricu18:06:46

SSL_ERROR_NO_CYPHER_OVERLAP

alricu18:06:05

in jetty I put

alricu18:06:19

:keystore (load-key-store "filename") 

alricu18:06:25

and send me that message; but if I put the path it works,.

alricu18:06:43

:keystore "path to file" 

alricu18:06:24

any idea why this is happening?

hiredman18:06:02

it means the ssl server and your browser are unable to agree on a cipher suite

hiredman18:06:19

which is likely due to using an out dated version of either

jcromartie19:06:27

BTW I would strong recommend against doing SSL termination in Jetty

jcromartie19:06:50

it's much better to do it with a reverse-proxying load balancer

jcromartie19:06:20

e.g. NGINX or an ELB in AWS

jcromartie19:06:45

you can do SSL termination in Jetty just fine but it just doesn't seem worth the effort when other tools do it better

jcromartie19:06:11

if you really really really need one host to serve up HTTPS from a single Java process, then sure

jcromartie19:06:24

otherwise you're probably already deploying your app behind something that can do SSL termination

jcromartie19:06:38

or you should be

jcromartie19:06:52

sorry, #off-topic and uninvited advice

jcromartie19:06:49

but if you're developing a web app in Clojure, trying to set up SSL in Jetty is probably pretty orthogonal to the real problems you're trying to solve

alricu19:06:18

yeap!!! actually jetty is working well for what I need!!!

alricu19:06:50

maybe there are other complex things which are not supported or they are better with other server!

jcromartie19:06:52

it's more about not doing it

jcromartie19:06:56

when you don't have to

alice20:06:16

So what resources exist for learning deployment? My app is Clojurescript with a Clojure REST api, I have a dedicated "server dude" but I don't know that he'll know what to do with me. I'm assuming for Clojurescript I'd just NGINX-up the html and js file that makes the app go round, and for clojure I guess I could just run my Compojure rest api, but that leaves the question of how tf do I load balance that and etc. I have a ton of questions about this, so if anyone has a clojure/script deployment bible, smack me with it

seancorfield20:06:21

@alice I think the answer is “the same way you’d do any JS / JVM combination web app” really — load balancing etc, and most of the deployment considerations, aren’t Clojure-specific. I know that doesn’t help but…

jcromartie20:06:03

@alice your Compojure rest API should be able to serve the HTML and compiled cljs

seancorfield20:06:12

I can tell you what we do at World Singles: we host the HTML and JS on S3 and serve that up through Amazon (using their CDN, DNS, etc) and the Clojure code gets wrapped up as uber JAR files and deployed to a bunch of servers and spun up with java -jar via scripts/services, and proxied via Apache, and F5 load balancers etc.

seancorfield20:06:00

We have a separate deployment chain for front and back end components — since they are actively developed on different schedules, by different teams.

jcromartie20:06:48

ah, my client/server (i.e. cljs/clj) code is all in one uberjar

alice20:06:37

@jcromartie some of us don't have the same kinda foresight lmao

alice20:06:54

Developing one project, oh - let's make a rest api, oh, now they're both gigantic

alice20:06:01

and here we are

jcromartie20:06:41

every project starts out fresh and beautiful, and then reality hits

jcromartie20:06:21

At least it's not a Clojure uberjar that starts up Jetty with an embedded JRuby on Rails and Spring web app loaded from precompiled WAR files.

jcromartie20:06:48

where the Rails app calls the legacy Spring app to provide a REST API 🙂

jcromartie20:06:27

and the Clojure code is creating DAO objects to be loaded by the Spring app via dependency injection

jcromartie20:06:30

all in one process!

donaldball20:06:33

That sounds terrifyingly specific.

jcromartie20:06:49

I mean, just a hunch, but I think a project like that would be pretty crazy.

jcromartie20:06:57

it would be even worse if the Spring app only communicated via SOAP

naomarik20:06:49

now i’m super curious to know explicitly if you’ve had to work on such a thing and how it came to be

jcromartie20:06:19

you should be upside_down_parrot

jcromartie20:06:46

I can make up more totally hypothetical aspects too

jcromartie20:06:15

like if you couldn't instantiate classes like (Foo.) but instead had to look them up by name every time, and the bulk of the code was interop requiring lots of this sort of thing

jcromartie20:06:31

or static method invocations

jcromartie20:06:38

without being able to do (Foo/bar)

jcromartie20:06:42

that would be silly

jcromartie20:06:44

in such a case, it would also be helpful to know how to get a Java enum value without being able to reference classes directly

jcromartie20:06:31

(.invoke (.getMethod (get-class system class-name) "valueOf" (into-array Class [String])) nil (into-array String [value]))

jcromartie20:06:55

for reference, just in case I or anybody else ever need that 🙂

jcromartie20:06:43

classloader problems suck

tjtolton21:06:59

is there any kind of string function that works with named parameters in a map? like python's string formatting (3+)?

tjtolton21:06:46

(format "hello {:foo}" {:foo "world"})

mobileink21:06:34

tjtolton: (format "hello %s" (:foo m))? what am i missing?

tjtolton21:06:52

or something

noisesmith21:06:39

that’s close to how selmer does templates https://github.com/yogthos/Selmer

tjtolton21:06:11

hahahaha, nice

noisesmith21:06:12

maybe we should call it juxt

tjtolton21:06:59

lol, nobody is gonna be cool with me pulling in a whole template rendering library for the string parser

noisesmith21:06:58

I wonder if something similar could be hiding deep in clojure.pprint/cl-format

tjtolton21:06:21

I should probably just use format and not be a lazy person. I dont have a special use case, I just margianlly prefer the syntax

madstap21:06:36

There's a lot of stuff hidden in cl-format

noisesmith21:06:43

insane stuff

spieden22:06:26

we just released the library we wrote for AWS Step Functions, in case anyone’s interested: https://github.com/uwcpdx/stepwise

spieden22:06:23

readme is incomplete but being worked on

bja22:06:24

tjtolton, it's pretty easy to write that if you (or a dependency) is already including instaparse or cljr-antlr (check lein deps :tree). See this for a minimal example: https://github.com/philipsdoctor/DST

tjtolton22:06:46

bja: neat! good suggestion. I'll take a look tomorrow morning