[ANN] Shrubbery 0.4.0, a stubbing, spying, and mocking library for Clojure protocols

2016-08-22 Thread Brian Guthrie
Clojure protocols are a great way to encapsulate operations with side
effects, but suffer from a lack of general test tooling. Shrubbery provides
a small set of basic building blocks for working with them.

New in this release:

– A throws function, which returns an object suitable for use with the
stub function
that throws the named exception when invoked, as so:

(defprotocol SomeProtocol
  (explode [t]))

(let [astub (shrubbery/stub SomeProtocol
  {:explode (shrubbery/throws RuntimeException "bang")})]
  (explode astub)) ;; throws RuntimeException "bang"

What Shrubbery provides:

 * stub, which accepts a variable list of protocols and a optional hashmap
of simple value implementations and returns an object that reifies all
given protocols;
 * spy, which accepts an object with at least one protocol implementation
and returns a new implementation that tracks the number of times each of
its members were called;
 * mock, which wraps a stub in a spy, allowing callers to supply basic
function implementations and assert against those calls; and
 * calls/received?, which in conjunction with the Matcher protocol provide
a way to query spies and assert against their state.

Shrubbery is test-framework-agnostic, avoids altering runtime state to the
degree possible, and uses no macros. It supports Clojure versions 1.5-1.8;
I haven't yet tested with 1.9. It should work nicely with automated
refactoring operations like rename-function.

https://github.com/bguthrie/shrubbery

[com.gearswithingears/shrubbery "0.4.0"]


Cheers,

Brian

-- 
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] Shrubbery 0.3.0, a stubbing, spying, and mocking library for Clojure protocols

2015-10-06 Thread Brian Guthrie
On Tue, Oct 6, 2015 at 6:16 AM, Atamert Ölçgen  wrote:

> It would be great if multiple return values for multiple calls were
> supported. First use case it something like an iteration, calling some
> protocol method repeatedly (possibly with different inputs). Another use
> case is just calling it with different inputs, expecting different outputs.
> Something like (add (square x) (square y)).
>

That's an excellent suggestion; it's not something I've needed yet but it's
a common enough use-case. It should be easy enough to riff on stubs, though
trickier to set up call-based return values; I'll think on it. Thanks for
the feedback.

Cheers,

Brian

-- 
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] Shrubbery 0.3.0, a stubbing, spying, and mocking library for Clojure protocols

2015-10-05 Thread Brian Guthrie
Great to hear! Let me know if there are any questions I can answer.
Feedback gratefully accepted.

Cheers,

Brian

On Mon, Oct 5, 2015 at 11:56 AM, James Reeves  wrote:

> Very nice. I was looking for something like this.
>
> - James
>
> On 5 October 2015 at 15:14, Brian Guthrie  wrote:
>
>> Clojure protocols are a great way to encapsulate operations with side
>> effects, but suffer from a lack of general test tooling. Shrubbery provides
>> a small set of basic building blocks for working with them:
>>
>>  * stub, which accepts a variable list of protocols and a optional
>> hashmap of simple value implementations and returns an object that reifies
>> all given protocols;
>>  * spy, which accepts an object with at least one protocol
>> implementation and returns a new implementation that tracks the number of
>> times each of its members were called;
>>  * mock, which wraps a stub in a spy, allowing callers to supply basic
>> function implementations and assert against those calls; and
>>  * calls/received?, which in conjunction with the Matcher protocol
>> provide a way to query spies and assert against their state.
>>
>> Shrubbery is test-framework-agnostic, avoids altering runtime state to
>> the degree possible, and uses no macros. It should work nicely with
>> refactorings like rename-function.
>>
>> https://github.com/bguthrie/shrubbery
>>
>> [com.gearswithingears/shrubbery "0.3.0"]
>>
>>
>> New in this release:
>>
>> – Support for multiple protocols in both spies and stubs.
>> – Spies attempt to automatically derive the given implementation's
>> protocols, and tracks calls to all of them. (This behavior can be
>> overridden.)
>> – Replaced all macros with plain functions. (Unfortunately, this means
>> leaning on eval in some cases.)
>>
>> Cheers,
>>
>> Brian
>>
>> --
>> 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.
>>
>
> --
> 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.
>

