admin-announcements

Announcements from the Clojurians Admin Team (@U11BV7MTK @U077BEWNQ @U050TNB9F @U0ETXRFEW @U04V70XH6 @U8MJBRSR5 and others)
markmandel 2015-12-14T00:23:40.001491Z

and (refresh-all) doesn't see it either. okay, I am super confused.

markmandel 2015-12-14T00:55:34.001492Z

It looks like if I have #?(:clj (:require [clojure.math.numeric-tower :as m])) as the only required thing in the ns, it gets skipped. It's very odd. If I just use (:require [clojure.math.numeric-tower :as m]) without the reader conditional, it works as expected.

nberger 2015-12-14T02:59:18.001494Z

@markmandel it seems you are using tools.namespace 0.2.10 but full reader conditionals support landed in tools.namespace 0.2.11

markmandel 2015-12-14T03:04:21.001495Z

I'll give that a shot @nberger - although it doesn't explain codox failing

markmandel 2015-12-14T03:04:47.001496Z

But maybe? šŸ˜•

nberger 2015-12-14T03:43:18.001497Z

Codox uses tools.namespace, so yeah, a bit more than maybe :)

boycott 2015-12-14T10:32:33.001500Z

hi, I am a javascript developer and the way I build apps is to separate static files to serve straight through nginx, and proxy dynamic pages and json through to an application. I of course know nodejs best, but professionally work in a large financial institution so have learned to know a little scala (but donā€™t like it), clojure and a tiny bit of haskell. What I want to do is replicate my node app as close as possible in clojure (which I have started using immutant), but to test want to maximise performance to give it as fair a shot as possible, should I stick with jetty or run wildfly, is there a tool to optimise min and max memory for java etc?

robert-stuttaford 2015-12-14T10:34:10.001501Z

i recommend you skip immutant and go straight to http-kit

jaen 2015-12-14T10:34:15.001502Z

Running immutant in Wildfly will be probably somewhat slower than using immutant-web directly in an uberjar-based application, since it has to conform to servlet specification.

robert-stuttaford 2015-12-14T10:34:17.001503Z

http://www.http-kit.org/

jaen 2015-12-14T10:34:25.001505Z

@robert-stuttaford: why?

jaen 2015-12-14T10:34:38.001506Z

http-kit is less maintained nowadays

robert-stuttaford 2015-12-14T10:34:43.001507Z

ah, i didnā€™t know that

jaen 2015-12-14T10:34:45.001508Z

Not more performant

robert-stuttaford 2015-12-14T10:34:57.001509Z

ok. i defer to jaenā€™s knowledge :simple_smile:

jaen 2015-12-14T10:34:58.001510Z

And only thing it supports that immutant doesn't

jaen 2015-12-14T10:35:03.001511Z

Is a http client

jaen 2015-12-14T10:35:05.001512Z

That said

artemyarulin 2015-12-14T10:35:17.001513Z

https://github.com/ptaoussanis/clojure-web-server-benchmarks here the couple of benchmark results. I think aleph is a good choice

jaen 2015-12-14T10:35:27.001515Z

I might be unaware of some of downsides of immutant compared to http-kit

jaen 2015-12-14T10:35:41.001516Z

You beat me to that link, heh

jaen 2015-12-14T10:35:53.001517Z

Yeah, I agree aleph seems like a good choice as well.

jaen 2015-12-14T10:36:06.001518Z

Quite curious how aleph based on undertow instead of netty would compare.

artemyarulin 2015-12-14T10:36:54.001521Z

I guess itā€™s possible to go with bare netty (which I guess 2 times faster than aleph) and use CLJ logic from it somehow

artemyarulin 2015-12-14T10:39:18.001523Z

https://www.techempower.com/benchmarks/#section=data-r11&hw=peak&test=plaintext oh, according to this aleph is 4 times slower comparing to bare netty

2015-12-14T10:39:50.001525Z

Is anyone aware of a Clojure webserver that allow persistent Websocket/SSE/HTTP/HTTP2 connection across code reloads ?

2015-12-14T10:40:16.001526Z

(A la Erlang/Elixir)

boycott 2015-12-14T10:40:28.001527Z

That techempower test site is great!

2015-12-14T10:42:54.001529Z

I played with Compojure/Pedestal/Aleph and now Yada. I am not completely happy with any of those so far by the way.

artemyarulin 2015-12-14T10:44:38.001530Z

Does anybody used Rapidoid? According to techempower itā€™s like 50% faster than netty which is really impressive

2015-12-14T10:45:38.001531Z

@artemyarulin: I never heard of it before. Looks impressive !

artemyarulin 2015-12-14T10:46:22.001532Z

@nha: Indeed, Iā€™m looking for any docs which describes how they were able to achieve that

2015-12-14T10:47:31.001533Z

