[ANN] com.walmartlabs/schematic 1.1.0

2018-03-30 Thread Steve Ashton
Schematic is a Clojure library which aids in assembling Component systems 
from configuration data. 

* Expects components to implement the Component/Lifecycle protocol
* Prefers pure data for declaring dependencies 
* Provides a simple mechanism for assembling/starting just a subset of 
Components
* Avoids the pattern of passing a large bag of config data through down 
through levels of Component creation functions

https://github.com/walmartlabs/schematic

This is the first public release of this library, but we've been using it 
in production systems at WalmartLabs for more than a year.

-- 
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: Kicking off a process in Compojure Defroutes / http-kit runserver

2016-02-01 Thread Steve Ashton
This sounds like a good candidate for using Component 
(https://github.com/stuartsierra/component). I would think you could create 
a component which starts the async process. That component could then be 
provided to your ring handlers, to be used during web request processing. 


On Monday, February 1, 2016 at 6:03:57 PM UTC-5, JvJ wrote:
>
> I'm working on a web app, and I'm using defroutes to define my application 
> and runserver to initialize it.  However, when run-server is called, I 
> can't find a way to run code before the app starts listening for requests.  
> I'd like to start a background async process that can interact with 
> incoming web requests.  Is there an easy way to do this using defroutes, or 
> will I have to come up with something on my own?
>
> Thanks
>

-- 
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 include ... in project.clj

2015-06-03 Thread Steve Ashton
Try:

:repositories [["..." "url"]]

-Steve

-- 
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.


map-in

2015-03-24 Thread Steve Ashton
Is there anything for map which operates like update-in and assoc-in, where 
we can call a function with the value looked up in a nested structure?

What I've come up with:
(defn map-in
  "Returns a lazy sequence consisting of the results of
  calling map on coll, for each value in the coll,
  extracting the value using keys ks, finally applying f the
  that value and args: (apply f item args)"
  [coll [& ks] f & args]
  (map (fn [item]
 (let [value (reduce #(%2 %1) item ks)]
   (apply f value args)))
   coll))

Which could then be used like:
(def customers [{:name "Alice" :address {:city "Raleigh" :state "NC"}}
{:name "Bob" :address   {:city "Seattle" :state "WA"}}])

(map-in customers [:address :state] #(-> % clojure.string/lower-case 
keyword))
=> (:nc :wa)

Just wondering if I am re-inventing something here.

Thanks,
Steve

-- 
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: Help needed with Component library

2015-02-10 Thread Steve Ashton
In main.clj, it looks like you aren't keeping a reference to the started 
app. So when you call stop, you are actually stopping the version of the 
system which doesn't have the jetty server set.

Try changing this:
(defn -main [& args]
  (component/start app)
  (component/stop app))


to this:
(defn -main [& args]
  (-> app
  (component/start)
  (component/stop)))

Now, that will immediately start then stop your app, which isn't useful in 
the long run. Here's how I've managed the system in one of my apps:
https://github.com/sashton/event-loupe/blob/master/src/clj/event_loupe/core.clj

And here is how start/stop/restart it in the repl:
https://github.com/sashton/event-loupe/blob/master/repl/user.clj




On Tuesday, February 10, 2015 at 8:35:44 AM UTC-5, Gilberto Garcia wrote:
>
> I get the same error because the key :jetty-server = nil
> so, (:jetty-server this) will return nil
> what turns into (.stop nil)
>
> note that if I print 'this' after assoc'ing :jetty-server in the start 
> lifecycle I see the jetty server associated with the key :jetty-server
>
> for some reason I'm loosing the reference for the jetty server between 
> start and stop phases.
>
> On Tue, Feb 10, 2015 at 10:35 AM, Chris Ford  > wrote:
>
>> What happens if you try:
>>
>> (.stop (:jetty-server this))
>>
>> instead of:
>>
>> (.stop jetty-server)
>>
>> I'm not at a repl right now, but maybe your stop method is closing over 
>> the value of jetty-server that's passed in when the record was constructed?
>>
>> On 10 February 2015 at 22:58, Gilberto Garcia > > wrote:
>>
>>> Here it goes https://gist.github.com/ggarciajr/e5f1c0f1072c63705ac4
>>>
>>> Note that the :jetty-server is nil and it should hold the jetty server 
>>> so it can be stopped in the stop phase.
>>>
>>> #toro_tokens_rest.components.ring.Ring{:port 3000, :database 
>>> #toro_tokens_rest.components.database.Database{:path /tmp/dev-leveldb}, 
>>> :jetty-server nil}
>>>
>>> So, I bet I'm doing something wrong.
>>>
>>>
>>> On Tue, Feb 10, 2015 at 9:45 AM, Chris Ford >> > wrote:
>>>
 Perhaps it would help if you posted a gist of the stacktrace you 
 encounter?

 On 10 February 2015 at 20:29, Gilberto Garcia >>> > wrote:

> Hi All,
>
> I'm new to clojure and I'm trying to create a simple rest api to 
> create and manages to token.
> I'm trying to use Stuart's component library but I'm having problems 
> when trying to stop a component because one of the component's map 
> attribute is nil, so, when I try to stop the jetty server I get a NPE.
>
> I bet that I'm doing something wrong and I'm failing to find what is 
> wrong due to my lack of clojure knowledge/experience.
>
> Any help is appreciated.
>
> Repo: 
> https://github.com/ggarciajr/toro-tokens-rest/tree/adding-functionality
> Branch: adding-functionality
>
> Thanks in advance
>
> -- 
> 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 
> 
> 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 
> 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 .
> 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 clo...@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+u...@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+u...@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 clo...@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+u...@googlegroups.com 
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are sub

Re: Combining reloaded workflow in web dev with dynamic var approach

2015-02-09 Thread Steve Ashton
I've had the same question. What I've come up with is to introduce a new 
middleware in the the dev-system, which wraps the both the creation of the 
app handler and calling the handler with the request map. The prod-system 
would still refer directly to a single instance of the app handler.

Now in dev-mode, on every request, a new handler is both created and 
executed. There is a potential performance impact of re-creating the app 
ring handlers, but I haven't noticed any issues yet, and this is only for 
development mode, so I'm not too concerned about it. The improved repl 
experience is valuable to me.

Using your code:

(defn app [] (app-handler
   [home-routes user-routes base-routes]
   :middleware (load-middleware)
   :ring-defaults (mk-defaults false)
   :access-rules []
   :formats [:json-kw :edn :transit-json]))

(defn dev-system []
  (component/system-map
   :web (new-web-server (env :http-port) (fn [] (fn [req] ((app) req)

(defn prod-system []
  (component/system-map
   :web (new-web-server (env :http-port) (app)))







On Sunday, February 8, 2015 at 1:37:40 PM UTC-5, Sven Richter wrote:
>
> Hi,
>
> This is something that I am struggling for some time and I still don't 
> know how to solve it.
> For dynamic reloading in web development there is this common pattern:
>
> (def app (app-handler
>[home-routes user-routes base-routes]
>:middleware (load-middleware)
>:ring-defaults (mk-defaults false)
>:access-rules []
>:formats [:json-kw :edn :transit-json]))
>
> (defn get-handler []
>   (-> #'app
>   (wrap-file "resources")
>   (wrap-file-info)))
>
>
>
> This works nice, but does not give me components. With components I would 
> do something like this:
>
> (defn app [] (app-handler
>[home-routes user-routes base-routes]
>:middleware (load-middleware)
>:ring-defaults (mk-defaults false)
>:access-rules []
>:formats [:json-kw :edn :transit-json]))
>
> (defn dev-system []
>   (component/system-map
>:web (new-web-server (env :http-port) (app)))
>
> Reloading all components takes a bit more time and ceremony than just 
> having it all reloaded by itself. (I don't wanna say it takes long, but for 
> me this are 2 keystrokes more + ~1 second wait time versus no keystrokes 
> and almost no wait time with dynamic var reloading).
>
> Is there a way to combine both approaches to get the best of both worlds?
>
> Thanks,
> Sven
>
>
>

-- 
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.


Better update function

2014-12-21 Thread Steve Ashton
I'm trying to figure out if there is a better / more concise / more generic 
way to write an update function. The data I have is a vector of maps 
containing vectors of maps. 
For example:
  [{:values [{:y 1 :x 4}{:y 2 :x 7}]}{:values [{:y 5 :x 8}]}]

The goal is to update all the :y values or all the :x values according to a 
passed-in function. As a concrete example, I'd like to invert the sign of 
all the :y values.

So here's the working function which I've come up with:

(defn update-nested-fields 
  "Updates a vector of maps containing vectors of maps"
  [col [k1 k2] f]
  (map (fn [outer-map] 
 (update-in outer-map 
[k1] 
(fn [inner-col] 
  (map
   (fn [inner-map] 
 (update-in inner-map [k2] f))   
   inner-col 
   col))

;; invert the :y values
(update-nested-fields 
 [{:values [{:y 1 :x 4}{:y 2 :x 7}]}{:values [{:y 5 :x 8}]}]
 [:values :y]
 (partial * -1))



As you can see, at a simple level it is: (map (update-in (map (update-in 
f))).

I'm really wondering if I'm missing an obvious simplification. I've tried 
to decide if a threading macro would help, but I don't see how, since the 
outer collection is provided to the outermost map function, rather than the 
inner-most function. 







-- 
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.