Re: Guidance on modelling listeners

2015-12-07 Thread Colin Yates
Thanks Jason,

I don’t particularly want dynamic registration; when the ‘world’ is 
instantiated it can now about the observers.

I could do this but it is missing the ‘filter out uninteresting events’ bit. I 
want each observer to declare its interest.

Your ‘middleware pattern’ however is something I would use to do the delegation 
(i.e. the actual glue that pushes to each interested observer) as the world 
itself shouldn’t really care.

Thanks for the thoughts - keep them coming!

> On 7 Dec 2015, at 17:15, Jason Felice  wrote:
> 
> It looks like you want dynamic registration of event handlers, which is not 
> something I've done.  If you *didn't* want that, then this the middleware 
> pattern:
> 
> (defn null-processor
>   [world event]
>   world)
> 
> (defn some-other-middleware
>   [handler]
>   (fn [world event]
>  ...
>  (handler world event)
>  ...
>  ) => world'
> 
> (def processor
>   (-> root-middleware
> some-other-middleware
> ...))
> 
> Each processor can respond to some subset of events and ignore the rest.  In 
> this case I folded "basket" into world.
> 
> I've thought a bit about making data-driven middleware and how to register or 
> deregister, but not come up with a decent solution – mostly because ordering 
> is often important.
> 
> 
> On Mon, Dec 7, 2015 at 6:01 AM, Colin Yates  > wrote:
> Hi all,
> 
> (apologies for the wall of text but I think the context might be useful)
> 
> I am using event sourcing so the world, at any given point in time is simply 
> a `reduce` over those events. Throughout the application different things are 
> interested in different events. 
> 
> A design that is emerging is the notion of a 'world' which knows how to 
> consume the various events and allows other parts of the system to respond to 
> certain states having happened. All of this is in-memory and could be client 
> or server side (yay for .cljc and ClojureScript).
> 
> In concrete terms imagine I have am modelling shopping baskets (again, all in 
> memory). I might be interested in knowing:
>  - whenever a certain item is added to a basket
>  - whenever a basket is cancelled
>  - whenever a complete basket is ordered
> 
> I could of course just filter the event log and pick out those events but I 
> typically want the entire entity _as it was when that event happened_, so the 
> event itself isn't sufficient.
> 
> My question is how best to model the 'I am interested in pre-x and post-y'. 
> In general, it is interesting to know the event, the aggregate root (shopping 
> basket) that event is associated with and the world (both the aggregate root 
> and the world as they were at the time of the event).
> 
> I could have an EventObserver: (defprotocol EventObserver  (observe [this 
> event entity world]) which the world notifies. One part of the system will 
> have one set of EventObservers, another will have a different set of 
> EventObservers. Also, some parts need to know _before_ the event and others 
> _after_ the event.
> 
> I don't want each Observer to have to specify every single event so a 
> protocol defining a pre/post method for each event wouldn't work because 
> (AFAIK) you can't have a default implementation of a protocol and you can't 
> have a partial implementation of a protocol. 
> 
> Where I am at is thinking that the world understands a map of EventObservers, 
> with one key for each pre/post event:
> 
> {:pre-event-one EventObserver :post-event-one EventObserver
>  :pre-event-two EventObserver :post-event-two EventObserver}
> 
> etc.
> 
> and each Observer can register their own map of EventObservers. I can 
> optimise the code by either having the world handle nil EventObserver or 
> having a default fully-populated map of EventObservers which Observers can 
> simple assoc their own handlers onto. 
> 
> Building the world is then trivially (usual disclaimer - hacky 
> stream-of-consciousness code):
> 
> (defn- locate-entity [world entity] ...)
> (defn- update-entity! [world entity] ...)
> 
> (defn- process-event [{:keys [observers world] :as result} event]
>   (let [pre-handler-kw (keyword (str 'pre-' (name (:event-type event
>  post-handler-kw (keyword (str 'post-' (name (:event-type event)))
>  pre-entity (locate-entity world event)
>  new-world (update-entity world entity)
>  post-entity (locate-entity new-world event]
> (do all (for [o observers
>   :let [pre-event-observer (pre-handler-kw o) 
> post-event-observer (post-handler-kw o)]]
>  (when pre-event-observer (pre-event-observer event 
> pre-entity world))
>  (when post-event-observer (post-event-observer event 
> post-entity new-world
>(assoc result :world new-world))
> 
> (defn build-world [events observers]
>   (reduce process-event {:world {} :observers observers} events))
> 
> The above code could be 

Re: Guidance on modelling listeners

2015-12-07 Thread Jason Felice
It looks like you want dynamic registration of event handlers, which is not
something I've done.  If you *didn't* want that, then this the middleware
pattern:

(defn null-processor
  [world event]
  world)

(defn some-other-middleware
  [handler]
  (fn [world event]
 ...
 (handler world event)
 ...
 ) => world'

(def processor
  (-> root-middleware
some-other-middleware
...))

Each processor can respond to some subset of events and ignore the rest.
In this case I folded "basket" into world.

I've thought a bit about making data-driven middleware and how to register
or deregister, but not come up with a decent solution – mostly because
ordering is often important.


On Mon, Dec 7, 2015 at 6:01 AM, Colin Yates  wrote:

> Hi all,
>
> (apologies for the wall of text but I think the context might be useful)
>
> I am using event sourcing so the world, at any given point in time is
> simply a `reduce` over those events. Throughout the application different
> things are interested in different events.
>
> A design that is emerging is the notion of a 'world' which knows how to
> consume the various events and allows other parts of the system to respond
> to certain states having happened. All of this is in-memory and could be
> client or server side (yay for .cljc and ClojureScript).
>
> In concrete terms imagine I have am modelling shopping baskets (again, all
> in memory). I might be interested in knowing:
>  - whenever a certain item is added to a basket
>  - whenever a basket is cancelled
>  - whenever a complete basket is ordered
>
> I could of course just filter the event log and pick out those events but
> I typically want the entire entity _as it was when that event happened_, so
> the event itself isn't sufficient.
>
> My question is how best to model the 'I am interested in pre-x and
> post-y'. In general, it is interesting to know the event, the aggregate
> root (shopping basket) that event is associated with and the world (both
> the aggregate root and the world as they were at the time of the event).
>
> I could have an EventObserver: (defprotocol EventObserver  (observe [this
> event entity world]) which the world notifies. One part of the system will
> have one set of EventObservers, another will have a different set of
> EventObservers. Also, some parts need to know _before_ the event and others
> _after_ the event.
>
> I don't want each Observer to have to specify every single event so a
> protocol defining a pre/post method for each event wouldn't work because
> (AFAIK) you can't have a default implementation of a protocol and you can't
> have a partial implementation of a protocol.
>
> Where I am at is thinking that the world understands a map of
> EventObservers, with one key for each pre/post event:
>
> {:pre-event-one EventObserver :post-event-one EventObserver
>  :pre-event-two EventObserver :post-event-two EventObserver}
>
> etc.
>
> and each Observer can register their own map of EventObservers. I can
> optimise the code by either having the world handle nil EventObserver or
> having a default fully-populated map of EventObservers which Observers can
> simple assoc their own handlers onto.
>
> Building the world is then trivially (usual disclaimer - hacky
> stream-of-consciousness code):
>
> (defn- locate-entity [world entity] ...)
> (defn- update-entity! [world entity] ...)
>
> (defn- process-event [{:keys [observers world] :as result} event]
>   (let [pre-handler-kw (keyword (str 'pre-' (name (:event-type event
>  post-handler-kw (keyword (str 'post-' (name (:event-type event)))
>  pre-entity (locate-entity world event)
>  new-world (update-entity world entity)
>  post-entity (locate-entity new-world event]
> (do all (for [o observers
>   :let [pre-event-observer (pre-handler-kw o)
> post-event-observer (post-handler-kw o)]]
>  (when pre-event-observer (pre-event-observer event
> pre-entity world))
>  (when post-event-observer (post-event-observer event
> post-entity new-world
>(assoc result :world new-world))
>
> (defn build-world [events observers]
>   (reduce process-event {:world {} :observers observers} events))
>
> The above code could be improved in a myriad of ways, but hopefully it is
> clear enough to highlight the problem: what mechanism is idiomatic in
> Clojure to implement the Observers where each Observer is interested in a
> subset of before and after a subset of events.
>
> If you are thinking 'duh, this is obvious - use X' or 'what! that's not
> true of course you can do X with protocols' then yep, I have almost
> certainly overlooked something.
>
> Finally - yeah, at times like this I really miss AOP.
>
> Thanks for still reading :-)
>
> Colin
>
>
> --
> 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 

Guidance on modelling listeners

2015-12-07 Thread Colin Yates
Hi all,

(apologies for the wall of text but I think the context might be useful)

I am using event sourcing so the world, at any given point in time is 
simply a `reduce` over those events. Throughout the application different 
things are interested in different events. 

A design that is emerging is the notion of a 'world' which knows how to 
consume the various events and allows other parts of the system to respond 
to certain states having happened. All of this is in-memory and could be 
client or server side (yay for .cljc and ClojureScript).

In concrete terms imagine I have am modelling shopping baskets (again, all 
in memory). I might be interested in knowing:
 - whenever a certain item is added to a basket
 - whenever a basket is cancelled
 - whenever a complete basket is ordered

I could of course just filter the event log and pick out those events but I 
typically want the entire entity _as it was when that event happened_, so 
the event itself isn't sufficient.

My question is how best to model the 'I am interested in pre-x and post-y'. 
In general, it is interesting to know the event, the aggregate root 
(shopping basket) that event is associated with and the world (both the 
aggregate root and the world as they were at the time of the event).

I could have an EventObserver: (defprotocol EventObserver  (observe [this 
event entity world]) which the world notifies. One part of the system will 
have one set of EventObservers, another will have a different set of 
EventObservers. Also, some parts need to know _before_ the event and others 
_after_ the event.

I don't want each Observer to have to specify every single event so a 
protocol defining a pre/post method for each event wouldn't work because 
(AFAIK) you can't have a default implementation of a protocol and you can't 
have a partial implementation of a protocol. 

Where I am at is thinking that the world understands a map of 
EventObservers, with one key for each pre/post event:

{:pre-event-one EventObserver :post-event-one EventObserver
 :pre-event-two EventObserver :post-event-two EventObserver}

etc.

and each Observer can register their own map of EventObservers. I can 
optimise the code by either having the world handle nil EventObserver or 
having a default fully-populated map of EventObservers which Observers can 
simple assoc their own handlers onto. 

Building the world is then trivially (usual disclaimer - hacky 
stream-of-consciousness code):

(defn- locate-entity [world entity] ...)
(defn- update-entity! [world entity] ...)

(defn- process-event [{:keys [observers world] :as result} event]
  (let [pre-handler-kw (keyword (str 'pre-' (name (:event-type event
 post-handler-kw (keyword (str 'post-' (name (:event-type event)))
 pre-entity (locate-entity world event)
 new-world (update-entity world entity)
 post-entity (locate-entity new-world event]
(do all (for [o observers
  :let [pre-event-observer (pre-handler-kw o) 
post-event-observer (post-handler-kw o)]]
 (when pre-event-observer (pre-event-observer event 
pre-entity world))
 (when post-event-observer (post-event-observer event 
post-entity new-world
   (assoc result :world new-world))

(defn build-world [events observers]
  (reduce process-event {:world {} :observers observers} events))

The above code could be improved in a myriad of ways, but hopefully it is 
clear enough to highlight the problem: what mechanism is idiomatic in 
Clojure to implement the Observers where each Observer is interested in a 
subset of before and after a subset of events.

If you are thinking 'duh, this is obvious - use X' or 'what! that's not 
true of course you can do X with protocols' then yep, I have almost 
certainly overlooked something.

Finally - yeah, at times like this I really miss AOP.

Thanks for still reading :-)

Colin


-- 
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: Guidance on modelling listeners

2015-12-07 Thread Colin Yates
Hiya,

I did consider (and have used) guarded visitors before but I discounted them 
because ‘action!’ ended up having the `case` statement when that visitor was 
interested in multiple events. I guess I could have one visitor per event ….

To be specific, these visitors are pure, read-only visitors - they won’t mutate 
the world they only react to specific changes in the world.

Interesting - thanks Aaron.

> On 8 Dec 2015, at 01:32, Aaron D. Valade  wrote:
> 
> What I’ve done in a similar situation is having a protocol defined like so:
> 
> (defprotocol Transition
>   (valid? [this world input] “Checks if the transition is valid for this 
> input given the state of the world”)
>   (action! [this world input] “Changes the state of the world based upon the 
> input and returns a new world state”)
> Then you can define a runner:
> 
> (defn check-transitions
>   [transitions]
>   (fn [world input]
> (let [run-t (fn [world t]
>   (if (valid? t world input)
> (action! t world input)
> world))]
>   (reduce run-t world transitions)))
> Now, just implement your transitions and then for each input you receive, run 
> it through the check-transitions function. The =valid?= predicate function is 
> called to check if the transition is interested in the input event and then 
> we only call =action!= when needed. By running a reduce, we then iterate over 
> the transitions sequentially, passing the new world state to each transition.
> 
> You could also wrap the =world= item in an atom and then change the 
> =check-transitions= into a transducer that could be the xform for a channel 
> to hook up to whatever is generating your inputs. Or even just leave the 
> =world= item as local state in a closure of the xform and just emit the new 
> worlds from the other end of the channel.
> 
> On 8 Dec 2015, at 1:19, Colin Yates wrote:
> 
> Thanks Jason,
> 
> I don’t particularly want dynamic registration; when the ‘world’ is 
> instantiated it can now about the observers.
> 
> I could do this but it is missing the ‘filter out uninteresting events’ bit. 
> I want each observer to declare its interest.
> 
> Your ‘middleware pattern’ however is something I would use to do the 
> delegation (i.e. the actual glue that pushes to each interested observer) as 
> the world itself shouldn’t really care.
> 
> Thanks for the thoughts - keep them coming!
> 
> On 7 Dec 2015, at 17:15, Jason Felice jason.m.fel...@gmail.com 
>  wrote:
> 
> It looks like you want dynamic registration of event handlers, which is not 
> something I've done. If you didn't want that, then this the middleware 
> pattern:
> 
> (defn null-processor
> [world event]
> world)
> 
> (defn some-other-middleware
> handler 
> 
> ...
> ) => world'
> 
> (def processor
> (-> root-middleware
> some-other-middleware
> ...))
> 
> Each processor can respond to some subset of events and ignore the rest. In 
> this case I folded "basket" into world.
> 
> I've thought a bit about making data-driven middleware and how to register or 
> deregister, but not come up with a decent solution – mostly because ordering 
> is often important.
> 
> On Mon, Dec 7, 2015 at 6:01 AM, Colin Yates  > wrote:
> Hi all,
> 
> (apologies for the wall of text but I think the context might be useful)
> 
> I am using event sourcing so the world, at any given point in time is simply 
> a reduce over those events. Throughout the application different things are 
> interested in different events.
> 
> A design that is emerging is the notion of a 'world' which knows how to 
> consume the various events and allows other parts of the system to respond to 
> certain states having happened. All of this is in-memory and could be client 
> or server side (yay for .cljc and ClojureScript).
> 
> In concrete terms imagine I have am modelling shopping baskets (again, all in 
> memory). I might be interested in knowing:
> - whenever a certain item is added to a basket
> - whenever a basket is cancelled
> - whenever a complete basket is ordered
> 
> I could of course just filter the event log and pick out those events but I 
> typically want the entire entity as it was when that event happened, so the 
> event itself isn't sufficient.
> 
> My question is how best to model the 'I am interested in pre-x and post-y'. 
> In general, it is interesting to know the event, the aggregate root (shopping 
> basket) that event is associated with and the world (both the aggregate root 
> and the world as they were at the time of the event).
> 
> I could have an EventObserver: (defprotocol EventObserver (observe [this 
> event entity world]) which the world notifies. One part of the system will 
> have one set of EventObservers, another will have a different set of 
> EventObservers. Also, some parts need to know before the event and others 
> after the event.
> 
> I 

Re: Guidance on modelling listeners

2015-12-07 Thread Aaron D. Valade
What I’ve done in a similar situation is having a protocol defined 
like so:


(defprotocol Transition
  (valid? [this world input] “Checks if the transition is valid 
for this input given the state of the world”)
  (action! [this world input] “Changes the state of the world 
based upon the input and returns a new world state”)


Then you can define a runner:

(defn check-transitions
  [transitions]
  (fn [world input]
(let [run-t (fn [world t]
  (if (valid? t world input)
(action! t world input)
world))]
  (reduce run-t world transitions)))

Now, just implement your transitions and then for each input you 
receive, run it through the check-transitions function.  The =valid?= 
predicate function is called to check if the transition is interested in 
the input event and then we only call =action!= when needed.  By running 
a reduce, we then iterate over the transitions sequentially, passing the 
new world state to each transition.


You could also wrap the =world= item in an atom and then change the 
=check-transitions= into a transducer that could be the xform for a 
channel to hook up to whatever is generating your inputs.  Or even just 
leave the =world= item as local state in a closure of the xform and just 
emit the new worlds from the other end of the channel.


On 8 Dec 2015, at 1:19, Colin Yates wrote:


Thanks Jason,

I don’t particularly want dynamic registration; when the ‘world’ 
is instantiated it can now about the observers.


I could do this but it is missing the ‘filter out uninteresting 
events’ bit. I want each observer to declare its interest.


Your ‘middleware pattern’ however is something I would use to do 
the delegation (i.e. the actual glue that pushes to each interested 
observer) as the world itself shouldn’t really care.


Thanks for the thoughts - keep them coming!

On 7 Dec 2015, at 17:15, Jason Felice  
wrote:


It looks like you want dynamic registration of event handlers, which 
is not something I've done.  If you *didn't* want that, then this the 
middleware pattern:


(defn null-processor
[world event]
world)

(defn some-other-middleware
[handler]
(fn [world event]
  ...
  (handler world event)
  ...
  ) => world'

(def processor
(-> root-middleware
 some-other-middleware
 ...))

Each processor can respond to some subset of events and ignore the 
rest.  In this case I folded "basket" into world.


I've thought a bit about making data-driven middleware and how to 
register or deregister, but not come up with a decent solution – 
mostly because ordering is often important.



On Mon, Dec 7, 2015 at 6:01 AM, Colin Yates > wrote:

Hi all,

(apologies for the wall of text but I think the context might be 
useful)


I am using event sourcing so the world, at any given point in time is 
simply a `reduce` over those events. Throughout the application 
different things are interested in different events.


A design that is emerging is the notion of a 'world' which knows how 
to consume the various events and allows other parts of the system to 
respond to certain states having happened. All of this is in-memory 
and could be client or server side (yay for .cljc and ClojureScript).


In concrete terms imagine I have am modelling shopping baskets 
(again, all in memory). I might be interested in knowing:

- whenever a certain item is added to a basket
- whenever a basket is cancelled
- whenever a complete basket is ordered

I could of course just filter the event log and pick out those events 
but I typically want the entire entity _as it was when that event 
happened_, so the event itself isn't sufficient.


My question is how best to model the 'I am interested in pre-x and 
post-y'. In general, it is interesting to know the event, the 
aggregate root (shopping basket) that event is associated with and 
the world (both the aggregate root and the world as they were at the 
time of the event).


I could have an EventObserver: (defprotocol EventObserver  (observe 
[this event entity world]) which the world notifies. One part of the 
system will have one set of EventObservers, another will have a 
different set of EventObservers. Also, some parts need to know 
_before_ the event and others _after_ the event.


I don't want each Observer to have to specify every single event so a 
protocol defining a pre/post method for each event wouldn't work 
because (AFAIK) you can't have a default implementation of a protocol 
and you can't have a partial implementation of a protocol.


Where I am at is thinking that the world understands a map of 
EventObservers, with one key for each pre/post event:


{:pre-event-one EventObserver :post-event-one EventObserver
:pre-event-two EventObserver :post-event-two EventObserver}

etc.

and each Observer can register their own map of EventObservers. I can 
optimise the