I am looking for that too right now :simple_smile: Although I am not sure how representative the techEmpower becnhmarks are (they just make small plain text requests, right ?).

robert-stuttaford 2015-12-14T10:48:39.001534Z

itā€™s all about tradeoffs, though, right? surely the faster ones are sacrificing some capability for speed

robert-stuttaford 2015-12-14T10:49:33.001535Z

are the sacrifices worth the speed?

2015-12-14T10:50:42.001536Z

My thoughts exactly :simple_smile: I was expecting Compojure to fare worse than that also, as I though it had a thread per request ?

artemyarulin 2015-12-14T10:50:46.001537Z

thatā€™s exactly why I ask - there should be some tradeoff but I couldnā€™t find it

robert-stuttaford 2015-12-14T10:51:30.001538Z

thatā€™s the issue, the benchmarks are concerned only with speed. itā€™s great that we have them to compare, but itā€™s not the whole picture

2015-12-14T10:51:52.001539Z

Right. I would give a lot of performance away for convenience and predictability.

robert-stuttaford 2015-12-14T10:51:52.001540Z

unless, of course, youā€™re in a game where sheer reqs/sec is a top concern for you

2015-12-14T10:53:26.001542Z

The one thing I have been looking for since a long time in a webserver is the ability to reboot without loosing websocket/etc. connections, I have found none so far in JavaLand.

artemyarulin 2015-12-14T10:55:29.001543Z

I guess (not sure) it could be resolved with load balanced in the front - so it will maintain all the connections and serve from the different back, while your back instance it rebooting

robert-stuttaford 2015-12-14T10:56:07.001544Z

thatā€™s a tough one. the ā€˜reloadedā€™ workflow that we like in Clojure is set up to tear everything down and re-instantiate everything, but thatā€™s for dev where it doesnā€™t matter. i think youā€™d need something special to prevent long-lived conn drops for production deploys

robert-stuttaford 2015-12-14T10:56:23.001545Z

yes, as artemyarulin just said. a facade

robert-stuttaford 2015-12-14T10:59:15.001546Z

the Erlang world has this sort of thing totally nailed

robert-stuttaford 2015-12-14T10:59:25.001547Z

pretty much because they started there :simple_smile:

2015-12-14T10:59:36.001548Z

Yes, Erlang/Elixir/Phoenix look attractive because of that.

2015-12-14T11:00:38.001549Z

In fact I just wrote something on that : https://gist.github.com/nha/618fd914f60ccac94657

robert-stuttaford 2015-12-14T11:00:51.001550Z

we serve a websocket app and reboots cull connections. websockets have retry built in, and we have an event-sourced model on the client with a bi-directional, fault-tolerant sync to the servers, so we donā€™t care if the servers go down or reconnect

2015-12-14T11:01:16.001551Z

So cooperation from the client.

robert-stuttaford 2015-12-14T11:01:21.001552Z

yup

2015-12-14T11:01:50.001553Z

Seems like the easiest thing is either to move the concern to the architecture then. But I'm not completely happy with that.

robert-stuttaford 2015-12-14T11:03:15.001554Z

all depends on the problem youā€™re trying to solve, i guess

2015-12-14T11:05:13.001555Z

Well I've been working on webrtc, chat stuff professionally, those things were missing a lot (was in Node.js/socket io at the time). I'd like to build a pubsub thing in Clojure now, but the availability part is not solved.

robert-stuttaford 2015-12-14T11:06:20.001556Z

solving that is a conceptual problem, though. no amount of hijinx with code is going to prevent the fact that your processes are being restarted

robert-stuttaford 2015-12-14T11:06:31.001557Z

youā€™ll need a delegation layer

robert-stuttaford 2015-12-14T11:07:49.001558Z

websockets do have retry built-in, so assuming you can do whatā€™s necessary to resume the websocket session on the server when the reconn comes through, you should be ok

robert-stuttaford 2015-12-14T11:08:11.001559Z

what does the Erlang world do for down servers on the client? surely they also have a cache and sync system?

robert-stuttaford 2015-12-14T11:09:17.001560Z

i am somewhat ignorant on this topicā€¦ iā€™m talking because i want to learn :simple_smile:

2015-12-14T11:09:23.001561Z

Not sure what they do, yes they probably have to do it anyway. But I feel it should go into that situation as little as possible.

2015-12-14T11:10:46.001562Z

Well I was planning to do something a la kafka, the client can request it's messages when reconnecting. Although necessary (network problems, server down), it feeld like it should be the last resort.

robert-stuttaford 2015-12-14T11:11:36.001563Z

thing is, network is a patchy concept overall these days. mobile network switching or airplane mode, rebooting servers, AWS ELB / DNS issues, they all interrupt that connection. building your system to assume the connection will be sound will give you ulcers. therefore, if you build assuming regular disconnects, you can safely cause regular disconnects, too