-- 
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] Shrubbery 0.3.0, a stubbing, spying, and mocking library for Clojure protocols

2015-10-05 Thread Brian Guthrie
Clojure protocols are a great way to encapsulate operations with side
effects, but suffer from a lack of general test tooling. Shrubbery provides
a small set of basic building blocks for working with them:

 * stub, which accepts a variable list of protocols and a optional hashmap
of simple value implementations and returns an object that reifies all
given protocols;
 * spy, which accepts an object with at least one protocol implementation
and returns a new implementation that tracks the number of times each of
its members were called;
 * mock, which wraps a stub in a spy, allowing callers to supply basic
function implementations and assert against those calls; and
 * calls/received?, which in conjunction with the Matcher protocol provide
a way to query spies and assert against their state.

Shrubbery is test-framework-agnostic, avoids altering runtime state to the
degree possible, and uses no macros. It should work nicely with
refactorings like rename-function.

https://github.com/bguthrie/shrubbery

[com.gearswithingears/shrubbery "0.3.0"]


New in this release:

– Support for multiple protocols in both spies and stubs.
– Spies attempt to automatically derive the given implementation's
protocols, and tracks calls to all of them. (This behavior can be
overridden.)
– Replaced all macros with plain functions. (Unfortunately, this means
leaning on eval in some cases.)

Cheers,

Brian

-- 
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] Shrubbery 0.2.0, a stubbing, spying, and mocking library for Clojure protocols

2015-05-08 Thread Brian Guthrie
Clojure protocols are a great way to encapsulate operations with side
effects, but suffer from a lack of general test tooling. Shrubbery provides
a small set of basic building blocks for working with them:

 * stub, which accepts a protocol and a hashmap of functions and returns an
implementation with those functions (functions without implementations
return nil);
 * spy, which accepts a protocol and some implementation and returns a new
implementation that tracks the number of times each of its members were
called;
 * mock, which wraps a stub in a spy, allowing callers to supply basic
function implementations and assert against those calls; and
 * received?, which in conjunction with the Matcher protocol provides a way
to query spies and mocks

Shrubbery was written with clojure.test and Cursive in mind. It should work
nicely with goodies like jump-to-reference and rename-function.

Source here: https://github.com/bguthrie/shrubbery

One major caveat is that it's heavily reliant on macros; my attempts to
reify protocols programmatically didn't work out in the end. However,
Shrubbery's macros introduce no new syntax and carry no side effects.

Feedback welcome!

Cheers,

Brian

-- 
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: Programmatic reification

2015-04-24 Thread Brian Guthrie
Thanks for the advice, Timothy. I think this is probably much cleaner than
where I ended up, and good advice. I'll let you know how it goes.

On Fri, Apr 24, 2015 at 10:45 AM, Timothy Baldridge 
wrote:

> This is a situation where I reach for eval. Construct your reify call as
> if you were inside a macro, but instead of returning data from the macro,
> call (eval form). The call to reify will be slow (and could cause permgen
> problems), but if you wrap the form in a function you can cache the
> function and avoid that problem. Something like:
>
>
> (let [cache (atom {})]
>   (defn implement-at-runtime [interface-name method-name & body]
> (if-let [result (@cache [interface-name method-name body])]
>   (result)
>   (let [f (eval `(fn []
>(reify
>  ~interface-name
>  (~method-name ~@body]
> (swap! cache assoc [interface-name  method-name body] f)
> (f)
>
> @(implement-at-runtime 'clojure.lang.IDeref 'deref '[this] 42)
> ;; returns 42
>
> Timothy
>
> On Fri, Apr 24, 2015 at 8:14 AM, Steven Deobald 
> wrote:
>
>> Okay, Brian. I'll bite. :)
>>
>> I don't have the answer for you, but I'm definitely curious what your use
>> case is. Whatcha upto?
>>
>> Steven Deobald -- ⌀ -- nilenso.com
>>
>> On Fri, Apr 24, 2015 at 7:18 PM, Brian Guthrie 
>> wrote:
>>
>>> Hi all,
>>>
>>> Is there a good way to reify protocols programmatically, i.e., by
>>> passing data structures rather than dropping down into a macro? reify
>>> bottoms out in reify*, which doesn't help much.
>>>
>>> Thanks,
>>>
>>> Brian
>>>
>>> --
>>> 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.
>>>
>>
>>  --
>> 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.
>>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> 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.
>

-- 
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: Programmatic reification

2015-04-24 Thread Brian Guthrie
On Fri, Apr 24, 2015 at 3:51 PM, Timothy Baldridge 
wrote:

> This is why I like component (https://github.com/stuartsierra/component).
> The nice thing about using this library is that it encourages you to break
> your application into self-contained components. Those components must then
> communicate via protocols, and the result is a modular system that's much
> simpler to test.
>

Strongly agree. I've been making much greater use of protocols since
adopting Component on a wider scale, and that's sort of the motivation here.

Brian

-- 
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: Programmatic reification

2015-04-24 Thread Brian Guthrie
On Fri, Apr 24, 2015 at 10:14 AM, Steven Deobald  wrote:

> I don't have the answer for you, but I'm definitely curious what your use
> case is. Whatcha upto?


I've become a firm believer in using protocols to encapsulate operations
with side effects, but I don't know of any good test-framework-agnostic
mocking or stubbing frameworks that work with them. I don't care much for
interaction-based (mocking) tests anyway, really, and reification is simple
enough that I don't think sugar for stubs buys you much. But it seemed like
an open niche and a fun project. If I'm wrong and such a library does
exist, please let me know.

The library I'm working on doesn't attempt to perform any var replacements,
and it doesn't introduce any new syntax; it's simply a mechanism for
building fake versions of protocols, with full or partial implementations,
that can be passed into functions that require them, and whose state (e.g.,
the set of calls they've received) can be subsequently inspected. I'd
prefer to avoid macros entirely, except that I don't know of any other way
to reify on demand.

Release coming shortly.

Cheers,

Brian

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


Programmatic reification

2015-04-24 Thread Brian Guthrie
Hi all,

Is there a good way to reify protocols programmatically, i.e., by passing
data structures rather than dropping down into a macro? reify bottoms out
in reify*, which doesn't help much.

Thanks,

Brian

-- 
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][book] Clojure Reactive Programming

2015-03-28 Thread Brian Guthrie
Congratulations Leo! Folks, I had an opportunity to read some advance
chapters and it looked great even then. I'm really looking forward to
reading the whole thing. Well done.

On Tue, Mar 24, 2015 at 10:25 AM, Leonardo Borges <
leonardoborges...@gmail.com> wrote:

> Hi all,
>
> Some of you may know that I have been working on a book for the better
> part of last year.
>
> I'm happy to announce it has finally been published! Here's the link:
> https://www.packtpub.com/web-development/clojure-reactive-programming
>
> I hope you find it useful! I've had a great time putting it together!
>
> Cheers,
> Leonardo Borges
> www.leonardoborges.com
>
> --
> 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.
>

-- 
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: Retrieving the namespace an expression in compiled in

2014-10-24 Thread Brian Guthrie
Oopsie daisy. Sorry, James––thanks for your hard work.

On Fri, Oct 24, 2014 at 12:59 PM, Herwig Hochleitner  wrote:

> 2014-10-24 10:20 GMT+02:00 Brian Guthrie :
>
>> Depending on how deep your investment in Compojure is, I've found ...
>>
>
> I'd imagine James' investment with Compojure to be quite substantial,
> given that he is its primary author ;-)
>
> --
> 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.
>

-- 
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: Retrieving the namespace an expression in compiled in

2014-10-24 Thread Brian Guthrie
Depending on how deep your investment in Compojure is, I've found Silk's
ability to derive a path once defined (bidirectional routes) to be quite
handy and very clean. I also prefer its general philosophy, though the
library's in its early days and I haven't tested it extensively. However,
it does appear to provide a nice solution for the problem you're trying to
solve. https://github.com/DomKM/silk

On Thu, Oct 23, 2014 at 11:06 PM, James Reeves 
wrote:

> I have some code that looks like this:
>
> (ns foo.bar.endpoint.example
>   (:require [compojure.core :refer [routes GET]]
> [duct.util.resource :as resource]))
>
> (defn endpoint [config]
>   (routes
>(GET "/" []
>  (resource/url "foo/bar/endpoint/example/index.html"
>
> In this case the resource/url function acts the same as
> clojure.java.io/resource.
>
> The problem is that I'd like to remove the repetition, so I extended
> resource/url with the ability to derive the resource path from a namespace
> object.
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] (resource/url *ns* "index.html"
>
> The problem with this approach is that the *ns* binding changes, and I
> want to fix it at compile time. I could write:
>
> (def this-ns *ns*)
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] (resource/url this-ns "index.html"
>
> But it's very tempting to use the eval reader form:
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] #=(resource/url *ns* "index.html"
>
> Or a macro:
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] (resource/url (this-ns) "index.html"
>
> Alternatively, I could do something with a quoted symbol:
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] (resource/url `index ".html"
>
> Or a keyword:
>
> (defn endpoint [config]
>   (routes
>(GET "/" [] (resource/url ::index ".html"
>
> What does everything think is the best solution?
>
> I must admit I'm tempted to use the eval reader, as it makes it very
> explicit as to what's happening, while at the same time being very concise.
>
> On the other hand, the eval reader isn't often used, and isn't actually
> documented in the reader docs, just in the *read-eval* docs.
>
> - 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.
>

-- 
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] async-sockets - work with sockets using core.async channels

2014-10-07 Thread Brian Guthrie
On Mon, Oct 6, 2014 at 12:10 AM,  wrote:

> Zach makes an excellent point; I've used AsyncSocketChannels and its irk (
> http://docs.oracle.com/javase/8/docs/api/java/nio/channels/AsynchronousServerSocketChannel.html),
> with core.async in the past. Perhaps replacing your direct java.net.Sockets
> with nio classes that can be given CompletionHandlers (
> http://docs.oracle.com/javase/7/docs/api/java/nio/channels/CompletionHandler.html)
> would be a better fit.
>

Once I do some performance instrumentation I'll give that a shot. I admit
that I'm not familiar with all the implications of using the nio classes;
were I to switch, is it safe to continue using go blocks, or is it worth
explicitly allocating a single thread per socket?

Brian

-- 
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] async-sockets - work with sockets using core.async channels

2014-10-07 Thread Brian Guthrie
On Sun, Oct 5, 2014 at 11:57 PM, Zach Tellman  wrote:

> If I'm reading this correctly, you're using non-blocking thread pools for
> blocking operations on the sockets.  Given more than N connections (last
> time I looked the thread pool's size was 42), you risk deadlock or at the
> very least poor average throughput.


I'd thought the thread pool's size was a function of your core count plus
some constant, which I believe is 42. But yes, that is a constraint, and
deadlock is a risk with too many concurrent connections. I haven't tried to
measure throughput yet but that seems like a reasonable next step. Thanks
for the code review!

-- 
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] async-sockets - work with sockets using core.async channels

2014-10-05 Thread Brian Guthrie
Hi all,

I'm releasing a little library for working with sockets. Feedback and pull
requests gratefully appreciated.

The skinny
---

This library allows you to create socket servers and socket clients and
interact with them asynchronously using channels. Servers return a record
with a :connections field, a channel which yields one socket per incoming
connection. Clients return the same socket record. Socket records each have
an :in and :out channel each which allow you to receive and send data
respectively on a line-by-line basis. The raw java.net.Socket is also
available (as :socket).

Servers and clients are defined using the Component framework and must be
explicitly started using (component/start ), though
sockets will clean up after themselves if they are terminated for some
reason.

Further information is available on Github here:
https://github.com/bguthrie/async-sockets

Releases
--

This is the first release, which I've tagged for now as 0.0.1-SNAPSHOT.
Leiningen dependency: [com.gearswithingears/async-sockets "0.0.1-SNAPSHOT"].

If this is useful to you, please let me know, but any and all feedback is
great.

Happy hacking,

Brian
@bguthrie
btguth...@gmail.com

-- 
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: For async, expose the channel directly or expose a function?

2014-10-05 Thread Brian Guthrie
Fair enough. Thanks again.

On Sat, Oct 4, 2014 at 11:49 AM, Stuart Sierra 
wrote:

>
> On Sat, Oct 4, 2014 at 12:31 AM, Brian Guthrie 
> wrote:
>
>> But I'm troubled by the idea of accepting channels as arguments, even
>> though there's a lot to be said for consumer control of buffer sizes (to
>> say nothing of providing potential fakes for test purposes). In that
>> scenario you'd essentially be *mutating* the input when you set up the
>> go-loop that feeds (or takes input from) the channel, yes? So in effect
>> they become out-params.
>>
>
>
> Once you start messing around with channels, you're no longer in the
> pure-functional business. Channels aren't values. Things which use channels
> are processes, not functions.
>
> -S
>
> --
> 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.
>

-- 
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: For async, expose the channel directly or expose a function?

2014-10-03 Thread Brian Guthrie
Thanks for the feedback! I buy that direct access to the channels provides
more transformative power, so I'll stick with that. But I'm troubled by the
idea of accepting channels as arguments, even though there's a lot to be
said for consumer control of buffer sizes (to say nothing of providing
potential fakes for test purposes). In that scenario you'd essentially be
*mutating* the input when you set up the go-loop that feeds (or takes input
from) the channel, yes? So in effect they become out-params. Doable but odd.

Brian

On Fri, Oct 3, 2014 at 7:00 PM, Stuart Sierra 
wrote:

> You generally provide more power and flexibility to consumers by handing
> them channels. That way the consumer can use things like transducers and
> pipelines.
>
> For maximum flexibility, allow the consumer to *pass in* the channels to
> be used for input / output. That way the consumer gets to decide about
> buffering.
>
> -S
>
>
>
>
>  Friday, October 3, 2014 12:06:05 PM UTC-4, Brian Guthrie wrote:
>>
>> Hi all,
>>
>> I'm assembling a library for working with sockets asynchronously (both as
>> a server and a client) and was wondering if there was a widely-accepted way
>> of handling channels. The rough idea is that each socket gets two channels,
>> in and out, receiving data in the former and using the latter to write it
>> out.
>>
>> What I'm asking is whether it's preferable to set up a construction
>> function and return a record (or map) with :in and :out keys, with the
>> expectation that consumers can manipulate those channels directly, or
>> expose functions like read-line and write-line that returns a channel which
>> yields and closes once on completion.
>>
>> Essentially, it's the difference between writing:
>>
>>   (let [sock (socket-client "localhost" 1024)
>>  line (async/>   ...)
>>
>> or writing:
>>
>>   (let [sock (socket-client "localhost" 1024)
>>  line (async/>   ...)
>>
>> The disadvantage to the latter approach is that it breaks the channel
>> contract: channels should return nil on closure. With single-yield
>> channels, detecting nil closure is tiresome: you intentionally return an
>> empty channel. And though the function name is nice and clear, it seems
>> like a lot of effort to put up a nice facade, especially if folks are
>> already comfortable managing channels directly.
>>
>> Any thoughts?
>>
>> Thanks,
>>
>> Brian
>>
>  --
> 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.
>

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


For async, expose the channel directly or expose a function?

2014-10-03 Thread Brian Guthrie
Hi all,

I'm assembling a library for working with sockets asynchronously (both as a
server and a client) and was wondering if there was a widely-accepted way
of handling channels. The rough idea is that each socket gets two channels,
in and out, receiving data in the former and using the latter to write it
out.

What I'm asking is whether it's preferable to set up a construction
function and return a record (or map) with :in and :out keys, with the
expectation that consumers can manipulate those channels directly, or
expose functions like read-line and write-line that returns a channel which
yields and closes once on completion.

Essentially, it's the difference between writing:

  (let [sock (socket-client "localhost" 1024)
 line (async/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.