Re: Lifecycle Composition

2013-10-15 Thread Murtaza Husain

Thanks Jonah.

Appreciate the reply, it was very helpful. 


On Monday, September 23, 2013 9:03:35 AM UTC+5:30, jonah wrote:
>
> Hi Murtaza,
>
> The short answer is that  it's not necessarily that there are pros or cons 
> between having components know about each other in their "constructed" vs 
> "started" forms- it's that immutability imposes limitations in the way that 
> components can maintain local references to other components in the context 
> of the composite system global state management pattern Stuart is 
> describing.
>
> If you want to use this pattern and have components that have circular 
> dependencies on each other, those components better have mutable 
> initialization operations. If they don't, the circular dependencies will 
> need to be factored out.
>
> Jonah
>
> ==
> Longer answer with an example-
>
> Stuart's original insight, documented here [1] and referenced in that post 
> has to do with keeping all global system entities- like a database 
> connection, a routing table, a cache, a configuration object, etc, anything 
> that would be a singleton in a generic java application- in a single 
> composite data structure (map, record, vector, etc) that itself can be a 
> local variable, rather than storing each component individually as a global 
> var in a namespace, as has been the informal convention in much open source 
> Clojure application code. This single composite data structure pattern 
> allows for a clean code reloads and application state reconstruction at the 
> repl, easy testability, and a host of other benefits.
>
> However, the pattern is not without its complications. Once you make a 
> commitment to working in accordance with this pattern, you run into the 
> situation where some of those individual singleton components have 
> lifecycle requirements, where after being created/constructed, they need 
> further setup to be made ready for use. A database has to be connected to. 
> A cache has to be started and given a backing store. A configuration object 
> has to be loaded with data.
>
> In that situation you then run into the problem of managing the sequencing 
> of and dependencies between those singleton lifecycle operations. Perhaps 
> the configuration object has to be loaded with data and then given to the 
> database which needs to be opened, and then the opened database connection 
> needs to be given to the cache, which fronts the database. And whatever is 
> done at initialization time to get all those components ready probably has 
> to be undone in the reverse order when the system is shutting down. 
>
> Finally, the last piece that adds complexity to the mix is immutability. 
> From an immutability perspective, the result of a lifecycle initialization 
> operation on a component should be a new version of that component- even if 
> in practice the initialization of the particular component under the covers 
> is some mutable operation. But immutability leading to the expected 
> creation of a new version creates issues when there are dependencies 
> between the components.
>
> For instance, say that the configuration object has to know about the 
> cache, because other objects expect to get the cache through configuration. 
> Then say the cache has to know about the database, because it has to know 
> about its backing store. But then the database may have to know about the 
> configuration object, because that's where it gets credentials and 
> connection URIs from.
>
> With immutability, this cyclical knowledge dependency is impossible to 
> implement, as the new instance of each individual component as it is 
> updated with the knowledge of a predecessor dependent and is initialized, 
> or "started", obviates the reference that a successor dependent was 
> initialized or "started" with. When individual component initialization is 
> a mutable operation, the cyclical update problem goes away- but there is 
> still a bit of code smell because the pattern of preserving the results of 
> what looks to be an immutable operation isn't maintained.
>
> In any event, this is what Stuart is talking about when he makes the 
> distinction between components knowing about each other in the 
> "constructed" forms- as an unconnected database, a non-started cache, etc- 
> and their "started" forms- their post-initialization state of being 
> connected to database or as a cache that is ready for work. 
>
> Hope that helps.
>
> 1. http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
>
>
>
> On Fri, Sep 20, 2013 at 1:21 PM, Murtaza Husain <
> murtaza...@sevenolives.com > wrote:
>
>> Hi,
>>
>> I am going through the blog of Stuart Sierra regarding lifecycle 
>> composition. http://stuartsierra.com/2013/09/15/lifecycle-composition
>>
>> In the end there is this para - 
>>
>> "This technique is a form of dependency injection through constructors.
>> The choice of whether to make the individual components mutable,
>> stateful objects has an impact on ho

Re: Lifecycle Composition

2013-09-22 Thread Jonah Benton
Hi Murtaza,

The short answer is that  it's not necessarily that there are pros or cons
between having components know about each other in their "constructed" vs
"started" forms- it's that immutability imposes limitations in the way that
components can maintain local references to other components in the context
of the composite system global state management pattern Stuart is
describing.

If you want to use this pattern and have components that have circular
dependencies on each other, those components better have mutable
initialization operations. If they don't, the circular dependencies will
need to be factored out.

Jonah

==
Longer answer with an example-

Stuart's original insight, documented here [1] and referenced in that post
has to do with keeping all global system entities- like a database
connection, a routing table, a cache, a configuration object, etc, anything
that would be a singleton in a generic java application- in a single
composite data structure (map, record, vector, etc) that itself can be a
local variable, rather than storing each component individually as a global
var in a namespace, as has been the informal convention in much open source
Clojure application code. This single composite data structure pattern
allows for a clean code reloads and application state reconstruction at the
repl, easy testability, and a host of other benefits.

However, the pattern is not without its complications. Once you make a
commitment to working in accordance with this pattern, you run into the
situation where some of those individual singleton components have
lifecycle requirements, where after being created/constructed, they need
further setup to be made ready for use. A database has to be connected to.
A cache has to be started and given a backing store. A configuration object
has to be loaded with data.

In that situation you then run into the problem of managing the sequencing
of and dependencies between those singleton lifecycle operations. Perhaps
the configuration object has to be loaded with data and then given to the
database which needs to be opened, and then the opened database connection
needs to be given to the cache, which fronts the database. And whatever is
done at initialization time to get all those components ready probably has
to be undone in the reverse order when the system is shutting down.

Finally, the last piece that adds complexity to the mix is immutability.
>From an immutability perspective, the result of a lifecycle initialization
operation on a component should be a new version of that component- even if
in practice the initialization of the particular component under the covers
is some mutable operation. But immutability leading to the expected
creation of a new version creates issues when there are dependencies
between the components.

For instance, say that the configuration object has to know about the
cache, because other objects expect to get the cache through configuration.
Then say the cache has to know about the database, because it has to know
about its backing store. But then the database may have to know about the
configuration object, because that's where it gets credentials and
connection URIs from.

With immutability, this cyclical knowledge dependency is impossible to
implement, as the new instance of each individual component as it is
updated with the knowledge of a predecessor dependent and is initialized,
or "started", obviates the reference that a successor dependent was
initialized or "started" with. When individual component initialization is
a mutable operation, the cyclical update problem goes away- but there is
still a bit of code smell because the pattern of preserving the results of
what looks to be an immutable operation isn't maintained.

In any event, this is what Stuart is talking about when he makes the
distinction between components knowing about each other in the
"constructed" forms- as an unconnected database, a non-started cache, etc-
and their "started" forms- their post-initialization state of being
connected to database or as a cache that is ready for work.

Hope that helps.

1. http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded



On Fri, Sep 20, 2013 at 1:21 PM, Murtaza Husain <
murtaza.hus...@sevenolives.com> wrote:

> Hi,
>
> I am going through the blog of Stuart Sierra regarding lifecycle
> composition. http://stuartsierra.com/2013/09/15/lifecycle-composition
>
> In the end there is this para -
>
> "This technique is a form of dependency injection through constructors.
> The choice of whether to make the individual components mutable,
> stateful objects has an impact on how I can use them later on. In the
> original version of this pattern using mutable objects, each component
> gets stable references to other components it depends on. In the later
> version using immutable data structures, each component gets
> references to the *constructed* versions of other components it
> depends on, but not the *starte