robert-stuttaford 2015-12-14T11:12:19.001564Z

losing user data sucks, which is why we invested on the client app to cache and sync transparently, retrying until server reports OK for everything

2015-12-14T11:14:10.001565Z

Good point. I plan to open this as a service too though, so even if I control the client I would like to avoid this. I am having a look at nginx-clojure, but it lacks a bit of docs, maybe something more heavy can do the trick too, but I would really like to have something that I can fiddle with on a single node.

2015-12-14T11:14:28.001566Z

I mean, that seems doable. Not exactly easy but doable.

robert-stuttaford 2015-12-14T11:17:09.001567Z

well, good luck :simple_smile:

šŸ‘ 1
razum2um 2015-12-14T12:02:53.001569Z

could you tell, whatā€™s the bot here (and where is the repo) which keeps track of history in this community?

roelof 2015-12-14T15:05:24.001574Z

Does anyone has examples how I can make template inheritance work with hiccup on a reagent project ?

jetmind 2015-12-14T15:10:02.001575Z

@roelof: Just compose functions! https://github.com/brain-fn/essence/blob/master/src/essence/handlers.clj#L23-L74 It's not reagent, but hiccup. wrap-page in this case is similar to a base template, which takes additional content as markup parameter and wraps it in all the stuff it needs (header, etc)

roelof 2015-12-14T15:12:12.001577Z

oke, but if you have some 20 pages , are the handlers then not get very large

roelof 2015-12-14T15:13:34.001578Z

and how do I put these together ?

jetmind 2015-12-14T15:15:22.001579Z

depends on the pages you have really. It's not really larger than html based template

jetmind 2015-12-14T15:16:42.001580Z

just extract as much as you can into the helper functions for header, footer, menu, whatever else you would have and make a wrapper to serve as a base template (or couple of them if you need)

roelof 2015-12-14T15:16:44.001581Z

I try to make this work with hiccup : https://laboutique.lemonstand.com/ and I think it will take some 10 - 15 pages

roelof 2015-12-14T15:17:05.001582Z

@jetmind

robert-stuttaford 2015-12-14T15:17:18.001583Z

hiccup can collapse lists

robert-stuttaford 2015-12-14T15:17:43.001584Z

[:div (for [a [1 2 3]] [:p a])]

roelof 2015-12-14T15:17:58.001585Z

@jetmind any example of that sort of wrapper ? Sorry to ask so many questions. Im a beginner in clojure and in web development with clojure

robert-stuttaford 2015-12-14T15:19:07.001586Z

