Log4j2 integration classloading woes

2021-01-18 Thread Dimitrios Piliouras

Hi folks,

I'm trying to integrate log4j2 (and its `MapMessage`) with 
tools.logging. Everything was going great until the moment I had to 
depend on this little library, from another project. Everything would 
work on the REPL, but `lein check` was failing with the most bizarre 
IOException (Stream closed) during compilation! I reported/asked about 
this to `duct-core` initially [1] (as it was a duct-based project), but 
it turns out that this doesn't really relate to duct. James 
(@weavejester) was kind enough to  attempt to explain this, and he 
basically concluded that (quoting straight from the ticket):


1. The Clojure classloader opens a stream to read
   |com.elcom.tools.logging.structured| from the jar.
2. The |clojure.tools.logging| namespace is then required and loaded.
3. Log4j is triggered from |clojure.tools.logging|, which then tries to
   read from the elcom-tools jar again, probably to load in your custom
   logging class or properties file.
4. This second read appears to close the first stream to
   |com.elcom.tools.logging.structured|, causing an IO error from the
   still-open reader.

Note that this only occurs when the classloader is trying to load from a 
jar. The moment the files are cached in the |target| directory, 
everything works fine.


Reproducing this requires that you download the two zips from the link 
below, install `elcom-tools` locally, and then doing `lein check` on 
`elcom-auth`.


I do have a workaround at this point, but at the same time, I'd love to 
understand what exactly is happening here. Many thanks in advance for 
any insights...


Kind regards,
Dimitris


[1]: https://github.com/duct-framework/core/issues/37 



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups "Clojure" group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/9a7c6d95-80f3-cb2a-5f3b-13c05ee97705%40gmail.com.


Integrating `core.async` with `httpcore5-h2`

2020-10-31 Thread Dimitrios Piliouras

Hi folks,

For some reason, the server component of the apache http-components [1] 
library doesn't get any love from the Clojure community. This is 
particularly strange to me, given the early/broad adoption of the client 
component (i.e. clj-http). In any case, I took version 5 for a spin, and 
in particular the async-server aspect of it, as I wanted to see whether 
it would integrate cleanly/nicely with core.async channels.


The ring model of async handlers taking 3 arguments, albeit necessary, 
is hard to work with.  Not only does it feel kind of magic - it is 
actually non-trivial to (correctly) propagate the `respond` and `raise` 
callbacks across the middleware stack (which can lead to bugs). The way 
I see it, it would be much nicer if the response's body was enough to 
distinguish whether this is a sync or async response. In other words, 
returning a core.async channel as the body should suffice to treat this 
as an async response.


I spent a few hours today, and came up with this server wrapper [2]. If 
you need convincing that this works, evaluate the two expressions at the 
bottom of the file (inside a `comment` expression), and cURL into it 
from your terminal (per the comments). The actual construct which 
enables a channel to act as body can be seen here 
(`ChannelContentProducer`) [3].


The convention (for handlers) is simple. Use `promise-chan` for single 
response, but regular `chan` for streaming responses. That is it! No 
respond/raise indirection - just putting into the channel (and closing 
it when streaming). Other than that, honors the ring-spec (wrt requests).


So there you have it - async from the ground-up, HTTP2 supporting, 
ring-friendly web-server prototype (in less than 250 lines).


Kind regards,

Dimitrios


[1]: https://hc.apache.org/httpcomponents-core-5.0.x/index.html

[2]: 
https://github.com/jimpil/asynctopia/blob/master/src/asynctopia/server/embedded.clj


[3]: 
https://github.com/jimpil/asynctopia/blob/master/src/asynctopia/server/channel_body.clj


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups "Clojure" group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/0dfa9260-9d8b-fbeb-d9ca-f29e01b1a04a%40gmail.com.