Fork me on GitHub
#clojure
<
2019-10-02
>
Eduardo Mata00:10:59

Howdy Y'all. I have been working on a small framework using pedestal io and integrant. The framework is used to create a server that serves user define APIs, State, Redis Processors, and Server Sent Events. Everything works greate, however, I noticed that when multiple clients are connected to the web app, the server sent events will only send data to one client at the time and it sends data in a particular order. The way the server sent events are implemented is with Core Async and the Pedestal library for SSE. such as

(def sse (chan 2046))

(defn stream-ready
"Get data from the sse channel and put it in `channel`. this is how SSE are sent to the client"
[channel context-map]
(go-loop []
  (async/put! channel (async/<! sse)))

(defn stream-data
"Put data in the sse channel"
[data]
(async/put! sse data))

Joe Lane15:10:51

Hi @contact904, I think if you still need some assistance with this issue you should head over to the #pedestal channel. Also, I assume you're aware of the pedestal SSE example project. I think in that example project there are 2 ways to send information, one is broadcast and the other is isolated messages to consumers. Going through that example may be helpful for resolving the "send data to one client at a time" issue you are running into. If you need a more complex pubsub approach you can always use core.async's tools for pubsub. Hope this was helpful!

Eduardo Mata15:10:11

I actually though about the pubsub approach using core.async. I use this in on of the Redis Processors.

Eduardo Mata15:10:44

@U0CJ19XAM I actually use the pedestal SSE sample to base my implementation

stathissideris08:10:34

@seancorfield hello, are you aware of any solution that would allow the usage of dependencies that are signed jars with depstar?

Alex Miller (Clojure team)12:10:25

signed jars are inherently not going to work with uberjars. signing includes the digest of the jar file and uberjar'ing will instead include the contents in a different jar file with different contents so there is no meaningful way to retain the signature.

erwinrooijakkers09:10:59

I am using Lacinia Pedestal and want to set some cookies. What I tried to set multiple cookies is this interceptor:

(def make-some-cookies-interceptor
  (fn [request]
    {:status 200
     :headers {"Set-Cookie" "a=; b=; c=; path=/;"}}))
This works only for the first cookie a. I also want to create a cookie b and c. What is the correct way to create multiple cookies?

erwinrooijakkers10:10:33

Adding io.pedestal.http.ring-middlewares/cookies interceptor and setting :cookies keys

{:status 200
       :cookies {"a" {:value ""}
                 "b" {:value ""}
                 "c" {:value ""}}
does not work

erwinrooijakkers11:10:04

FYI this works:

{:headers {"Set-Cookie" ["a=; path=/;" "b=; path=/;"]}}
Thanks to @orestis

Joe Lane15:10:13

@contact904 you should join the #pedestal channel to discuss this there.

Eduardo Mata15:10:37

aww man, I thought I posted this in Pedestal

folcon17:10:24

Anyone doing matrix stuff? Is core.matrix still being used? and or maintained…

noisesmith17:10:20

many clojure libs are focused enough and independent of fast-moving external libs so that they can reach a point of stability - a good rule of thumb is to compare the date of the most recent commit and the number (and quality) of unopened issues in the issue tracker

noisesmith17:10:03

and now I see you created an issue for an uninitialized object :D

folcon17:10:06

Right, the reason I’m asking in this case is that it doesn’t currently appear to be compatible with clojure itself… specifically 1.10.0-alpha5 and later

folcon17:10:10

Currently balancing how to report this while still moving forward with my work =)…

folcon17:10:26

@U051SS2EU to be honest I’m not really familiar with uninitialized object, any suggestions on how I’d go about fixing this?

noisesmith17:10:16

the only way you would get that is a bug in the creation of the bytecode itself - either because you are using a combo of bytecode from different clojure versions or a regression in newer clojure versions with the code generated by this project

noisesmith17:10:50

if the library artifact (effectively a zip file) contains .class files, I'd suspect it's about the different clojure versions, and you could build the lib with a newer clj locally, if not it's either a clojure compiler bug or a redesign is required for newer core.matrix versions...

folcon17:10:50

I’ve been using checkouts and running the test cases with different clojure versions. Anything greater than 1.10.0-alpha4 appears to fail… It appears that either a bug or breaking change was introduced there…

folcon17:10:45

not sure what the path forward is… ¯\(ツ)

noisesmith17:10:53

I just confirmed that core.matrix dooesn't come with any class files, only clj and xml and properties files as expected

noisesmith17:10:06

so it's a compiler regression (or some compiler case that core.matrix needs to accommodate if there's a difference...)

