Re: Trouble Running Chime Application outside for repl
Hi Chris, Thanks for posting an example - unfortunately I can't get onto it at the moment because it seems gitlab is down :( FWIW, I've seen a similar issue before where the schedule will run for a minute or so, then the process will exit successfully (even though you'd like it to continue) - is this what you're seeing? If so, this was caused by there being no non-daemon threads left running in the JVM, so the JVM exited - we worked around that by adding `@(promise)` to the end of our `-main` function, which had the effect of indefinitely pausing the main thread, and allowing the schedule to continue. If not, I'll try gitlab again in a bit! James On Monday, November 21, 2016 at 3:03:45 PM UTC, Chris Snyder wrote: > > > Have a program I want to run every 5 seconds unless the previous run is > not finished then I want it to wait on the previous run to finish. > To do this I used a library called Chime (https://github.com/jarohen/chime). > > > *The Problem* is the program works perfectly in repl but will not work > outside out of it? > > lein trampoline run - does not work > lein run - does not work > Java -jar (point to the uberjar file) - does not work > > lein repl then running main -does work > > Here is a small example I put together > https://gitlab.com/csnyder/chime-test/tree/master > -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
Hi Timothy - firstly, thank you for taking the time to read through and reply. I understand it would have been very easy to read them and move on thinking 'just a nutter on the mailing list who doesn't really understand what he's talking about', but I do really appreciate your feedback - thanks :) You're right - openly, I think it took not only hammocking about Yo-yo, but also sitting down over the weekend writing up the side-by-side to really realise what Component and Yo-yo both provide. (I don't regret doing either, of course - without doing so I wouldn't have got close to thinking about it in this way!) I do agree that not everything about Spring/OOP is bad, and certainly that Clojure/Component has taken the good parts. What I've seen so far, though, is some people (me included, probably) seeing Component, thinking 'that's nice, a pattern I'm familiar with', and reverting to writing Clojure apps like they used to write Spring apps - with components for *everything*, components for wiring up other components, etc, giving them all sorts of names (a la 'the Kingdom of Nouns'). It's also Phoenix, in particular, that reminded people of Spring - I've tried to ensure I always make that distinction, apologies if that didn't come across. Incidentally, I wrote a first iteration of the side-by-side blog with the Component side written in this style, and then realised there was nothing in Component that mandated writing in that way; just that I and others had interpreted it that way - it was quite an 'aha' moment! I'd also not heard that advice about anonymous functions either - thanks! Thinking about it, I've come up with all sorts of workarounds to get closed-over variables out of closures. Having said that, I think there's still some legs in Yo-yo - given that it doesn't mandate writing apps in any style (only that the one top level function accepts a system latch) it's possible to write Yo-yo apps as you would a Component system, or using functional composition, or anywhere in between. At the very least, Yo-yo would help with managing Component's system at the REPL - the top-level function becomes: (defn make-system [f] (let [started-system (- (c/system-map ...) c/start-system)] (try (f started-system) (finally (c/stop-system started-system) (defn -main [ args] (yoyo/set-system-fn! 'myapp.main/make-system) (yoyo/start!)) with the ability to then run (yoyo/reload!) etc from the REPL (without everyone having to write their own user namespace start/stop functions) I do also like the way that there aren't separate start/stop functions - maybe there's scope for a Lifecycle protocol that only involves one function instead? Maybe that's not even a good idea either, I don't know. I'll keep on experimenting, that's for sure :) Thanks again, James On Monday, 29 June 2015 02:49:43 UTC+1, tbc++ wrote: A few bits of feedback after seeing these examples. Firstly, I'd like to see a more fleshed-out rationale. Currently it sounds a bit like cargo-culting, e.g. Spring is bad, Component reminds people of Spring, therefore Component is bad. I'd challenge several parts of that rationale, but the first is that spring is bad. Why is that so? Is it the XML configuration? Because Component doesn't have that. Is it the mutability? Because Component doesn't have that either. Sadly I'm afraid some people seem to see polymorphic functions (protocols) and think AAAHHH OOP! OOP IS BAD!!. When that's not really the case. The worst parts of OOP are mutability and encapsulation of state inside opaque objects. Component (and clojure for that matter) discourages both of these, so I'm not sure I see the problem. Secondly, I'm a bit leery of using anonymous functions instead of records. I once worked on a system with a co-worker, and I asked him why are you using a record here...why not a closure?. He replied: Because I can't see what's inside a closure...it's opaque. That bit of advice has stuck with me for some time. With something like component, if I have a function that takes a component, I can look at that argument and see something like this: = #db.DBClient {:server 127.0.0.1 :port 4242 :schema my-schema} With Closures I get something like this: = fn foo.bar.baz That doesn't help much with debugging. With Records I get immutability plus a type I can extend to any protocols. Also, since my protocol is clearly defined, it's simple to extend. I don't have to worry about hidden functions some inner function may call on my client. Protocols provide abstraction. So I guess that's my critique of Yo-Yo. I'd love to see a more in-depth rationale, and I get nervous when people replace protocols with plain functions, because normally I loose some expressiveness in the process. Timothy On Sun, Jun 28, 2015 at 8:03 AM, James Henderson ja...@jarohen.me.uk javascript: wrote
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
Hey Thomas, thanks for your e-mail :) On Monday, 29 June 2015 11:25:44 UTC+1, Thomas Heller wrote: Hey, interesting approach but I don't like the nesting and manual wiring of dependencies. I've found people at both ends of that particular spectrum - some that won't live with DI, some that won't live without it :) I guess a library like Yo-yo has two options - either be opinionated about it, or let people choose one or the other. In this case, I've chosen to let people choose - there's nothing about Yo-yo that mandates the nesting (except the top-level function) - what you do within that is up to you. I don't quite like that every with-* function remains on the stack as well, but it shouldn't hurt that much. Hmm - I was wondering about that too. Maybe an approach similar to trampoline would help here? An uncaught exception will also take down your entire system, but I guess you'd have a try/catch in your latch anyways. I'm not sure it will? If there's an exception thrown during system startup, the components will then have an opportunity to stop themselves (in the reverse order) because of their try/finally's - I'd say this is the behaviour we'd want, in order to avoid half-started systems. Once the system's started, and (latch) called, an uncaught exception in the components won't stop the system - because it'll be thrown on a different thread, if I understand correctly? Certainly need to write some test cases around it! But what I miss the most is an instance of your app (ie. all components together). You create it yourself in the example but I really want that always. Sometimes you just want to access your system from the outside just to see whats up (eg. REPL into a live system). I also consider the webserver to be a client of my app and not part of it (or another layer of it if you will), but that is a topic for another day. Yep, I agree with this - I've been using some workarounds to get values out of the system, none of them particularly pretty. Interesting idea about the webserver being a client of the app - would be good to see where you take that? Way way back in the day I used to work with (and on) PicoContainer which was/is a dependency injection and lifecycle management container. I tried writing a DSL for it (in Groovy, this was 2003 or so) but concluded that Java already was good enough to set everything up, a DSL (or XML) is overkill. All you need to describe a Component is: a) what are its dependencies b) how do I start it c) how do I stop it In that light I wrote my own dependency injection helper functions since nothing like Stuart's Component existed at the time I got into Clojure. I don't like Component due to its invasive protocol but in essence I do the same. In my system I just set up a map of components and use that as a descriptor for wiring: {:a {:depends-on [] :start my.components.a/start :stop my.components.a/stop} :b {:depends-on [:a] :start my.components.b/start :stop my.components.b/stop}} The key in the outer map becomes whatever the :start function returns and is refered to it by its name :a (the key of the map). The :start function of :b is called as (my.components.b/start instance-of-a). An instance of a component is treated as an opaque value and other components interact with it only via its public interface (ie. my.components.a). Whether this is done via a protocol or not doesn't matter. When a shutdown is requested the :stop function is called with the instance of the component as the argument. That is about it. Mocking is just assoc over default descriptor map and I have helper functions to only do partial start/stop calls if only a specific component is needed (eg. I only need :a). Like I said it basically does the same stuff as Component, just a little less invasive since I think a component should not know about the container it runs in. Looks another interesting approach :) I'm currently hacking on some similar ideas myself - think there's plenty of room for iteration in this area at the moment! Hope that was somewhat useful as feedback to Yo-Yo. Certainly was! Thanks! :) Cheers, /thomas On Sunday, June 28, 2015 at 4:03:34 PM UTC+2, James Henderson wrote: As promised, have blogged: 'Yo-yo Component - Side by Side https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org ' Contents: - Making components https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#making-components - Using a component as a dependency https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#using-a-component-as-a-dependency - Serving a REST API https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#serving-a-rest-api - Wiring it all up https://github.com/james-henderson/yoyo/blob/master
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
As promised, have blogged: 'Yo-yo Component - Side by Side https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org ' Contents: - Making components https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#making-components - Using a component as a dependency https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#using-a-component-as-a-dependency - Serving a REST API https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#serving-a-rest-api - Wiring it all up https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#wiring-it-all-up - Yo-yo / Component Interoperability https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#yo-yocomponent-interoperability - Mockable Services https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#mockable-services - ‘Mocking out’ dependencies https://github.com/james-henderson/yoyo/blob/master/articles/mocking-out-dependencies Let me know what you think! Cheers, James On Thursday, 25 June 2015 09:25:56 UTC+1, James Henderson wrote: Seems like the next step for this would be for me to put together a blog with an example Component system, and its equivalent Yoyo system?! :) Should have time for that over the weekend. James On Thursday, 25 June 2015 09:05:39 UTC+1, James Henderson wrote: On Wednesday, 24 June 2015 11:17:41 UTC+1, Atamert Ölçgen wrote: On Tue, Jun 23, 2015 at 11:47 PM, James Henderson ja...@jarohen.me.uk wrote: Hi Atamert - thanks :) I thought it might be preferable to keep the call to (latch)explicit - it means that ylet can be used in nested calls, too - for example, to set up and compose groups of components/sub-systems: (contrived example, though!) ;; (docs for ylet at https://github.com/james-henderson/yoyo#introducing-ylet ) (require '[yoyo :refer [ylet]]) (defn with-connections [config f] (ylet [db-pool (with-db-pool (:db config)) es-conn (with-es-connection (:elasticsearch config))] (f {:db-pool db-pool :es-conn es-conn}))) (defn make-system [latch] (let [config ...] (ylet [connections (with-connections system) _ (with-webserver {:handler (make-handler (merge connections {:config config})) :port 3000})] (latch How would you see the with-* functions working, btw? I think the general idea should be to provide a clean API to the consumer (of your lib). Perhaps something that accepts a start function, a stop function and some sort of main loop (f in your example). Not sure I understand what you mean here? Tbh, I was trying to get away from the idea of separate start stop functions - it seems 'cleaner' to me without them! (although of course that's subjective). Also, the 'with-*' functions here are consumer code - the only Yo-yo functions/macros in this example are 'run-system!' and 'ylet'. Yo-yo itself is *tiny* (100 LoC) - my aim was for a library that solely dealt with starting/stopping a provided system, and *no more* :) Maybe it'd be worth fleshing out an example of what you were looking for? Cheers, James Cheers, James On Tuesday, 23 June 2015 09:57:16 UTC+1, Atamert Ölçgen wrote: Hi James, Interesting idea. Thanks for sharing. I think you can simplify this: (yoyo/run-system! (fn [latch] (ylet [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server) (latch to: (yoyo/foo! [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server)) I believe with-* function can also be simplified further. On Tue, Jun 23, 2015 at 1:18 AM, James Henderson ja...@jarohen.me.uk wrote: Hi all, I've just released an early version of 'Yo-yo', a protocol-less, function composition-based alternative to Component. It's still in its early stages, so feedback would be very much appreciated! https://github.com/james-henderson/yoyo Yo-yo was also an experiment to see what could be de-coupled from the concept of 'reloadable systems', so you won't find any configuration, dependency injection, etc - just a way to write a system that can be easily started, stopped, and reloaded. Fundamentally, we start by assuming there's a function available that only returns 'when the system stops' - a 'latch', say. If we had such a function, we could start our system, call that function
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
On Wednesday, 24 June 2015 11:17:41 UTC+1, Atamert Ölçgen wrote: On Tue, Jun 23, 2015 at 11:47 PM, James Henderson ja...@jarohen.me.uk javascript: wrote: Hi Atamert - thanks :) I thought it might be preferable to keep the call to (latch)explicit - it means that ylet can be used in nested calls, too - for example, to set up and compose groups of components/sub-systems: (contrived example, though!) ;; (docs for ylet at https://github.com/james-henderson/yoyo#introducing-ylet ) (require '[yoyo :refer [ylet]]) (defn with-connections [config f] (ylet [db-pool (with-db-pool (:db config)) es-conn (with-es-connection (:elasticsearch config))] (f {:db-pool db-pool :es-conn es-conn}))) (defn make-system [latch] (let [config ...] (ylet [connections (with-connections system) _ (with-webserver {:handler (make-handler (merge connections {:config config})) :port 3000})] (latch How would you see the with-* functions working, btw? I think the general idea should be to provide a clean API to the consumer (of your lib). Perhaps something that accepts a start function, a stop function and some sort of main loop (f in your example). Not sure I understand what you mean here? Tbh, I was trying to get away from the idea of separate start stop functions - it seems 'cleaner' to me without them! (although of course that's subjective). Also, the 'with-*' functions here are consumer code - the only Yo-yo functions/macros in this example are 'run-system!' and 'ylet'. Yo-yo itself is *tiny* (100 LoC) - my aim was for a library that solely dealt with starting/stopping a provided system, and *no more* :) Maybe it'd be worth fleshing out an example of what you were looking for? Cheers, James Cheers, James On Tuesday, 23 June 2015 09:57:16 UTC+1, Atamert Ölçgen wrote: Hi James, Interesting idea. Thanks for sharing. I think you can simplify this: (yoyo/run-system! (fn [latch] (ylet [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server) (latch to: (yoyo/foo! [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server)) I believe with-* function can also be simplified further. On Tue, Jun 23, 2015 at 1:18 AM, James Henderson ja...@jarohen.me.uk wrote: Hi all, I've just released an early version of 'Yo-yo', a protocol-less, function composition-based alternative to Component. It's still in its early stages, so feedback would be very much appreciated! https://github.com/james-henderson/yoyo Yo-yo was also an experiment to see what could be de-coupled from the concept of 'reloadable systems', so you won't find any configuration, dependency injection, etc - just a way to write a system that can be easily started, stopped, and reloaded. Fundamentally, we start by assuming there's a function available that only returns 'when the system stops' - a 'latch', say. If we had such a function, we could start our system, call that function, then stop the system (closing any necessary resources). A database pool, for example, might look like this: (defn with-db-pool [db-config f] (let [db-pool (start-pool! db-config)] (try (f db-pool) (finally (stop-pool! db-pool) Here, we're assuming that we'll be passed 'f', the 'latch' function. A web server would be similar, and, because they're both functions, they're very simple to compose: (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) :port ...} (fn [web-server] ;; TODO: Ah. We've run out of turtles. :( This is where Yo-yo comes in - there’s a function called run-system!, which takes a function that accepts a latch: (:require [yoyo]) (yoyo/run-system! (fn [latch] (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) ; n.b. we have access to the db-pool here - no need for global state! :port ...} (fn [web-server] (latch))) ; Aha! run-system! then returns a promise - deliver any value to it, and it'll stop the system. And that's pretty much it! There are a few more functions - mostly to do with easily starting/stopping/reloading a system through the REPL, and a macro to simplify the 'function staircase' - these are covered in more detail
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
Seems like the next step for this would be for me to put together a blog with an example Component system, and its equivalent Yoyo system?! :) Should have time for that over the weekend. James On Thursday, 25 June 2015 09:05:39 UTC+1, James Henderson wrote: On Wednesday, 24 June 2015 11:17:41 UTC+1, Atamert Ölçgen wrote: On Tue, Jun 23, 2015 at 11:47 PM, James Henderson ja...@jarohen.me.uk wrote: Hi Atamert - thanks :) I thought it might be preferable to keep the call to (latch)explicit - it means that ylet can be used in nested calls, too - for example, to set up and compose groups of components/sub-systems: (contrived example, though!) ;; (docs for ylet at https://github.com/james-henderson/yoyo#introducing-ylet ) (require '[yoyo :refer [ylet]]) (defn with-connections [config f] (ylet [db-pool (with-db-pool (:db config)) es-conn (with-es-connection (:elasticsearch config))] (f {:db-pool db-pool :es-conn es-conn}))) (defn make-system [latch] (let [config ...] (ylet [connections (with-connections system) _ (with-webserver {:handler (make-handler (merge connections {:config config})) :port 3000})] (latch How would you see the with-* functions working, btw? I think the general idea should be to provide a clean API to the consumer (of your lib). Perhaps something that accepts a start function, a stop function and some sort of main loop (f in your example). Not sure I understand what you mean here? Tbh, I was trying to get away from the idea of separate start stop functions - it seems 'cleaner' to me without them! (although of course that's subjective). Also, the 'with-*' functions here are consumer code - the only Yo-yo functions/macros in this example are 'run-system!' and 'ylet'. Yo-yo itself is *tiny* (100 LoC) - my aim was for a library that solely dealt with starting/stopping a provided system, and *no more* :) Maybe it'd be worth fleshing out an example of what you were looking for? Cheers, James Cheers, James On Tuesday, 23 June 2015 09:57:16 UTC+1, Atamert Ölçgen wrote: Hi James, Interesting idea. Thanks for sharing. I think you can simplify this: (yoyo/run-system! (fn [latch] (ylet [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server) (latch to: (yoyo/foo! [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server)) I believe with-* function can also be simplified further. On Tue, Jun 23, 2015 at 1:18 AM, James Henderson ja...@jarohen.me.uk wrote: Hi all, I've just released an early version of 'Yo-yo', a protocol-less, function composition-based alternative to Component. It's still in its early stages, so feedback would be very much appreciated! https://github.com/james-henderson/yoyo Yo-yo was also an experiment to see what could be de-coupled from the concept of 'reloadable systems', so you won't find any configuration, dependency injection, etc - just a way to write a system that can be easily started, stopped, and reloaded. Fundamentally, we start by assuming there's a function available that only returns 'when the system stops' - a 'latch', say. If we had such a function, we could start our system, call that function, then stop the system (closing any necessary resources). A database pool, for example, might look like this: (defn with-db-pool [db-config f] (let [db-pool (start-pool! db-config)] (try (f db-pool) (finally (stop-pool! db-pool) Here, we're assuming that we'll be passed 'f', the 'latch' function. A web server would be similar, and, because they're both functions, they're very simple to compose: (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) :port ...} (fn [web-server] ;; TODO: Ah. We've run out of turtles. :( This is where Yo-yo comes in - there’s a function called run-system!, which takes a function that accepts a latch: (:require [yoyo]) (yoyo/run-system! (fn [latch] (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) ; n.b. we have access to the db-pool here - no need for global state! :port ...} (fn [web-server] (latch))) ; Aha! run-system! then returns a promise - deliver any value
Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
Hi Atamert - thanks :) I thought it might be preferable to keep the call to (latch)explicit - it means that ylet can be used in nested calls, too - for example, to set up and compose groups of components/sub-systems: (contrived example, though!) ;; (docs for ylet at https://github.com/james-henderson/yoyo#introducing-ylet ) (require '[yoyo :refer [ylet]]) (defn with-connections [config f] (ylet [db-pool (with-db-pool (:db config)) es-conn (with-es-connection (:elasticsearch config))] (f {:db-pool db-pool :es-conn es-conn}))) (defn make-system [latch] (let [config ...] (ylet [connections (with-connections system) _ (with-webserver {:handler (make-handler (merge connections {:config config})) :port 3000})] (latch How would you see the with-* functions working, btw? Cheers, James On Tuesday, 23 June 2015 09:57:16 UTC+1, Atamert Ölçgen wrote: Hi James, Interesting idea. Thanks for sharing. I think you can simplify this: (yoyo/run-system! (fn [latch] (ylet [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server) (latch to: (yoyo/foo! [db-pool (with-db-pool {...}) :let [server-opts {:handler (make-handler {:db-pool db-pool}) :port 3000}] web-server (with-web-server server-opts)] (do-this web-server) (do-that db-pool web-server)) I believe with-* function can also be simplified further. On Tue, Jun 23, 2015 at 1:18 AM, James Henderson ja...@jarohen.me.uk javascript: wrote: Hi all, I've just released an early version of 'Yo-yo', a protocol-less, function composition-based alternative to Component. It's still in its early stages, so feedback would be very much appreciated! https://github.com/james-henderson/yoyo Yo-yo was also an experiment to see what could be de-coupled from the concept of 'reloadable systems', so you won't find any configuration, dependency injection, etc - just a way to write a system that can be easily started, stopped, and reloaded. Fundamentally, we start by assuming there's a function available that only returns 'when the system stops' - a 'latch', say. If we had such a function, we could start our system, call that function, then stop the system (closing any necessary resources). A database pool, for example, might look like this: (defn with-db-pool [db-config f] (let [db-pool (start-pool! db-config)] (try (f db-pool) (finally (stop-pool! db-pool) Here, we're assuming that we'll be passed 'f', the 'latch' function. A web server would be similar, and, because they're both functions, they're very simple to compose: (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) :port ...} (fn [web-server] ;; TODO: Ah. We've run out of turtles. :( This is where Yo-yo comes in - there’s a function called run-system!, which takes a function that accepts a latch: (:require [yoyo]) (yoyo/run-system! (fn [latch] (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) ; n.b. we have access to the db-pool here - no need for global state! :port ...} (fn [web-server] (latch))) ; Aha! run-system! then returns a promise - deliver any value to it, and it'll stop the system. And that's pretty much it! There are a few more functions - mostly to do with easily starting/stopping/reloading a system through the REPL, and a macro to simplify the 'function staircase' - these are covered in more detail in the README. There are some also common components - a database pool, a web server, and a simple integration for existing Component systems. It'd be great to hear your thoughts/ideas, whatever they may be - either through here, e-mail, Github, or Twitter - thanks! James -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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+u...@googlegroups.com javascript:. For more options, visit
[ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component
Hi all, I've just released an early version of 'Yo-yo', a protocol-less, function composition-based alternative to Component. It's still in its early stages, so feedback would be very much appreciated! https://github.com/james-henderson/yoyo Yo-yo was also an experiment to see what could be de-coupled from the concept of 'reloadable systems', so you won't find any configuration, dependency injection, etc - just a way to write a system that can be easily started, stopped, and reloaded. Fundamentally, we start by assuming there's a function available that only returns 'when the system stops' - a 'latch', say. If we had such a function, we could start our system, call that function, then stop the system (closing any necessary resources). A database pool, for example, might look like this: (defn with-db-pool [db-config f] (let [db-pool (start-pool! db-config)] (try (f db-pool) (finally (stop-pool! db-pool) Here, we're assuming that we'll be passed 'f', the 'latch' function. A web server would be similar, and, because they're both functions, they're very simple to compose: (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) :port ...} (fn [web-server] ;; TODO: Ah. We've run out of turtles. :( This is where Yo-yo comes in - there’s a function called run-system!, which takes a function that accepts a latch: (:require [yoyo]) (yoyo/run-system! (fn [latch] (with-db-pool {...} (fn [db-pool] (with-web-server {:handler (make-handler {:db-pool db-pool}) ; n.b. we have access to the db-pool here - no need for global state! :port ...} (fn [web-server] (latch))) ; Aha! run-system! then returns a promise - deliver any value to it, and it'll stop the system. And that's pretty much it! There are a few more functions - mostly to do with easily starting/stopping/reloading a system through the REPL, and a macro to simplify the 'function staircase' - these are covered in more detail in the README. There are some also common components - a database pool, a web server, and a simple integration for existing Component systems. It'd be great to hear your thoughts/ideas, whatever they may be - either through here, e-mail, Github, or Twitter - thanks! James -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Phoenix 0.1.0 - help with structuring configuring Component-based systems
Just released 0.1.1 - bug when using Schema in Phoenix apps due to Phoenix's overly-enthusiastic AOT'ing. Thanks to @whodidthis for flagging the issue! James On Sunday, 29 March 2015 20:44:04 UTC+1, James Henderson wrote: A link would have been really helpful, I'm guessing! Here it is: https://github.com/james-henderson/phoenix James On Sunday, 29 March 2015 20:42:06 UTC+1, James Henderson wrote: Hi all, I've just released v0.1.0 of Phoenix - a 'batteries included, but removable' library to wire up and configure Component-based systems. If you've ever wondered whether you really have to copy and paste 'system.clj', 'dev.clj' and 'user.clj' from one Component project to the next, it's well worth having a look at! Having used Phoenix in anger on a few projects for a couple of weeks, it's now had a fair bit of battle-testing, kinks ironed, and the like - so thought I'd make another post to the list :) Features added since I last posted: - Many re-usable Components - CLJS compiler, Aleph, http-kit, JDBC pool, CSS compiler (using Garden) - see https://github.com/james-henderson/phoenix/tree/master/modules/ for more details. These components can be used whether or not you choose to use Phoenix, and, likewise, non-Phoenix components can be used in Phoenix-configured systems - hooray for composability :) - Support for managing passwords/credentials - you can store these, encrypted, in your configuration, and Phoenix will decrypt them for you. - Pulling configuration variables from environment variables and JVM properties, in addition to the Phoenix config files - 'Batteries removable' API - if you need a little more flexibility, or want to compose Phoenix with something else. - A fair few bugfixes/API changes through usage There's also a couple of Lein templates to get up and running quickly: - `lein new phoenix-webapp my-project -- :reagent` will get you a working webapp (other options are `:om`, `:om-sablono` or `:flow`). - If you don't want the CLJS side, `lein new phoenix-api my-project` just has an example server-side API. Would be great to get your thoughts and feedback on this - is this a good way to wire up such systems? Cheers, James -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Phoenix 0.1.0 - help with structuring configuring Component-based systems
Thanks Jeroen - I'd not spotted that! Yes, definitely a better idea - will update the examples. James On 31/03/15 12:49, Jeroen van Dijk wrote: Thanks for sharing James! I'll have a look. As a side note, I see in the example code that you are dissoc-ing on the component. This can lead to unexpected behaviour as I have experienced (mostly in repl cases), as this will return a map instead of a record when the field is not part of the record. This is also mentioned in the readme of https://github.com/stuartsierra/component where `(assoc component ::field nil)` is recommended Jeroen On Sun, Mar 29, 2015 at 9:44 PM, James Henderson ja...@jarohen.me.uk mailto:ja...@jarohen.me.uk wrote: A link would have been really helpful, I'm guessing! Here it is: https://github.com/james-henderson/phoenix James On Sunday, 29 March 2015 20:42:06 UTC+1, James Henderson wrote: Hi all, I've just released v0.1.0 of Phoenix - a 'batteries included, but removable' library to wire up and configure Component-based systems. If you've ever wondered whether you really have to copy and paste 'system.clj', 'dev.clj' and 'user.clj' from one Component project to the next, it's well worth having a look at! Having used Phoenix in anger on a few projects for a couple of weeks, it's now had a fair bit of battle-testing, kinks ironed, and the like - so thought I'd make another post to the list :) Features added since I last posted: * Many re-usable Components - CLJS compiler, Aleph, http-kit, JDBC pool, CSS compiler (using Garden) - see https://github.com/james-henderson/phoenix/tree/master/modules/ for more details. These components can be used whether or not you choose to use Phoenix, and, likewise, non-Phoenix components can be used in Phoenix-configured systems - hooray for composability :) * Support for managing passwords/credentials - you can store these, encrypted, in your configuration, and Phoenix will decrypt them for you. * Pulling configuration variables from environment variables and JVM properties, in addition to the Phoenix config files * 'Batteries removable' API - if you need a little more flexibility, or want to compose Phoenix with something else. * A fair few bugfixes/API changes through usage There's also a couple of Lein templates to get up and running quickly: * `lein new phoenix-webapp my-project -- :reagent` will get you a working webapp (other options are `:om`, `:om-sablono`or `:flow`). * If you don't want the CLJS side, `lein new phoenix-api my-project` just has an example server-side API. Would be great to get your thoughts and feedback on this - is this a good way to wire up such systems? Cheers, James -- 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 mailto: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 mailto:clojure%2bunsubscr...@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 mailto:clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/EgfoZK0vV08/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com mailto:clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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
Re: [ANN] Phoenix 0.1.0 - help with structuring configuring Component-based systems
A link would have been really helpful, I'm guessing! Here it is: https://github.com/james-henderson/phoenix James On Sunday, 29 March 2015 20:42:06 UTC+1, James Henderson wrote: Hi all, I've just released v0.1.0 of Phoenix - a 'batteries included, but removable' library to wire up and configure Component-based systems. If you've ever wondered whether you really have to copy and paste 'system.clj', 'dev.clj' and 'user.clj' from one Component project to the next, it's well worth having a look at! Having used Phoenix in anger on a few projects for a couple of weeks, it's now had a fair bit of battle-testing, kinks ironed, and the like - so thought I'd make another post to the list :) Features added since I last posted: - Many re-usable Components - CLJS compiler, Aleph, http-kit, JDBC pool, CSS compiler (using Garden) - see https://github.com/james-henderson/phoenix/tree/master/modules/ for more details. These components can be used whether or not you choose to use Phoenix, and, likewise, non-Phoenix components can be used in Phoenix-configured systems - hooray for composability :) - Support for managing passwords/credentials - you can store these, encrypted, in your configuration, and Phoenix will decrypt them for you. - Pulling configuration variables from environment variables and JVM properties, in addition to the Phoenix config files - 'Batteries removable' API - if you need a little more flexibility, or want to compose Phoenix with something else. - A fair few bugfixes/API changes through usage There's also a couple of Lein templates to get up and running quickly: - `lein new phoenix-webapp my-project -- :reagent` will get you a working webapp (other options are `:om`, `:om-sablono` or `:flow`). - If you don't want the CLJS side, `lein new phoenix-api my-project` just has an example server-side API. Would be great to get your thoughts and feedback on this - is this a good way to wire up such systems? Cheers, James -- 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. For more options, visit https://groups.google.com/d/optout.
[ANN] Phoenix 0.1.0 - help with structuring configuring Component-based systems
Hi all, I've just released v0.1.0 of Phoenix - a 'batteries included, but removable' library to wire up and configure Component-based systems. If you've ever wondered whether you really have to copy and paste 'system.clj', 'dev.clj' and 'user.clj' from one Component project to the next, it's well worth having a look at! Having used Phoenix in anger on a few projects for a couple of weeks, it's now had a fair bit of battle-testing, kinks ironed, and the like - so thought I'd make another post to the list :) Features added since I last posted: - Many re-usable Components - CLJS compiler, Aleph, http-kit, JDBC pool, CSS compiler (using Garden) - see https://github.com/james-henderson/phoenix/tree/master/modules/ for more details. These components can be used whether or not you choose to use Phoenix, and, likewise, non-Phoenix components can be used in Phoenix-configured systems - hooray for composability :) - Support for managing passwords/credentials - you can store these, encrypted, in your configuration, and Phoenix will decrypt them for you. - Pulling configuration variables from environment variables and JVM properties, in addition to the Phoenix config files - 'Batteries removable' API - if you need a little more flexibility, or want to compose Phoenix with something else. - A fair few bugfixes/API changes through usage There's also a couple of Lein templates to get up and running quickly: - `lein new phoenix-webapp my-project -- :reagent` will get you a working webapp (other options are `:om`, `:om-sablono` or `:flow`). - If you don't want the CLJS side, `lein new phoenix-api my-project` just has an example server-side API. Would be great to get your thoughts and feedback on this - is this a good way to wire up such systems? Cheers, James -- 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. For more options, visit https://groups.google.com/d/optout.
Re: Announcing oolong: a config-based glue for `component`
Thanks - thoughts inline :) On Wednesday, 18 March 2015 09:29:59 UTC, James Laver wrote: Hi James, ‘component’ is a difficult term to google for, so I hadn’t come across your project :) Same problem here when I started writing Phoenix - there could be many libraries trying to solve the same problem! I think your module had slightly different design goals from mine. Mine were: * everything in one config file (although i also provide support for separate data-config and system config) * be minimal. i’ve got a bunch of things i’m building on top of oolong at present that will together provide a more “complete” experience Fair enough! I went for giving people the option of either one config file or multiple (after all, you don't *have* to use :phoenix/includes!) mainly because I got a lot of requests in Nomad (Phoenix's predecessor) for separate apps within the same company to share common configuration. I see you note that phoenix is ‘batteries included’. That’s a great experience for new users, but i wasn’t trying to build that on this occasion :) The leiningen template and plugin are also nice additions, and reloaded workflow integration is very handy. Hmm - Phoenix is 'batteries included, but removable' (phrasing stolen from Docker) which is significantly different from 'batteries included'. I'm not a fan of 'batteries included' - it tends to mean libraries that are hard for users to customise at a later date, which (to me, and to you as well by the sounds of it) goes against Clojure ideals. Phoenix is deliberately written as a standalone runtime library, which composes with whatever other systems people dream up, and a separate, lightweight plugin (not so composable), which essentially just bootstraps the library and saves people the hassle of a separate 'system.clj', 'dev.clj' and 'user.clj', if they so wish. Reloaded workflow has been an experience for me. I haven’t yet managed to get it working in the face of compile errors. I find myself restarting the leiningen repl about as much as before. For this reason I chose to keep it separate and delay dealing with it for a few weeks. Have you managed to overcome these problems? I’m definitely interested in knowing how if so. Happy to help with these - do you want to post some specifics? As a starting point, I've found that including an 'emergency nREPL' - an nREPL that starts before the application (and doesn't depend on the application compiling) gets you a long way. If the application doesn't compile, the system doesn't start, but I think that's actually preferable than half a system. I’ve only really given phoenix a few minutes of my attention so far, but I like what I see and I’m liable to steal ideas for some of the things i’ll be building on top of oolong. Feel free to reply offlist if you have any further questions. Feel free to steal ideas from Phoenix - that's what open source is all about! More than happy to work together on this as well though - seems like we have both come to very similar conclusions about how we want to wire up Clojure components. James On 18 Mar 2015, at 09:07, James Henderson ja...@jarohen.me.uk javascript: wrote: Hi James, This looks very similar to Phoenix - a project I've been working on for the last few months. It's pretty likely you hadn't heard of it (and that's fine - it's not been hugely publicised!), but if you have, I was wondering whether there was anything about it that you felt was missing/a bad design decision? If so, would be great to get your feedback! Cheers, James On Tuesday, 17 March 2015 10:02:51 UTC, James Laver wrote: I've been using stuartsierra's handy component library for a while now, but I wanted an easier way of connecting components together. To that end, I wrote oolong. The main mode of operation is to take an edn configuration file and connect the specified systems and components. https://github.com/jjl/oolong https://clojars.org/oolong Feedback welcome. I spent quite a while documenting it so hopefully it should be fairly clear to understand. James -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/T_skapDqZ0U/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+u
Re: Announcing oolong: a config-based glue for `component`
Hi James, This looks very similar to Phoenix https://github.com/james-henderson/phoenix - a project I've been working on for the last few months. It's pretty likely you hadn't heard of it (and that's fine - it's not been hugely publicised!), but if you have, I was wondering whether there was anything about it that you felt was missing/a bad design decision? If so, would be great to get your feedback! Cheers, James On Tuesday, 17 March 2015 10:02:51 UTC, James Laver wrote: I've been using stuartsierra's handy component library for a while now, but I wanted an easier way of connecting components together. To that end, I wrote oolong. The main mode of operation is to take an edn configuration file and connect the specified systems and components. https://github.com/jjl/oolong https://clojars.org/oolong Feedback welcome. I spent quite a while documenting it so hopefully it should be fairly clear to understand. James -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Introducing 'Phoenix' - a new library for declarative configuration and wiring of Component-based systems
Hi Dan - it's possible to load configuration from environment variables as of version 0.0.2 (released today) - you can now put [::env :env-var-name]in your configuration to look up the 'ENV_VAR_NAME' environment variable. More info in the env-vars section https://github.com/james-henderson/phoenix#config-in-environment-variables of the README. Re: tagged literals: I'm pretty sure that's possible too - I can't see why it wouldn't honour readers that you put into your data-readers.edn file (haven't tried this out yet though), but there's currently no way to pass custom readers to Phoenix directly. I think this is one of the downsides of going for a plugin+library approach rather than just a library - I've split it out today so that it is possible to call the library directly, but it could still do with being a bit more flexible, I think! James On Sunday, 25 January 2015 13:10:34 UTC, Dan Kersten wrote: Hi James, This looks nice. I do have one question: is it possible to load parts of a configuration from environment variables? Eg, in your location-aware configuration example, lets say I wanted to specify the database user and pass configuration options as you do for the dev configurations, but I want to load them from environment variables in the prod configuration? Or, better yet, if it were pluggable (through tagged literals maybe?), so that I can choose where to load configuration from, eg, zookeeper or etcd). On Sat Jan 24 2015 at 3:20:13 PM James Henderson ja...@jarohen.me.uk javascript: wrote: Hi all, I've just released Phoenix - a library for declarative configuration and wiring of Component-based systems. Phoenix came out of a number of discussions at ClojureX, thank you to all involved for their suggestions and feedback :) https://github.com/james-henderson/phoenix If you’ve written a traditional Component-based system, you’ve probably experienced having to create and maintain a plethora of ‘system.clj’, ‘dev.clj’, ‘user.clj’ etc type namespaces in order to wire-up the system, set up configuration-based switches, and duplicate the code to start/stop/reload the system. Phoenix removes the need for all of this, replacing it with one (or more, if you choose) EDN declaration of how your system should be wired up. It should also compose well with any other Components you (or anyone else) may have already written. For a sample project, you can run 'lein new phoenix-webapp your-project', then 'cd your-project' and 'lein dev'. Once the nREPL is up, running ' (phoenix/reload!)' will stop the system, reload any namespaces, and restart the system. Phoenix is just one possible way of wiring up such a system - I understand that there are a fair few ideas floating around out there at the moment! I'd be really interested to hear your thoughts - whether it be 'this is mostly right, but I wouldn't do that part like that', or 'you've gone about this completely the wrong way, because ...' - let me know! Cheers, James -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Introducing 'Phoenix' - a new library for declarative configuration and wiring of Component-based systems
Hi Leif - thanks for the suggestion. You're not the only person that's questioned the auto-namespaced keywords, btw! The original reasoning behind them was to keep Phoenix-related configuration separate from the user's own configuration, but without enforcing typing :phoenix/ in front of all of the keywords. I'm not sure if this is the best/only way to do it, or even whether people would mind writing out :phoenix/component or :phoenix/dep every time they were required? Do you have any ideas/thoughts about how to do this? I'm happy to make breaking changes at the moment if necessary - Phoenix is still very much in 0.0.x territory! Also, I didn't realise the EDN spec prohibited it, although now you mention it it makes sense that it should. I think, on balance, I'd prefer to resolve the problem rather than just accepting it and renaming the configuration file - if we can find the right way to solve it! Thanks, James On Sunday, 25 January 2015 13:15:00 UTC, Leif wrote: Hi, James. I'll let people with more experience with components critique your solution, but one thing that I thought was weird was that you had auto-namespaced keywords in the config file. I'm referring to: https://github.com/james-henderson/phoenix#adding-dependencies-between-components That means only code in your blessed ns can read the file, or things break. Also, the edn spec disallows keywords beginning with ::. So, I'd suggest either following the edn spec or using the .clj ending for the config files. --Leif On Saturday, January 24, 2015 at 10:20:10 AM UTC-5, James Henderson wrote: Hi all, I've just released Phoenix - a library for declarative configuration and wiring of Component-based systems. Phoenix came out of a number of discussions at ClojureX, thank you to all involved for their suggestions and feedback :) https://github.com/james-henderson/phoenix If you’ve written a traditional Component-based system, you’ve probably experienced having to create and maintain a plethora of ‘system.clj’, ‘dev.clj’, ‘user.clj’ etc type namespaces in order to wire-up the system, set up configuration-based switches, and duplicate the code to start/stop/reload the system. Phoenix removes the need for all of this, replacing it with one (or more, if you choose) EDN declaration of how your system should be wired up. It should also compose well with any other Components you (or anyone else) may have already written. For a sample project, you can run 'lein new phoenix-webapp your-project', then 'cd your-project' and 'lein dev'. Once the nREPL is up, running ' (phoenix/reload!)' will stop the system, reload any namespaces, and restart the system. Phoenix is just one possible way of wiring up such a system - I understand that there are a fair few ideas floating around out there at the moment! I'd be really interested to hear your thoughts - whether it be 'this is mostly right, but I wouldn't do that part like that', or 'you've gone about this completely the wrong way, because ...' - let me know! Cheers, James -- 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. For more options, visit https://groups.google.com/d/optout.
[ANN] Introducing 'Phoenix' - a new library for declarative configuration and wiring of Component-based systems
Hi all, I've just released Phoenix - a library for declarative configuration and wiring of Component-based systems. Phoenix came out of a number of discussions at ClojureX, thank you to all involved for their suggestions and feedback :) https://github.com/james-henderson/phoenix If you’ve written a traditional Component-based system, you’ve probably experienced having to create and maintain a plethora of ‘system.clj’, ‘dev.clj’, ‘user.clj’ etc type namespaces in order to wire-up the system, set up configuration-based switches, and duplicate the code to start/stop/reload the system. Phoenix removes the need for all of this, replacing it with one (or more, if you choose) EDN declaration of how your system should be wired up. It should also compose well with any other Components you (or anyone else) may have already written. For a sample project, you can run 'lein new phoenix-webapp your-project', then 'cd your-project' and 'lein dev'. Once the nREPL is up, running ' (phoenix/reload!)' will stop the system, reload any namespaces, and restart the system. Phoenix is just one possible way of wiring up such a system - I understand that there are a fair few ideas floating around out there at the moment! I'd be really interested to hear your thoughts - whether it be 'this is mostly right, but I wouldn't do that part like that', or 'you've gone about this completely the wrong way, because ...' - let me know! Cheers, James -- 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. For more options, visit https://groups.google.com/d/optout.
(ANN) simple-brepl 0.1.2 released
Hi all - just a quick note to announce the release of *simple-brepl* 0.1.2. 'simple-brepl', as the name suggests, is a really simple way to connect to ClojureScript browser REPLs. It's built atop Tom Jakubowski's excellent Weasel library, which uses Websockets to communicate with the browser. Full docs and a sample project are on GitHub at https://github.com/james-henderson/simple-brepl Any problems, let me know! James -- 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. For more options, visit https://groups.google.com/d/optout.
[ANN] Nomad 0.7.0 and Frodo 0.4.1 - configuration made simple
Hi all, I've just released Nomad 0.7.0, a configuration management library that makes it simple to configure instances of your applications on multiple machines; and Frodo 0.4.1 - a web server that is configured using Nomad and uses Stuart Sierra's 'Reloaded' pattern. Github repos are at https://github.com/james-henderson/nomad and https://github.com/james-henderson/frodo respectively. Thanks to Dylan Paris and Luke Snape for their PRs! James -- 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. For more options, visit https://groups.google.com/d/optout.
Re: How to add elements to a vector that is the value of a map key?
'alter' expects your anonymous function to take at least one argument (the current value of the ref being altered), whereas you've passed a 0-arg function - there's no mention of a '%' so Clojure expands it to: (fn [] (update-in @v (fnil conj []))) Indeed, I suspect you want a 2-arg function here - one for the current value of the ref and one for the number to conj on - if you were writing it in expanded form you'd write: (fn [v x] (update-in v (fnil conj []) x)) Or, in compact form: #(update-in %1 (fnil conj []) %2) HTH, James On Tuesday, 17 June 2014 19:05:10 UTC+1, Hussein B. wrote: Thanks, it works. In case, my initial map is a ref type (def m (ref { } )) Why this isn't working? (dosync (alter m #(update-in @v [1] (fnil conj [ ])) 11)) On Tuesday, June 17, 2014 7:55:14 PM UTC+2, Mauricio Aldazosa wrote: For updating the value of a map given a key you can use update-in: user (update-in {1 [11]} [1] conj 22) {1 [11 22]} Now, to handle the case when the key is not present, you can use fnil: user (update-in {} [1] (fnil conj []) 22) {1 [22]} Cheers, Mauricio -- 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. For more options, visit https://groups.google.com/d/optout.
Re: How to add elements to a vector that is the value of a map key?
Ah, you got there first :) James On Tuesday, 17 June 2014 19:20:52 UTC+1, James Henderson wrote: 'alter' expects your anonymous function to take at least one argument (the current value of the ref being altered), whereas you've passed a 0-arg function - there's no mention of a '%' so Clojure expands it to: (fn [] (update-in @v (fnil conj []))) Indeed, I suspect you want a 2-arg function here - one for the current value of the ref and one for the number to conj on - if you were writing it in expanded form you'd write: (fn [v x] (update-in v (fnil conj []) x)) Or, in compact form: #(update-in %1 (fnil conj []) %2) HTH, James On Tuesday, 17 June 2014 19:05:10 UTC+1, Hussein B. wrote: Thanks, it works. In case, my initial map is a ref type (def m (ref { } )) Why this isn't working? (dosync (alter m #(update-in @v [1] (fnil conj [ ])) 11)) On Tuesday, June 17, 2014 7:55:14 PM UTC+2, Mauricio Aldazosa wrote: For updating the value of a map given a key you can use update-in: user (update-in {1 [11]} [1] conj 22) {1 [11 22]} Now, to handle the case when the key is not present, you can use fnil: user (update-in {} [1] (fnil conj []) 22) {1 [22]} Cheers, Mauricio -- 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. For more options, visit https://groups.google.com/d/optout.
Re: ANN: ring-token-authentication. A ring middleware to authenticate API requests
Really useful, concise library - thanks! James On Saturday, 15 February 2014 18:53:58 UTC, Jason Stewart wrote: I've just pushed the first version of ring-token-authentication, a Ring middleware to authenticate HTTP API requests. Token authentication is a popular way to authenticate API requests over HTTP. A client sends a token in the Authorization header like so: Authorization: Token token=notasecret The token is then parsed from the authorization header and checked for authenticity on the server side. This middleware aims to make it easy to add HTTP token authentication to your application, like it is in many other frameworks. This is my first open source Clojure project, and I'm excited to share it with you. Come check it out at https://github.com/jstewart/ring-token-authenticationor on clojars here: https://clojars.org/ring-token-authentication -- 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. For more options, visit https://groups.google.com/groups/opt_out.
ANN: Chord 0.3.0 - WebSockets as core.async channels
I've just pushed v0.3.0 of Chord, a library to make a WebSockets appear as a bi-directional core.async channels. More info on GitHub https://github.com/james-henderson/chord. New since 0.2.2: - Messages over the channel treated as EDN by default (although option to fall back to previous raw strings) - this saves wrapping every write with `pr-str` and every read with `edn/read-string` As usual, feedback welcome! Cheers, James -- 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. For more options, visit https://groups.google.com/groups/opt_out.
ANN: Clidget 0.2.0
Hi all, I've just released a new version of Clidgethttps://github.com/james-henderson/clidget- a very lightweight library similar to Om, that watches your application state and re-renders your UI components when necessary. 0.2.0 is a significant performance upgrade over 0.1.0 due to better batching of DOM updates - which means that Clidget is now comparablehttps://gist.github.com/james-henderson/9020774in performance to Om. For those who haven't seen Clidget before: - Clidget has *one macro*, 'defwidget', which looks and behaves like 'defn' - you take in *values* and return a real DOM element, like any other Clojure function. When you call it, pass it *atoms*, and Clidget will work out when the DOM element needs to be re-rendered. That's all there is to it! - You choose how to render the DOM element, how to respond to events and how to update the atoms. Clidget does *one thing* - figuring out when to update widgets - there are people far better than me at designing DOM templating libraries! Useful links: - Github, Rationale and READMEhttps://github.com/james-henderson/clidget - A more in-depth comparison to Om, Reagent and Reacthttps://github.com/james-henderson/clidget/blob/master/comparison.org - Clidget 'Hello worldhttps://github.com/james-henderson/clidget/tree/master/clidget-sample ' - Contact Manager Tutorialhttps://github.com/james-henderson/clidget/tree/master/contacts (along the same lines as Om + Reagent's tutorials) - TodoMVC implementationhttps://github.com/james-henderson/clidget/tree/master/todomvc Feedback always welcome! Cheers, James (@jarohen https://twitter.com/jarohen) -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: core.async over websocket + cljs + clojure
Hi folks, sorry I'm a bit late to the party, but Chord might be a good base for what you want to do? It probably falls a bit short at the moment on your disconnection semantics, but could be worth a shot. https://github.com/james-henderson/chord James -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Clidget, a lightweight CLJS state utility that helps you build small, composable UI ‘widgets’.
Hi all, I've recently released Clidget v0.1.0, a new lightweight CLJS state utility that allows you to build UIs through small, composable widgets. Quick links: - GitHub https://github.com/james-henderson/clidget (README, Rationale and Getting Started) - Sample 'counter' applicationhttps://github.com/james-henderson/clidget/tree/master/clidget-sample - TodoMVC implementationhttps://github.com/james-henderson/clidget/tree/master/todomvc The fundamental idea behind Clidget is to ensure that you can write widgets declaratively, in traditional Clojure style, as a function that *takes in immutable values and returns a DOM element*. Then, rather than calling that function with values, you* call it with atoms*, and Clidget figures out when each widget needs to be re-rendered. So, a counter widget would look something like this (using Dommy to create the DOM element and core.async for event handling - you're free to choose whatever you like): (:require [cljs.core.async :as a] [dommy.core :as d] [clidget.widget :refer [defwidget] :include-macros true]) (:require-macros [dommy.macros :refer [node]] [cljs.core.async.macros :refer [go-loop]])) (defwidget counter-widget [{:keys [counter]} events-ch] (node [:div [:h2 counter is now: counter] [:p (doto (node [:button Increment counter]) (d/listen! :click #(a/put! events-ch :inc-counter)))]])) To include a widget in the page, call it (it’s just a function!), but provide it with the *atoms* that it needs to watch: (set! (.-onload js/window) (fn [] (let [!counter (atom 0) events-ch (doto (a/chan) ;; 'watch-events!' implemented below (watch-events! !counter))] (d/replace-contents! (.-body js/document) (counter-widget {:!counter !counter} events-ch)] (I'm prefixing the atom with '!', to easily differentiate between atoms and values) Finally, we implement watch-events! (no Clidget here): (defn watch-events! [events-ch !counter] (go-loop [] (when-let [event (a/! events-ch)] (when (= :inc-counter event) (swap! !counter inc)) (recur (We could do this inside the widget, given it's only a counter, but it's probably better to separate it!) *Why?!* The main design decision behind Clidget was to favour simplicity over performance (obviously within reason). Clidget does one thing (I hope it does it well!) - figuring out which widgets to re-render and when. How you update the state, render the widgets, pass the events, handle the events etc is completely up to you. There's no 'magic' in Clidget - you pass in atoms, it behaves pretty much like Clojure's add-watch function. I've found this to be a really useful quality when reasoning about applications - it makes the debugging headache a lot more manageable. Finally, I wanted to preserve Clojure's composability. One of the benefits I really enjoy about working with Clojure is the ability to use many small libraries without worrying about how they'll fit together. If you're a Hiccup person, you can use your favourite Hiccup-like library; if you're an Enlive/Mustache person, likewise! In Clidget, this also extends to JS libraries - when you're working with the DOM elements that will end up on the page, you can pass them to other JS libraries easily. I've received a number of requests for a comparison with Om/Cloact/React - it didn't fit into 140 characters, so it's here https://github.com/james-henderson/clidget/blob/master/comparison.org. *Feedback* The idea behind Clidget is still very much experimental - I'd be very interested to hear thoughts and feedback (good, bad, and 'what on earth were you thinking?!') on the approach and/or implementation, please let me know! GitHub, Twitter (@jarohen https://twitter.com/jarohen) or through here are all good. If you've got this far, thanks for reading! James -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Clidget, a lightweight CLJS state utility that helps you build small, composable UI ‘widgets’.
Hi all, I've recently released *Clidget v0.1.0*, a new lightweight CLJS state utility that allows you to build UIs through small, composable widgets. Quick links: - GitHub https://github.com/james-henderson/clidget (README, Rationale and Getting Started) - Sample 'counter' applicationhttps://github.com/james-henderson/clidget/tree/master/clidget-sample - TodoMVC implementationhttps://github.com/james-henderson/clidget/tree/master/todomvc The fundamental idea behind Clidget is to ensure that you can write widgets declaratively, in traditional Clojure style, as a function that *takes in immutable values and returns a DOM element*. Then, rather than calling that function with values, you* call it with atoms*, and Clidget figures out when each widget needs to be re-rendered. So, a counter widget would look something like this (using Dommy to create the DOM element and core.async for event handling - you're free to choose whatever you like): (:require [cljs.core.async :as a] [dommy.core :as d] [clidget.widget :refer [defwidget] :include-macros true]) (:require-macros [dommy.macros :refer [node]] [cljs.core.async.macros :refer [go-loop]])) (defwidget counter-widget [{:keys [counter]} events-ch] (node [:div [:h2 counter is now: counter] [:p (doto (node [:button Increment counter]) (d/listen! :click #(a/put! events-ch :inc-counter)))]])) To include a widget in the page, call it (it’s just a function!), but provide it with the *atoms* that it needs to watch: (set! (.-onload js/window) (fn [] (let [!counter (atom 0) events-ch (doto (a/chan) ;; 'watch-events!' implemented below (watch-events! !counter))] (d/replace-contents! (.-body js/document) (counter-widget {:!counter !counter} events-ch)] (I'm prefixing the atom with '!', to easily differentiate between atoms and values) Finally, we implement watch-events! (no Clidget here): (defn watch-events! [events-ch !counter] (go-loop [] (when-let [event (a/! events-ch)] (when (= :inc-counter event) (swap! !counter inc)) (recur (We could do this inside the widget, given it's only a counter, but it's probably better to separate it!) *Why?!* The main design decision behind Clidget was to favour simplicity over performance (obviously within reason). Clidget does one thing (I hope it does it well!) - figuring out which widgets to re-render and when. How you update the state, render the widgets, pass the events, handle the events etc is completely up to you. There's no 'magic' in Clidget - you pass in atoms, it behaves pretty much like Clojure's add-watch function. I've found this to be a really useful quality when reasoning about applications - it makes the debugging headache a lot more manageable. Finally, I wanted to preserve Clojure's composability. One of the benefits I really enjoy about working with Clojure is the ability to use many small libraries without worrying about how they'll fit together. If you're a Hiccup person, you can use your favourite Hiccup-like library; if you're an Enlive/Mustache person, likewise! In Clidget, this also extends to JS libraries - when you're working with the DOM elements that will end up on the page, you can pass them to other JS libraries easily. I've received a number of requests for a comparison with Om/Cloact/React - it didn't fit into 140 characters, so it's herehttps://github.com/james-henderson/clidget/blob/master/comparison.org . *Feedback* The idea behind Clidget is still very much experimental - I'd be very interested to hear thoughts and feedback (good, bad, and 'what on earth were you thinking?!') on the approach and/or implementation, please let me know! GitHub, Twitter (@jarohen https://twitter.com/jarohen) or through here are all good. If you've got this far, thanks for reading! James -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Frodo 0.2.9 - Ring-compatible web server with Stuart Sierra's 'Reloaded' workflow
Hi all, I've just released Frodo 0.2.9 - a web server plugin that allows you to develop using Stuart Sierra's 'Reloaded' workflow. It sets up a web server that you can nREPL into, easily open a CLJS browser REPL (using Chas Emerick's 'Austin' library) and, when you've made changes, to start a fresh web-server and refresh the server-side state without restarting the JVM. *https://github.com/james-henderson/frodo*https://github.com/james-henderson/frodo If you haven't seen it already, Stuart's written a great blog on how to develop using the 'Reloaded' workflow and its benefits - it's at http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded. There are plenty of Frodo examples and a sample project on the GitHub repo, but the basic premise is that you configure Frodo with a function that initialises your system state and returns a handler. When your server-side code changes and you run (user/reload-frodo!)in the REPL, it will reload any changed namespaces (and anything that depends on a changed namespace), restart the web server and ask your function to initialise its state and return another handler. This usually looks something like: (ns your-app.handler (:require [compojure.core :refer [routes GET]] [compojure.handler :refer [api]] [ring.util.response :refer [response]])) (defn app-routes [] (let [system (init-system)] (routes (GET /route/:id [id] (response (handle-get system id))) ...))) (defn app [] (- (app-routes) wrap-with-ring-middleware api)) You'd then configure Frodo to use '*your-app.handler/app*' as its entry point. Probably the easiest way to get up and running is to use '*splat*', a Lein template: lein new splat your-project cd your-project lein dev If you've got any questions or feedback, it'd be great to hear it! Let me know, either through here, GitHub or Twitter (I'm @jarohenhttps://twitter.com/jarohen ) Hope you all have a great Christmas, and a happy New Year! James -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] cljs-start 0.0.7 now support source-map
Hi all, On Tuesday, 17 December 2013 16:35:24 UTC, Magomimmo wrote: In my mind I think about something like a pair composed by of a lein template and a lein plugin. The template should serve to create new mixed clj/cljs projects and the plugin should serve to easily manage the project itself. I recently wrote a clj/cljs template called 'splat' which is implemented exactly as you suggest - `lein new splat your-project` I would be even better to absorb the awesome stuff my Stuart Sierra and jig, then absorb stuff regarding continuos development, integration and deployment to try to minimize any incidental complexities caused by the used tools. That would be great - at the moment I rely on connecting to the nREPL (in preference to the plugin naively guessing what to reload) but something based on the Reloaded workflow or Jig would be really cool. A kind of reference sample could http://yeoman.io/ Will take a look, thanks for the pointer! mimmo James -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Chord 0.2.1 - making WebSockets look like core.async channels in CLJ+CLJS
Unfortunately Chord only accepts raw strings on the channel at the moment - I've been using pr-str and read-string around EDN messages until now. It's a great idea to be able to format/parse different message formats automatically though and something that IMO Chord should provide. I've added a GitHub issue https://github.com/james-henderson/chord/issues/4 - watch this space! Thanks, James On Monday, 2 December 2013 09:38:50 UTC, Henrik Eneroth wrote: Cool! I presume you're restricted to EDN on the channels though, right? On Saturday, November 30, 2013 5:23:17 PM UTC+1, James Henderson wrote: https://github.com/james-henderson/chord Chord is a library for making WebSockets look like simple core.async channels in Clojure (using http-kit) and ClojureScript. Basic usage: Leiningen: [jarohen/chord 0.2.1] ClojureScript: (:require [chord.client :refer [ws-ch]] [cljs.core.async :refer [! ! put! close!]])(:require-macros [cljs.core.async.macros :refer [go]]) (go (let [ws (! (ws-ch ws://localhost:3000/ws))] (! ws Hello server!) (loop [] (when-let [{:keys [message]} (! ws)] (js/console.log Got message from server: message) (recur) Clojure (a wrapper around http-kit's 'with-channel'): (:require [chord.http-kit :refer [with-channel]] [clojure.core.async :refer [! ! put! close! go]]) (defn your-handler [req] (with-channel req ws-ch (go (let [{:keys [message]} (! ws-ch)] (println Message received from client: message) (! ws-ch Hello client from server!) (close! ws-ch) There's more documentation and a few code examples on the Github page, and a full example project in the repo. Feedback is *always very welcome* - either here, through Github in the usual way or (if it fits into 140 chars!) Twitter. Version 0.2.1 brings the ability to specify custom buffered channels - thanks to Timo Sulg for the PR! James (@jarohen) -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Chord 0.2.1 - making WebSockets look like core.async channels in CLJ+CLJS
https://github.com/james-henderson/chord Chord is a library for making WebSockets look like simple core.async channels in Clojure (using http-kit) and ClojureScript. Basic usage: Leiningen: [jarohen/chord 0.2.1] ClojureScript: (:require [chord.client :refer [ws-ch]] [cljs.core.async :refer [! ! put! close!]])(:require-macros [cljs.core.async.macros :refer [go]]) (go (let [ws (! (ws-ch ws://localhost:3000/ws))] (! ws Hello server!) (loop [] (when-let [{:keys [message]} (! ws)] (js/console.log Got message from server: message) (recur) Clojure (a wrapper around http-kit's 'with-channel'): (:require [chord.http-kit :refer [with-channel]] [clojure.core.async :refer [! ! put! close! go]]) (defn your-handler [req] (with-channel req ws-ch (go (let [{:keys [message]} (! ws-ch)] (println Message received from client: message) (! ws-ch Hello client from server!) (close! ws-ch) There's more documentation and a few code examples on the Github page, and a full example project in the repo. Feedback is *always very welcome* - either here, through Github in the usual way or (if it fits into 140 chars!) Twitter. Version 0.2.1 brings the ability to specify custom buffered channels - thanks to Timo Sulg for the PR! James (@jarohen) -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: How do you configure your Ring apps?
Hi Gordon/all, Hope you'll forgive the plug, but it sounds like Nomadhttps://github.com/james-henderson/nomad.git does what you want here. In particular, it allows you to store configuration for multiple different environments as a simple EDN config file in your project repo (Gordon's 'global.clj'), meaning that it's versioned with the rest of your project code (i.e. there's no need to configure Puppet etc separately, and keep the project and Puppet versions co-ordinated). It also allows for 'private config files' (Gordon's 'local.clj'), to store passwords etc that you don't want in version control. HTH! James On Sunday, 8 September 2013 02:44:24 UTC+1, Gordon Stratton wrote: I'm only starting out with Clojure/Ring, but I was thinking about this recently too. I had something like the following in mind, borrowing some concepts from other projects/frameworks/strategies that I've had success with. The project could contain something like 'config/global.clj' which contains a simple Clojure map with configuration for your app that is appropriate for version control. Maybe it has some default values, comments, etc. You could build this in to your app somewhere, too. The project would then have another Clojure map in a file named like 'config/local.clj' in your project root which would be ignored by version control, and deployed alongside your application. You'd probably template it with Puppet or Chef or Ansible and it would contain your deep, dark secrets. You'd have a project-local one of these for development. You could even have more than one, if that's your thing. At application initialization, the maps are then read in, merged and made available to your application exactly like weavejester's environ that you mentioned. environ already handles leiningen profiles for things like AWS access keys which might be annoying to duplicate across all of your projects in development, and such a system as I've described would fit in fairly naturally with environ. In any event, I hadn't found that project yet, but I definitely plan to use it now. Thanks for pointing it out! On Sat, Sep 7, 2013 at 11:53 PM, Alexandr Kurilin al...@frontrowed.comjavascript: wrote: I'm curious to find out how you folks decided to organize configuration for your Ring applications, assuming you also use configuration management like Puppet/Ansiblet etc to deploy them. So far I've been using a combination of daemontools' envdir (through runit) + weavejester's environ for things like db address, db password, cookie secret keys, logging level etc. Each one is an individual file in root-only folder that runit envdirs from. I honestly can't decide whether a single configuration file (YAML, EDN, whatever) would be more appropriate for this scenario or if I should go ahead and continue keeping each configuration value in its own file and use env to load them. What are people's thoughts on this? Any reason why one or the other would be better, or is there an even better option out there I'm not considering? -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: Current state of the art in Web deployment?
Hi John, Building on Ray's answer to use Upstart, I've recently started using a Git-based deployment method that essentially uses a Git post-receive hook to re-deploy the application with a simple git push. To set-up, create a bare repo and a working tree on the deploy host, and the relevant Upstart job. We then deploy using *`git push deployhost:path/to/deploy-repo.git master:deploy`*. When a push is received on the deploy branch, the hook on the remote repo updates the working tree, and restarts the Upstart job. (I use SystemD services in place of Upstart when I get the choice - IMO it beats Upstart hands-down, but that's an aside!) I've put the post-receive hook at https://gist.github.com/james-henderson/6263386 - hope this helps! Regards, James On Sunday, 18 August 2013 17:21:22 UTC+1, John Jacobsen wrote: Many thanks to everyone who replied about deploying a Web server to production. Specific replies: On Aug 17, 2013, at 6:51 PM, Mark Mandel mark@gmail.com javascript: wrote: On Sun, Aug 18, 2013 at 6:52 AM, John Jacobsen eigen...@gmail.comjavascript: wrote: After some prototyping and development, we are now getting to the stage where lein run and a Jetty server running from -main aren't going to cut it. At the risk of asking a dumb question, but being quite new to Clojure, I don't mind - why do you say they won't cut it? On Aug 18, 2013, at 9:25 AM, Norman Richards o...@nostacktrace.comjavascript: wrote: Other than that, mechanically our deploy is not significantly different from a lein ring server, so maybe you can explain what your concerns with that are? My main concern was just the need to ssh into the server and run leiningen in the background, as opposed to setting up a real server which starts at boot time. I'm OK w/ wrapping 'lein ring server-headless' with Apache/Nginx, if there are no known issues w/ that approach. On Aug 17, 2013, at 4:52 PM, Ray Miller r...@1729.org.uk javascript: wrote: One option is simply to write an upstart script that invokes 'lein ring server-headless' and sit an apache or nginx proxy in front of it. That's how my website is currently running. Alternatively, you could deploy your application as a war to tomcat or jetty. The upstart configuration, which is installed to /etc/init/cms.conf, can be found here: https://gist.github.com/ray1729/6258845 That's very helpful -- can you be a little more specific about what you mean by sit an apache or nginx proxy in front of it? It looks like your example is self-contained (need Clojure/lein + upstart, and that's it). Thanks again everyone. John -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: Would you please help in migrating this code from Bishop to Liberator?
For anyone stumbling upon this question - it was answered on the Liberator Github repository, at https://github.com/clojure-liberator/liberator/issues/6 James On Wednesday, 19 September 2012 14:05:08 UTC+1, Hussein B. wrote: Hi, I want to migrate this code written in Bishop REST framework to Liberator REST framework: (bishop/defresource ticket { text/html (fn [request] (let [request-method (:request-method request)] (case request-method :get (list-all-tickets request) :post (create-ticket-per-uploaded-file request } { :allowed-methods (fn [request] [:get :post]) }) I'm not really digesting the liberator approach. Thanks for help and time. -- 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