(defn page-wrap [& content] (hiccup/html5 [:body content])) (defn page1 [] (page-wrap [:div [:h1 ā€œpage 1ā€]]) (defn page2 [] (page-wrap [:div [:h1 ā€œpage 2ā€]])

robert-stuttaford 2015-12-14T15:19:50.001587Z

like that, basically. the trick is to use the & operator to soak up everything passed to page-wrap and let hiccup deal with it as a list

robert-stuttaford 2015-12-14T15:21:23.001588Z

this is just one way to do it. once you get that itā€™s just Clojure data, all the possibilities open up to you :simple_smile:

jetmind 2015-12-14T15:21:58.001589Z

@roelof: see wrap-page function in link I posted above, also look at what @robert-stuttaford told (it's the same principle really)

roelof 2015-12-14T15:22:01.001590Z

@robert-stuttaford: that would be a very big function if I do it like this with a lot of code in the bod. Or I misunderstood what you mean

robert-stuttaford 2015-12-14T15:23:13.001591Z

try it out, roelof

robert-stuttaford 2015-12-14T15:23:22.001592Z

get a feel for it and see

šŸ‘ 1
roelof 2015-12-14T15:26:46.001593Z

I see it. In my project only the body have to change so I could make a wrap page where a different body is being called.

jetmind 2015-12-14T15:27:12.001594Z

exactly

robert-stuttaford 2015-12-14T15:27:30.001595Z

bazinga

roelof 2015-12-14T15:27:47.001596Z

sorry that I did not see it first. I think I need to take more time to look more carefully at the code

roelof 2015-12-14T15:28:35.001597Z

I will experiment with it and hopefully get it working

robert-stuttaford 2015-12-14T15:29:29.001598Z

100% :simple_smile: best way to get familiar with it

robert-stuttaford 2015-12-14T15:29:41.001599Z

if you start writing macros, youā€™ll know youā€™ve gone too far šŸ˜„

roelof 2015-12-14T15:31:06.001601Z

@jetmind : is sente easier to learn then react ? I like to make a ecommerce site where I would like that the shopping cart is updated without a browser refresh

jaen 2015-12-14T15:31:28.001602Z

Those have entirely nothing in common.

roelof 2015-12-14T15:31:54.001604Z

@robert-stuttaford: I have not learned to write very easy macros so that would not be a problem

jaen 2015-12-14T15:32:01.001605Z

Sente is a library for writing websockets, more or less.

jaen 2015-12-14T15:32:12.001606Z

React is a library for dynamic client-side components.

roelof 2015-12-14T15:32:35.001607Z

@jaen: I know but as far as I know both can be used to make real-time web applications

robert-stuttaford 2015-12-14T15:32:44.001608Z

you could use sente and react (via reagent or one of the other wrappers) very nicely together

jaen 2015-12-14T15:32:49.001609Z

But it solves a different problem.

jaen 2015-12-14T15:33:01.001610Z

Sente can talk to your server, but can't display anything

jaen 2015-12-14T15:33:10.001611Z

React can display whatever you want, but can't talk to your server

jaen 2015-12-14T15:33:34.001612Z

It's a bit like asking if you can use CSS to solve a differential equation, those are totally different things.

roelof 2015-12-14T15:33:48.001613Z

oke, so you need both to make a realtime app

jaen 2015-12-14T15:33:51.001614Z

Yes

jaen 2015-12-14T15:33:54.001615Z

Or neither.

jaen 2015-12-14T15:33:56.001616Z

For example

jaen 2015-12-14T15:34:22.001617Z

Instead of using sente you can use cljs-ajax or cljs-http and just do AJAX calls

jaen 2015-12-14T15:34:29.001618Z

That would be enough for a refreshable cart.

jaen 2015-12-14T15:34:40.001619Z

No need to go into websockets unless you need two-way communication

jaen 2015-12-14T15:34:50.001620Z

Say, you were writing a chat - yeah, sente is great.

jaen 2015-12-14T15:34:54.001621Z

In your case that's an overkill.

roelof 2015-12-14T15:35:17.001622Z

oke, I think I have a project which is more then I can chew. Many parts that I still have to learn

jaen 2015-12-14T15:35:33.001623Z

The same with reagent - you could use a library wrapping jQuery or goog.dom like jayq or domina and don't have to touch React.

jaen 2015-12-14T15:35:54.001624Z

Or choose Holpon or freactive or zelkova or any other library that does not depend on React.

jaen 2015-12-14T15:36:15.001625Z

It's just that React is the most popular in Clojurescript (and quite so in the wider Javascript world) and for a good reason.

jaen 2015-12-14T15:36:38.001626Z

And things like jQuery or goog.dom are just antiquated and don't scale well to more complex applications.

jaen 2015-12-14T15:36:43.001627Z

What I suggest you do

jaen 2015-12-14T15:36:54.001629Z

Is first write your project as a multi-page application.

jaen 2015-12-14T15:36:56.001630Z

Zero javascript

jaen 2015-12-14T15:37:06.001631Z

Just posting forms and redirecting to new URLs and so on.

jaen 2015-12-14T15:37:10.001632Z

That'll be pretty easy

roelof 2015-12-14T15:37:12.001633Z

oke, just plain hiccup

jaen 2015-12-14T15:37:20.001634Z

Like you would do with Rails or Sinatra or something else.

jaen 2015-12-14T15:37:24.001635Z

When you have that working

jaen 2015-12-14T15:37:41.001636Z

You can try using reagent + cljs-ajax to make parts of website interactive, like the cart.

jaen 2015-12-14T15:37:52.001637Z

There's nothing stopping you from using reagent on only the part of website

jaen 2015-12-14T15:38:05.001638Z

You don't have to go full SPA - you can just have one div reactified.

jaen 2015-12-14T15:38:25.001640Z

Step-by-step is the most sensible solution I think.

roelof 2015-12-14T15:38:34.001641Z

oke, then the next few days/ 2 weeks making my site work with all the pages I want.

roelof 2015-12-14T15:39:27.001642Z

Making the login work / displaying articles / working with a database (first it can be a map in memory)

jaen 2015-12-14T15:39:42.001643Z

Yeah, that sounds like a sensible approach

jaen 2015-12-14T15:39:46.001644Z

Don't overextend yourself.

roelof 2015-12-14T15:40:07.001645Z

that is a problem I have encountered earlier with 4clojure

roelof 2015-12-14T15:40:25.001646Z

Trying to make a solution in one step instead of small steps

jaen 2015-12-14T15:40:56.001647Z

Yep, bulding up bigger things from smaller is a thing functional programming is good at

jaen 2015-12-14T15:41:01.001648Z

So you should try to leverage that.

roelof 2015-12-14T15:41:19.001649Z

I try but old habits die not so fast

roelof 2015-12-14T15:42:05.001650Z

@jaen: I could start with a compojure or luminus template ?

jaen 2015-12-14T15:42:38.001651Z

I never used templates to be honest, I like to setup the project just how I want it, with libraries I like

jaen 2015-12-14T15:42:40.001652Z

But in your case

jaen 2015-12-14T15:42:48.001653Z

Yeah, Luminus sounds like a good choice to me.

jaen 2015-12-14T15:43:02.001654Z

Think somewhere between Sinatra and Padrino in Ruby world.

jaen 2015-12-14T15:43:17.001655Z

You get some structure, some libraries and off you go.

sventechie 2015-12-14T15:44:01.001656Z

@roelof Iā€™ve worked from Luminus and also from the Immutant demo project and was happy. Luminus is very flexible and well documented.

roelof 2015-12-14T15:44:35.001657Z

oke, first step : do some beginners tutorials in luminus

sventechie 2015-12-14T15:46:28.001658Z

Yes, further down the road you may want to consider @danielsz system based on @stuartsierra component architecture. That also has ready-made support for immutant and a very clean configuration system.

jaen 2015-12-14T15:47:14.001659Z

I think that's far too early. It's just gonna confuse him.

jaen 2015-12-14T15:47:30.001660Z

It's better he gets comfortable with Luminus as-is.

roberto 2015-12-14T15:47:51.001661Z

yeah, just start with Luminus, donā€™t pay attention to component or system for now.

roberto 2015-12-14T15:48:01.001662Z

they are a little hard to understand for a beginner

jaen 2015-12-14T15:48:10.001663Z

Grokking how to do components wasn't all that straightforward for me, never having done any non-trivial system with dependency injection.

roberto 2015-12-14T15:48:33.001664Z

I had to dedicate an entire day to just component before I understood it.

roberto 2015-12-14T15:49:26.001665Z

it can be a set back for beginners, they should just focus on the basic tools to start with, and component is not a basic tool.

sventechie 2015-12-14T15:50:27.001666Z

True. Luminus has started moving that way as well, though, so it might come up.

roelof 2015-12-14T15:50:49.001667Z

correct, I did a quick look and saw it nothing for me yet

jaen 2015-12-14T15:51:29.001668Z

@sventechie: You sure? Yogthos doesn't seem to like component.

roelof 2015-12-14T15:52:15.001669Z

but why not use the compojure template . I could then learn to add my own authentication as friend instead of boddy

roelof 2015-12-14T15:52:19.001670Z

buddy

jaen 2015-12-14T15:52:40.001671Z

Well, to me buddy is considerably simpler.

jaen 2015-12-14T15:52:55.001672Z

I couldn't make head or tails out of friend, so I'm not sure if it's a good choice for a beginner.

jaen 2015-12-14T15:53:13.001673Z

Don't jump from library to library as much. Take something simple and stick with it.

roelof 2015-12-14T15:53:16.001674Z

As far as I can see luminus is using friend

roelof 2015-12-14T15:55:06.001675Z

no, im wrong it using bouncer

jaen 2015-12-14T15:55:27.001676Z

Bouncer is for form validation, nothing to do with authentication.

jaen 2015-12-14T15:55:42.001677Z

And Luminus doesn't really force you to use anything, you can swap things as you wish.

roelof 2015-12-14T15:55:48.001678Z

I take a break

jaen 2015-12-14T15:56:10.001680Z

But for authentication I think buddy is it's first suggestion - http://www.luminusweb.net/docs/security.md#password_hashing

sventechie 2015-12-14T15:56:16.001681Z

@jaen Re: component, not sure yogthos doesnā€™t seem to hate it: http://yogthos.net/posts/2015-10-01-Compojure-API.html

jaen 2015-12-14T15:56:16.001682Z

And I'm behind that - it's simple.

roelof 2015-12-14T15:58:04.001683Z

@jaen: you right. I take a break.

roelof 2015-12-14T15:58:20.001684Z

too long behind the screen I think

jaen 2015-12-14T16:03:24.001688Z

He seems to prefer mount as component seems too OO and complex, and I can get behind that actually.

jaen 2015-12-14T16:04:29.001689Z

I myself am eyeing https://github.com/jarohen/bounce right now, mount didn't somehow convince me - I tried it and it started components in the reverse order than I expected for reasons that weren't obvious for me.

jaen 2015-12-14T16:04:51.001692Z

Component, while more complex, at least is not surprising in behaviour.

jaen 2015-12-14T16:05:39.001693Z

Yoyo by the author of bounce was interesting, but handling monads in Clojure tends to be awkward, so I'm curious what he is planning to do with bounce to alleviate that.

sventechie 2015-12-14T16:08:05.001694Z

@jaen Hmm, he has some good points. @danielsz systemisa bit more high-level and is being integrated with `mount` as well~.

jaen 2015-12-14T16:08:44.001695Z

But if I understand correctly system is just a collection of components, isn't it?

jaen 2015-12-14T16:09:45.001696Z

I tend to prefer write the component myself, feel like I have more control then. But system's boot task for reload is pretty cool, though I had to hack it to add regex-based exclusion.

danielsz 2015-12-14T16:12:02.001701Z

Nice, @jaen ! If you think it can be useful to others, please feel free to push a PR.

jaen 2015-12-14T16:14:20.001705Z

@danielsz: but that's only boot-specific, I wouldn't know how to do it for lein.

danielsz 2015-12-14T16:15:59.001706Z

No need.

jaen 2015-12-14T16:16:45.001707Z

Okay, I guess I can push a PR for that in a moment.

danielsz 2015-12-14T16:17:26.001708Z

dziękuję

jaen 2015-12-14T16:17:34.001709Z

Nie ma za co ; d

jarohen 2015-12-14T16:27:33.001710Z

hi @jaen - yes, monads in Clojure did turn out to be pretty awkward

jarohen 2015-12-14T16:28:34.001711Z

I'm working on a readme for bounce at the moment, (on the readme branch on GH), but most of the docstrings are in place, and some tests too

jaen 2015-12-14T16:28:59.001712Z

Well, that depends, I implemented event sourcing event application as fold over maybes and it was pretty cool and not all that verbose, but when I tried to grok yoyo I was a bit at loss.

jaen 2015-12-14T16:29:12.001713Z

Component is cool and all, but it's OO-centric approach feels a bit weird.

jaen 2015-12-14T16:29:58.001714Z

I liked that you could just ask the dependency out of the monad without having to pass things around or write methods on records (at least that's how I understood it, maybe I'm wrong here)

jarohen 2015-12-14T16:30:40.001715Z

mm, agreed - it's a great idea to set out your application state in the Component way, but it was that OO-ish approach that caused me to start looking around for alternative solutions - mostly just variations on a Component theme, though

jarohen 2015-12-14T16:30:52.001716Z

yep, that's right

jarohen 2015-12-14T16:31:16.001717Z

although it's viral - every time your callee needs to return a monadic value, you yourself need to as well

jarohen 2015-12-14T16:31:22.001718Z

which didn't work out so well in practice

jaen 2015-12-14T16:33:16.001719Z

Yeah, I can imagine how it's cleaner in Haskell for example, but I'm no walking typeclassopedia at the moment so I'm taking a stop at Clojure. Monads are cool and all, but if you can be sideeffectful like in Clojure that can be an unneeded burden, I guess.

jaen 2015-12-14T16:33:53.001720Z

If bounce has something like that, that is being able to set up a system, and ask for dependencies without passing arguments around it could be pretty cool.

jaen 2015-12-14T16:34:25.001721Z

Does it resolve dependencies a la component, or will it need explicit ordering like with leaven?

jarohen 2015-12-14T16:35:18.001722Z

so bounce is completely monad-less - which should get around a lot of the problems of yoyo

jarohen 2015-12-14T16:35:43.001723Z

but yes, resolves dependencies like component - you give it a map of dependencies and it resolves them

jarohen 2015-12-14T16:35:59.001725Z

(it uses Stuart Sierra's 'dependency' library under the hood, same as Component)

jarohen 2015-12-14T16:36:40.001726Z

difference is that I'm looking into ways that you don't have to: - pass the whole system around everywhere - but keep the referential transparency related test benefits

jarohen 2015-12-14T16:37:01.001727Z

very much in progress at the moment though, so completely subject to change! :simple_smile:

jaen 2015-12-14T16:37:06.001728Z

That sounds nice.

2015-12-14T16:37:07.001729Z

Is there an easy ā€œtransform a hash-map by mapping over the valuesā€? Right now Iā€™m doing (apply hash-map (mapcat #(list (first %) (dothing (second %))) my-hash-map)) which isnā€™t super elegant

jaen 2015-12-14T16:37:35.001730Z

@jarohen: Any thoughts about co-dependencies?

jarohen 2015-12-14T16:37:46.001731Z

@jaredly: I tend to use map-vals from @weavejester's 'medley'

bronsa 2015-12-14T16:37:48.001732Z

@jaredly: there are a number of util libraries that implement that, usually called update-vals or map-vals

jarohen 2015-12-14T16:38:04.001734Z

https://github.com/weavejester/medley

2015-12-14T16:38:06.001736Z

cool

jaen 2015-12-14T16:38:50.001737Z

I usually use clojure.walk, didn't know about those libs.

jarohen 2015-12-14T16:39:06.001738Z

@jaen: trying to avoid them where possible! cyclic dependencies can usually be refactored away

jaen 2015-12-14T16:41:25.001739Z

@jarohen: that is a fair point, but what happens if you can't?

yogthos 2015-12-14T16:41:26.001740Z

@jaen: wrt mount, the starting and stopping of states is based on the namespace hiearchy

yogthos 2015-12-14T16:41:46.001741Z

so the components should be started in order theyā€™re required in

yogthos 2015-12-14T16:42:10.001742Z

and as a side effect if a namespace is not used anywhere then its state will not be part of the lifecycle

yogthos 2015-12-14T16:42:41.001743Z

the latest version also works with cljs now, so you can mange stuff like websocket connections with it

jaen 2015-12-14T16:43:13.001744Z

So if I understand correctly I have to manually make sure it is required like so?

[component.depdency]
[component.dependent]

jaen 2015-12-14T16:43:40.001745Z

I tried to make a component that depended on another component and couldn't seem to have them start in the right order for some reason '

yogthos 2015-12-14T16:44:43.001746Z

well letā€™s say you have two states a queue and a database, and the queue state has to be started before the database state

jarohen 2015-12-14T16:44:48.001747Z

@jaen: that's a fair point too :simple_smile: tbh, I've never come across a situation where you couldn't, so it hasn't been enough of an issue - example and/or PR gratefully received though :simple_smile:

yogthos 2015-12-14T16:45:37.001748Z

so you might have namespaces like app.queue that has its defstate for the queue and app.db with a defstate for the db connection

yogthos 2015-12-14T16:46:04.001749Z

if app.db requires app.queue, then the queue state will be started before the db one

yogthos 2015-12-14T16:46:37.001750Z

Iā€™ve switched a few apps Iā€™m using to mount and I found I generally donā€™t have to think about this explicitly

yogthos 2015-12-14T16:47:37.001751Z

the start/stop order will be dictated by the namespace hierarchy, and since namespaces that rely on a particular state will have to require namespaces that manage it then it forces the states to be started in that order

jaen 2015-12-14T16:48:57.001752Z

Yeah, I figured so, that's why them starting in reverse surprised me, maybe I've just misunderstood something.

jaen 2015-12-14T16:49:27.001753Z

Anyway, not having to lug around the system and/or write OO-ish records mount and bounce give seems like a nice thing.

yogthos 2015-12-14T16:51:41.001754Z

yeah I think the big difference with mount is that it leverages namespace declarations, while other systems introduce an additional layer like classes

jaen 2015-12-14T16:52:36.001755Z

I actually like explicit system map for some reason, but I can see the appeal of that. Not having to do records is the biggest win I think.

yogthos 2015-12-14T16:53:38.001756Z

note that mount can generate the resulting system

yogthos 2015-12-14T16:54:13.001757Z

for me the biggest win is that I can have completely self contained component namespaces

sveri 2015-12-14T16:54:14.001758Z

Actually I think I will replace component by mount too in closp when I have time to do so. I think it has a better readability than component in a clojure namespace.

yogthos 2015-12-14T16:54:52.001759Z

my main issue with having a global system is that it has to be passed all over the app

jaen 2015-12-14T16:55:28.001760Z

@yogthos: well, component namespaces are also self contained to be pedantic, if you use record you can close over it's fields and you don't have to worry about the implementation detail of having to carry the system about.

jaen 2015-12-14T16:55:36.001761Z

But then you have weird OO-ish record code.

jaen 2015-12-14T16:55:40.001762Z

Which is meh to read.

yogthos 2015-12-14T16:55:48.001763Z

but the context has to be passed in from the top

jaen 2015-12-14T16:56:15.001764Z

Yeah, but you don't have to do that, component does that for you.

jaen 2015-12-14T16:56:24.001765Z

If I understand it correctly.

yogthos 2015-12-14T16:56:56.001766Z

you generally would pass the config from the top level the way duct does for example

jaen 2015-12-14T16:57:38.001767Z

The problem is you either have to have methods in a record to close over the fields as to not have to get things from the system, or you have methods outside the record at the cost of having to get the system components you need from the param.

jaen 2015-12-14T16:57:55.001768Z

And either is awkward to be honest.

yogthos 2015-12-14T16:58:00.001769Z

I agree :simple_smile:

roelof 2015-12-14T16:59:02.001770Z

one luminus question : what does this do <a href="{{servlet-context}}/about">About</a> expecially the servlet part

yogthos 2015-12-14T16:59:27.001771Z

itā€™s for running on app servers like tomcat

yogthos 2015-12-14T16:59:39.001772Z

if youā€™re running standalone then the context will always be empty

yogthos 2015-12-14T16:59:58.001773Z

but if you deploy to an app server then each app has to have a unique context for routing

roelof 2015-12-14T17:00:35.001774Z

oke, so I can better make all my links that way when using the luminus template ?

yogthos 2015-12-14T17:01:32.001775Z

only if you plan on running on an app server

yogthos 2015-12-14T17:02:24.001776Z

if youā€™re just going to make an uberjar then you can just omit that

yogthos 2015-12-14T17:02:53.001777Z

another case could be if you front multiple apps with apache/nginx and you donā€™t want to setup subdomains

roelof 2015-12-14T17:03:04.001778Z

maybe one time. It's not a hobby-project in my mind but maybe later on I could decide to deploy it

roelof 2015-12-14T17:05:07.001779Z

now time for dinner

roelof 2015-12-14T17:05:19.001780Z

Thanks everyone for the time and patience

2015-12-14T19:41:41.001783Z

@nha, @robert-stuttaford: Erlang's persistence of connections over code reloads doesn't involve a process or server going down. A client reaching a unresponsive system is the same in Erlang as it is in Clojure :simple_smile:

robert-stuttaford 2015-12-14T19:43:03.001784Z

-grin- i suspected as much

2015-12-14T19:43:30.001785Z

It's closer to redefining a Var in a running system

robert-stuttaford 2015-12-14T19:43:53.001786Z

which we can definitely do in Clojure

2015-12-14T19:45:53.001787Z

exactly. Both Clojure and Erlang make no guarantees about how the state may or may not play well with that new code. Erlang just has the convenience layer in it's runtime VM to say "Given a collection of new namespaces, update all the root vars accordingly."

robert-stuttaford 2015-12-14T19:46:22.001788Z

yeah. we have to use the reloaded pattern to accomplish that, which is totally ok

2015-12-14T19:49:08.001789Z

ah, yeah, I see that. That's pretty cool :simple_smile:

2015-12-14T19:49:16.001790Z

@mlbatema: Thanks for the info ! So it means that it is totally ok for requests which are stateless, but what about websockets and such ? As I understand it you have to keep some state on the server. Does that mean that even Erlang can't do it ?

2015-12-14T19:51:25.001791Z

An Erlang hot-code reload can be stateful. You just need be aware of, and implement, potential code-upgrade paths to make your new code work with your old state when incompatible. However, the whole system stays alive during this reload, so there is no downtime.

2015-12-14T19:52:19.001792Z

for details, you can read: http://learnyousomeerlang.com/designing-a-concurrent-application#hot-code-loving

2015-12-14T19:52:46.001794Z

I see, like serializing/deserializing requests? And does the typical Erlang webserver helps with that ?

2015-12-14T19:52:51.001795Z

Ok reading your link :simple_smile:

2015-12-14T19:55:26.001796Z

but Sierra's reloaded pattern looks like it can do enough of that. Just put your runtime state into your defined "system" and figure how you'll want to persist that with the start/stop (serialization, dirty global state, whatever)

2015-12-14T19:55:54.001797Z

@nha: Webserver has nothing to do with it. All VM-level support.

2015-12-14T19:58:08.001798Z

Honestly, hot-code reloads can be complex and can fail. It's a feature you use because it's cheaper to write and test an upgrade path of a live application (or trust a framework to manage as much of it as it can for you) than to accept the downtime necessary to turn off v1 and power on v2.

robert-stuttaford 2015-12-14T19:58:19.001799Z

if you keep your websocket connections in an atom (or whatever -waves hands-) outside of the stuff the reloaded workflow manages, then you can do this

robert-stuttaford 2015-12-14T19:59:15.001800Z

yeah, mlbatema. like we were discussing earlier, weā€™ve allowed for the webserver to be completely down by teaching the client how to cache and sync. more work, but affords us more flexibility

2015-12-14T20:01:14.001801Z

yeah, that seems the simpler answer. To my knowledge, Erlang doesn't have a solution for the client when the server's completely down. Gotta write/implement all that yourself. Go make friends with CRDTs and read about the CAP theorem šŸ˜›

sveri 2015-12-14T20:10:43.001802Z

I just tried clj-http and it seems like a failed request in the sense of not being authorized, throws an exception, which is suprising at least. Shouldn't it just return the response from the request and let me handle errors? That's what I would expect. Am I using it wrong?

markmandel 2015-12-14T20:11:38.001803Z

@nberger: Updating tools.namespace totally fixed that issue! Much appreciated!

sveri 2015-12-14T20:13:29.001804Z

Nevermind, I just found about {:throw-exceptions false}

jaen 2015-12-14T20:16:45.001805Z

@sveri: just keep in mind it will stop it only from throwing status code exceptions. Things like timeouts will still throw.

sveri 2015-12-14T20:18:24.001806Z

@jaen: ok, thank you, that is perfectly fine. Was just surprised, from a clients point of view I think, 401 or 403 are perfectly valid responses :simple_smile:

jaen 2015-12-14T20:22:47.001807Z

Yeah, I agree

nberger 2015-12-14T20:38:45.001808Z

Nice to hear @markmandel!

Josh Horwitz 2015-12-14T22:08:20.001810Z

Hi everyone, new to Clojure and hoping to make a website for a friends nonprofit using it

alexmiller 2015-12-14T22:09:05.001811Z

welcome!