noisesmith18:10:21

wait - why are you using that older version of core.matrix?

folcon18:10:31

Which older version?

noisesmith18:10:52

0.62.0 - maybe that's not older

noisesmith18:10:31

my mistake, I was using http://clojars.org as my source of truth for versions

folcon18:10:32

I’m using develop branch

folcon18:10:47

via lein checkouts

noisesmith18:10:20

my problem was looking at mikera/core.matrix instead of net.mikera/core.matrix

folcon18:10:22

yea the version there is really old… not sure why as there’s stuff going on in the develop branch and the published version still has this issue

noisesmith18:10:46

he changed org names (a good change) and you can't delete old things

noisesmith18:10:49

in your checkout, is there any chance you created class files (which would have been created with 1.8, the clojure version in that project.clj)

noisesmith18:10:19

you can purge them with lein clean

folcon18:10:29

I’ve been doing that then running lein test

noisesmith18:10:34

if I edit the project.clj in the develop branch to ask for 1.10.1 it just works

folcon18:10:36

let me just run clean and try and import

noisesmith18:10:41

lein test will create those class files

noisesmith18:10:02

they will be under target/

folcon18:10:01

so basically just change the version in checkouts to 1.10.1 and then, lein clean then try and import?

folcon18:10:37

wait, are you loading into a clojure or clojurescript repl?

noisesmith18:10:55

clojure repl, oh right you are using cljs

folcon18:10:46

yep, as it’s cljc and supposed to be compatible…

folcon18:10:11

as in there’s an issue (81) where they said they’d achieved compatibility…

folcon18:10:24

they just hadn’t optimised…

andy.fingerhut18:10:01

What command are you using to start a cljs repl?

folcon18:10:55

alias:

"fig:dev"   ["trampoline" "run" "-m" "figwheel.main" "-b" "dev" "-r"]

folcon18:10:12

figwheel-main version if it helps =)…

[com.bhauman/figwheel-main "0.2.3"]

andy.fingerhut18:10:11

This may not be helpful, but I tried starting a REPL with clj, and while I get warnings when require'ing the clojure.core.matrix.dataset namespace, I do not get an error.

andy.fingerhut18:10:32

I can share a deps.edn file and command sequence I tried in case you want to see if it gives you similar results, but not sure whether it would help you get your dev environment working.

folcon18:10:16

as in a clojure repl?

andy.fingerhut18:10:48

You can start a cljs repl using a clj command from a terminal.

andy.fingerhut18:10:05

with the proper options. Let me make a gist to link to, in case you want to try it.

folcon18:10:29

For what version of clojure? If I try and run "1.10.1" it fails with the Uninitialized object error

folcon18:10:54

I didn’t know that

andy.fingerhut18:10:13

It is a different way to start a cljs REPL, but I do not know enough about cljs environments to know whether it helps with using figwheel, or cljs in a browser.

andy.fingerhut18:10:52

The commands in that gist will use Clojure/Java 1.10.1 running in a JVM, and also Node.js for executing the compiled JavaScript code.

andy.fingerhut18:10:31

In case that doesn't help get you up and running, others in the #clojurescript channel on Slack might be more knowledgeable about that environment, and why you are getting errors with core.matrix

folcon18:10:45

Give me a sec, reading =)…

folcon18:10:06

Hmm, so this is what I’ve gotten:

testing-this folcon$  vim deps.edn
testing-this folcon$  clj -m cljs.main --repl-env node
ClojureScript 1.10.520
cljs.user=>  (require '[clojure.core.matrix :as m])
Syntax error (VerifyError) compiling new at (wrappers.cljc:218:1).
Uninitialized object exists on backward branch 108
Exception Details:
  Location:
    clojure/core/matrix/impl/wrappers/NDWrapper.get_slice_view(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @152: goto
  Reason:
    Error exists in the bytecode
  Bytecode:
    0000000: 2c01 4db8 010b 422b 014c b801 0b37 05b2
    0000010: 010e b600 99c0 009b 2ab4 0047 b900 d202
    0000020: 003a 072a b400 43c0 0110 1605 882f 0037
    0000030: 0819 07c0 0110 1608 8821 b801 1458 bb00
    0000040: 0259 2ab4 003f 2ab4 0041 c001 10be 360a
    0000050: 150a 850a 6588 360b 2ab4 0041 c001 1015
    0000060: 0bb8 011a 3a0c 1605 8885 370d 160d 150a
    0000070: 850a 6594 9c00 2b19 0cc0 0110 160d 8800
    0000080: 2ab4 0041 c001 1016 0d0a 6188 002f b801
    0000090: 1458 160d 0a61 370d a7ff d400 00bf bf01
    00000a0: 5701 5719 0c01 3a0c 2ab4 0043 c001 10be
    00000b0: 360a 150a 850a 6588 360b 2ab4 0043 c001
    00000c0: 1015 0bb8 011a 3a0c 1605 8885 370d 160d
    00000d0: 150a 850a 6594 9c00 2b19 0cc0 0110 160d
    00000e0: 8800 2ab4 0043 c001 1016 0d0a 6188 002f
    00000f0: b801 1458 160d 0a61 370d a7ff d400 00bf
    0000100: bf01 5701 5719 0c01 3a0c 2ab4 0045 c001
    0000110: 26be 360a 150a 850a 6588 360b 2ab4 0045
    0000120: c001 2615 0bb8 0129 3a0c 1605 8885 370d
    0000130: 160d 150a 850a 6594 9c00 2d19 0cc0 0126
    0000140: 160d 8800 2ab4 0045 c001 2616 0d0a 6188
    0000150: 00b8 012d b801 3057 160d 0a61 370d a7ff
    0000160: d200 00bf bf01 5701 5719 0c01 3a0c 1907
    0000170: 013a 07b7 0136 b0                      
  Stackmap Table:
    full_frame(@108,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#272],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4]})
    full_frame(@155,{},{Object[#316]})
    same_locals_1_stack_item_frame(@158,Object[#316])
    full_frame(@159,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#272],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4]})
    full_frame(@206,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#272],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4],Object[#272]})
    full_frame(@253,{},{Object[#316]})
    same_locals_1_stack_item_frame(@256,Object[#316])
    full_frame(@257,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#272],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4],Object[#272]})
    full_frame(@304,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#294],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4],Object[#272],Object[#272]})
    full_frame(@353,{},{Object[#316]})
    same_locals_1_stack_item_frame(@356,Object[#316])
    full_frame(@357,{Object[#2],Null,Null,Long,Long,Object[#4],Long,Integer,Integer,Object[#294],Long},{Uninitialized[#62],Uninitialized[#62],Object[#4],Object[#272],Object[#272]})

cljs.user=> 

folcon18:10:23

That’s interesting

folcon18:10:05

what jdk are you running?

folcon18:10:14

I doubt this is a ubuntu vs mac thing…

andy.fingerhut18:10:54

I did my experiment on a Mac, AdoptOpenJDK 11, in a directory with no files except that deps.edn file.

folcon18:10:16

ok, it might be my jdk version

andy.fingerhut18:10:22

Another possible source of differences is that our $HOME/.m2 contents could be different.

folcon18:10:40

let me wipe mine…

andy.fingerhut18:10:34

I also so no errors when I tried AdoptOpenJDK 8. What OS and JDK are you using?

folcon19:10:17

mac, 1.8.0 jdk

andy.fingerhut19:10:04

I do not know which part of this software is doing it, but on Ubuntu Linux I see warnings, but no errors, but it also mentions it is writing files into my $HOME/.cljs directory.

andy.fingerhut19:10:29

I have such a directory on my Mac as well. You might want to try deleting that if you have one.

folcon19:10:12

just found it, I’ll move that as well to see if it’s the issue…

andy.fingerhut19:10:13

I saw a $HOME/.cljs/.aot_cache directory that appears to contain many .cljs and .js files, probably created by the cljs compiler.

andy.fingerhut19:10:59

After deleting that and trying my short sequence of commands, I see warnings that seem to be from the ClojureScript compiler. After a successful run with just warnings, if i repeat the sequence, no warnings, probably because it is using already-compiled JavaScript source files in that directory.

folcon19:10:16

ok it just re-downloaded everything after moving /.m2 and /.cljs and no luck… I’ll see if changing java versions works…

andy.fingerhut19:10:36

caches are great, except when you do not know they exist and their contents are bad 🙂

folcon19:10:30

yep, currently brew cask install adoptopenjdk

folcon19:10:18

ok, that seems to finally work.

folcon19:10:34

Now let’s see if I can get it to work in my project =)…

andy.fingerhut19:10:53

As mentioned earlier, #clojurescript might be a more target rich environment for asking about issues with figwheel, but maybe since you were have similar errors between figwheel and clj, hopefully getting them fixed in clj will fix them in figwheel too

folcon19:10:30

I did think that, but I figured since I was getting a clojure error this might be better?

andy.fingerhut19:10:58

no problem asking either place, really. Whatever gets the job done

folcon19:10:23

Are people switching to openjdk and I’ve just not noticed?

andy.fingerhut19:10:19

I think lots of people are switching away from Oracle JDK since they changed their license

andy.fingerhut19:10:22

several choices of what to switch to, but OpenJDK seems to be widely used.

folcon19:10:59

Ok as I’ve been building ions as well and fingers crossed I can use the same jdk :)…

andy.fingerhut19:10:47

For that, I would go with whatever the Datomic support folks recommend.

folcon19:10:35

This is getting silly, now figwheel doesn’t load >_<…

folcon19:10:31

Thanks for all your help @andy.fingerhut =)…

andy.fingerhut19:10:30

I have updated that gist slightly to add a few comments about local caches that are written to when you run the commands.

andy.fingerhut19:10:44

Wait, not cool. Sorry. Weird.

andy.fingerhut19:10:53

Like I said, I haven't used figwheel, and don't know its install steps. If they involve Leiningen auto-downloading JARs into your $HOME/.m2, not sure why that wouldn't happen again, but perhaps there is more involved?

folcon19:10:49

there shouldn’t be

folcon19:10:02

for some reason the websocket is not connecting…

folcon23:10:54

Ok! I think I’ve managed to resurrect it! However I have no idea why I can’t connect to 127.0.0.1 any more, just localhost… Seems like something has changed and I’m not sure what…

andy.fingerhut23:10:43

Glad you got there. I do not know why that change may have occurred -- only guess is whether some kind of local firewall software on your machine was allowing it before, but preventing it now. But there are likely other causes than that.

folcon23:10:05

Yep, not in the mood to dig out that mess, I’ll leave that yak for another day…

folcon23:10:04

Thanks again for your help @andy.fingerhut!

mruzekw21:10:25

Is there any reliable resource on using Clojure to build an Android application? (Not React Native)

noisesmith21:10:32

it can't be done directly, but there's a fork of clojure that works via lein-droid, it's a few versions behind mainline clojure though

noisesmith21:10:07

also if someone uses your app it could take long enough to start that they think it's broken :/

mruzekw21:10:33

I see, okay, thanks. Kotlin is it haha

noisesmith21:10:54

yeah, it's too bad, but I think that is the better of the options right now

👍 4
noisesmith21:10:35

I think rust works on android as well

mruzekw21:10:02

Really now?

mruzekw21:10:05

That would be cool

mruzekw21:10:14

Like for app code as well? Not just a shared lib?

hmaurer21:10:26

Hey! How can I check if something is a clojure.lang.Cons? e.g.

user=> (list? `(1))
true
user=> (list? `(1 2))
false
user=> (type `(1 2))
clojure.lang.Cons

danielgrosse21:10:05

I've asked a question on StackOverflow. Would be great, if you could help me with this. https://stackoverflow.com/questions/58208842/how-to-annotated-a-record-for-jackson-dataype-hal

andy.fingerhut21:10:47

For any Java type, you can use (instance? clojure.lang.Cons x) (replace clojure.lang.Cons with whatever Java type you are interested in).

Alex Miller (Clojure team)22:10:07

(but fyi asking that specific question is weird - generally you should never want to know or care that something is a concrete Cons object)

8
👌 4
noisesmith22:10:48

perhaps what you want is seq? or sequential?

hmaurer10:10:57

Ah, yes, I think that fits my use-case better; thanks 🙂