Idea for Coldspring 2 - Individual Object Reload

49 views
Skip to first unread message

Dave

unread,
Sep 12, 2011, 11:51:33 PM9/12/11
to ColdSpring-Users
Mark/All,

The ability to reload an individuality singletons in Coldspring would
save man-hours of dev each month across a medium sized team.

Thought I'd run it up the flag-poll to see how possible it was with
the Coldspring 2 development.


Dave

Mark Mandel

unread,
Sep 12, 2011, 11:53:58 PM9/12/11
to coldspri...@googlegroups.com
Is the issue that you want to reload a singleton, or is this really just a symptom of the overall issue of how long it can take to reload ColdSpring entirely?

Just making sure I understand where everything is coming from.

Mark


--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.




--
E: mark....@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

cf.Objective(ANZ) + Flex - Nov 17, 18 - Melbourne Australia
http://www.cfobjective.com.au

2 Devs from Down Under Podcast

Matt Quackenbush

unread,
Sep 13, 2011, 12:00:37 AM9/13/11
to coldspri...@googlegroups.com
The problem with reloading a single object is that there could be a lot of things affected.  If any other object contains a reference to it, they would still have the old object.  There are theoretical ways around that, but I'm not convinced they'd be worth the time or effort.  Of course, Mark may thoroughly disagree.  :D

But if it's overall speed, CS2 should nicely surprise you.  :-)

Mark Mandel

unread,
Sep 13, 2011, 12:05:24 AM9/13/11
to coldspri...@googlegroups.com
Oh yeah - reloading a single object is a pain.

Really, the best way is to proxy that object, and have the proxy reload the singleton, probably on each method request. But it would need to handle dependencies injection on each round as well.

Not impossible, but a tad tricky.

Mark

Dave

unread,
Sep 13, 2011, 12:15:58 AM9/13/11
to ColdSpring-Users
Mark,

The problem is that a 1 line change in a singleton during dev time
results in minutes of Coldspring reload time.

I realise that all inbound and outbound references to the object need
to be followed, but I figure it's possible as CS needs to follow all
inbound and outbound references when building up the initial object
graph.


Dave




On Sep 13, 1:53 pm, Mark Mandel <mark.man...@gmail.com> wrote:
> Is the issue that you want to reload a singleton, or is this really just
> a symptom of the overall issue of how long it can take to reload ColdSpring
> entirely?
>
> Just making sure I understand where everything is coming from.
>
> Mark
>
>
>
>
>
>
>
>
>
> On Tue, Sep 13, 2011 at 1:51 PM, Dave <davidame...@gmail.com> wrote:
> > Mark/All,
>
> > The ability to reload an individuality singletons in Coldspring would
> > save man-hours of dev each month across a medium sized team.
>
> > Thought I'd run it up the flag-poll to see how possible it was with
> > the Coldspring 2 development.
>
> > Dave
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "ColdSpring-Users" group.
> > To post to this group, send email to coldspri...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > coldspring-use...@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/coldspring-users?hl=en.
>
> --
> E: mark.man...@gmail.com
> cf.Objective(ANZ) + Flex - Nov 17, 18 - Melbourne Australiahttp://www.cfobjective.com.au

Brian Kotek

unread,
Sep 13, 2011, 12:43:18 AM9/13/11
to coldspri...@googlegroups.com
I would argue that ColdSpring startup time wouldn't matter at all if you were just running a unit test to validate changes rather than reloading the whole app for every change.

Brian Kotek

unread,
Sep 13, 2011, 12:50:10 AM9/13/11
to coldspri...@googlegroups.com
Also, the problem is less about figuring out what to "replace" and more about the fact that anything else that has a reference to the old object is now referencing the wrong object. ColdSpring has no idea what you may have done with the object it injected. This is the reason why Spring doesn't allow this either, there's a vast number of ways this can go horribly wrong.
  

On Tue, Sep 13, 2011 at 12:15 AM, Dave <david...@gmail.com> wrote:

Mark Mandel

unread,
Sep 13, 2011, 1:05:51 AM9/13/11
to coldspri...@googlegroups.com

Dave,

What version of cf are you running?

Are you doing anything above and beyond di with cs? Is it set to autowire?

I'm amazed it's minutes, but to be honest, I've been running on cs2 for so long, I have no real basis for knowledge anymore.

Mark

Sent from my mobile doohickey.

Sean Corfield

unread,
Sep 13, 2011, 2:34:19 AM9/13/11
to coldspri...@googlegroups.com
On Mon, Sep 12, 2011 at 9:15 PM, Dave <david...@gmail.com> wrote:
> The problem is that a 1 line change in a singleton during dev time
> results in minutes of Coldspring reload time.

Minutes? Really? That makes me wonder a) how many beans you have in
your XML and b) which version of CF you're using?

My largest application has taken about 45 seconds to reload...
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Mark Mandel

unread,
Sep 13, 2011, 2:37:22 AM9/13/11
to coldspri...@googlegroups.com
Report Execution Times turned on? (only other thing I can think of)

Or, a craaazy amount of AOP.

Mark


--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.

Barney Boisvert

unread,
Sep 13, 2011, 11:40:55 AM9/13/11
to coldspri...@googlegroups.com
Do consider that bean initialization counts against "reload" time. On
our main application we have several beans which do a LOT of work
during initialization, so our spinup time for the beanfactory is about
5 minutes. If we remove those couple beans, it drops back to perhaps
40-50 seconds. So it's not just ColdSpring overhead in place.

cheers,
barneyb

> --
> You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
> To post to this group, send email to coldspri...@googlegroups.com.
> To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.
>
>

--
Barney Boisvert
bboi...@gmail.com
http://www.barneyb.com/

Dave

unread,
Sep 13, 2011, 5:09:57 PM9/13/11
to ColdSpring-Users
Thank you everyone for your replies, I will attempt to answer them all
below.

To clarify, obviously it's not CS's fault that we have large startup
times - it's a large app & some beans do a fair bit of work on statup
(eg, loading Constants from the db, loading some plugins, etc).

We are using CF8 in production, and starting to dev on CF9. Startup
times do not improve on CF9.

App stats are as follows:
CS Beans - Approx 300.
CS Config XML File - Approx 800 lines.
Mach-II split over 3 modules, 50,000 lines.
LOC - ~750,000.
*.cfc count - ~1800 files.
Transfer config file: ~3545 lines.

In dev mode, we essentially make changes and dump Coldspring/Mach-II
out of app scope. Looking @ Stack traces in FusionReactor, it appears
most of the time is spent in compiling code/autowiring.

Our main use for CS is autowiring of singletons. We don't use AOP
style coding. We use BeanInjector for a few transient objects (maybe 5
classes all up?)

We don't use Report Execution times, however on some dev machines we
might have FusionReactor and/or SeeFusion running, this does not make
a noticeable difference to startup times.

Performance of app when not reloading CS/Mach-II is acceptable.


All dev machines are relatively new - 64bit, 8 gig ram quad core
boxes.

I have access to Dynatrace for the next couple of days, so if there
are any internal CS methods that you think I should instrument to see
what's going on then let me know.



Dave






On Sep 13, 4:34 pm, Sean Corfield <seancorfi...@gmail.com> wrote:
> On Mon, Sep 12, 2011 at 9:15 PM, Dave <davidame...@gmail.com> wrote:
> > The problem is that a 1 line change in a singleton during dev time
> > results in minutes of Coldspring reload time.
>
> Minutes? Really? That makes me wonder a) how many beans you have in
> your XML and b) which version of CF you're using?
>
> My largest application has taken about 45 seconds to reload...
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
> Railo Technologies, Inc. --http://www.getrailo.com/

Kurt Wiersma

unread,
Sep 13, 2011, 5:15:45 PM9/13/11
to coldspri...@googlegroups.com
Could you break up your ColdSpring bean factory and use the parent
bean factory feature to "modulize" the ColdSpring setup?

--Kurt

Sean Corfield

unread,
Sep 13, 2011, 5:41:56 PM9/13/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 2:09 PM, Dave <david...@gmail.com> wrote:
> We are using CF8 in production, and starting to dev on CF9.  Startup
> times do not improve on CF9.

Since CF9 has so many speed improvements over CF8, this surprises me!

> App stats are as follows:
> CS Beans - Approx 300.
> CS Config XML File - Approx 800 lines.
> Mach-II split over 3 modules, 50,000 lines.
> LOC - ~750,000.
> *.cfc count - ~1800 files.
> Transfer config file: ~3545 lines.

When I was freelance I worked with several companies with large
Mach-II applications where startup/reload time was very large (five
minutes not being unheard of) but I can't remember if they were all
using ColdSpring...

> In dev mode, we essentially make changes and dump Coldspring/Mach-II
> out of app scope.  Looking @ Stack traces in FusionReactor, it appears
> most of the time is spent in compiling code/autowiring.

What is "Save class files to disk" set to in your CFIDE? Try changing
that setting and see how it affects reload time (on some systems with
CFC-heavy apps, it's faster to NOT save class files to disk because
checking timestamps on disk is a larger overhead when you have ~20,000
generated class files in one folder). With ACF, a .class file is
generated for every single function in every CFC so that cfclasses
folder fills up real fast! :)

> Performance of app when not reloading CS/Mach-II is acceptable.

Is there a way to force a reload of Mach-II without reloading CS?
(It's been a while since I worked with Mach-II so I don't remember how
it's ColdSpringPlugin works)

One client of mine made a change to Mach-II to load listeners
on-demand and that made a big difference for development work since
the overhead was spread over time (I don't know how safe that would be
in production).


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Dave

unread,
Sep 13, 2011, 6:55:56 PM9/13/11
to ColdSpring-Users
"Save class files" was enabled, I have disabled it and will see how we
go today.

No doubt there are incremental speed improvements in CF9, and startup
may be a few seconds faster in 9, however it's still really slow in
the scheme of things.

We can force the reloading of mach-ii without reloading Coldspring,
which helps if we are only editing managers/filters/etc. A change to
a factory/coldspring managed bean will mean both CS and Mach-II need
to be reloaded.

Maybe I'm being naive here - but if CS maintained a list of inbound
references for each bean as it was autowiring it, then doing a hot-
replacement of that bean would be fairly simple: create and auto-
write the new bean like BeanInjector does, iterate through each of the
inbound references calling the public setters, passing in the new
bean. You would use some sort of Builder plugin to select the bean to
re-inject, which would be passed to a web service on the app side that
had access to the beanFactory.

There would be a bunch of caveats to using this, eg won't work with
dependencies passed through constructor args, or with beanInjected
transient Objects.

However the time savings in system reloads during development would be
massive, especially because large projects tend to have large dev
teams.


Dave



















On Sep 14, 7:41 am, Sean Corfield <seancorfi...@gmail.com> wrote:
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
> Railo Technologies, Inc. --http://www.getrailo.com/

Mark Mandel

unread,
Sep 13, 2011, 7:14:36 PM9/13/11
to coldspri...@googlegroups.com
Yeah, but how do you know what things do outside of ColdSpring?

Often CS beans get injected into handlers, and CS has no knowledge of that.

Honestly, implementing a reload proxy that you can switch out for the objects you are working on seems to be the best fit as far as I can see.

The tricky bit there would be to make it mimic the type of the original bean, while still giving it access to it's own BeanDefinition, so it can wire the underlying bean whenever it reloads.

Or something like that, anyway ;o)

Mark


On Wed, Sep 14, 2011 at 8:55 AM, Dave <david...@gmail.com> wrote:
Maybe I'm being naive here - but if CS maintained a list of inbound
references for each bean as it was autowiring it, then doing a hot-
replacement of that bean would be fairly simple:  create and auto-
write the new bean like BeanInjector does, iterate through each of the
inbound references calling the public setters, passing in the new
bean.  You would use some sort of Builder plugin to select the bean to
re-inject, which would be passed to a web service on the app side that
had access to the beanFactory.



Mark Mandel

unread,
Sep 13, 2011, 7:20:45 PM9/13/11
to coldspri...@googlegroups.com
I think this idea is an awesome one.

Although, it would be the child bean factory that would need to be reloaded on each request, so you may have to move a few objects across, depending on your dependency graph.

Then you are just reloading a subset, and not the full gamut of all your beans while you develop.

Once you are done, move them back into the parent, and continue on your merry way.

Sounds good to me.

Mark



On Wed, Sep 14, 2011 at 7:15 AM, Kurt Wiersma <kwie...@gmail.com> wrote:
Could you break up your ColdSpring bean factory and use the parent
bean factory feature to "modulize" the ColdSpring setup?



--

Dave

unread,
Sep 13, 2011, 8:41:20 PM9/13/11
to ColdSpring-Users

Framework's such as Mach-II do their injection in a central location
so it would be possible to do the tracking in there, on a framework-by-
framework basis (eg, modifying ColdspringProperty.cfc).

Areas of code that arbitrary set references to singletons/cs beans
would still be problematic, and I can't see any way around that - but
I'd also question how often that is used. - Maybe a lot for some apps,
maybe not at all for others.

I like the idea of a reload proxy, but I agree that implementation
would be tricky - the goal of dynamic reload should be as friction-
less as possible - after all, it's about improving developer
productivity.

The other idea we have been kicking around is that instead of storing
hard references to singletons, we store a reference to a
serviceFactory, eg.

function getCampaignService()
{
return getServiceFactory().getService("CampaignService");
}

With ServiceFactory storing references to all other factories. I'm
not a fan of this model.


No doubt this is a tricky problem to solve with a few other people on
this thread alone mentioning massive startup times. I'm half tempted
to start hacking into CS 1.x myself to see if it's possible. The
productivity gains would be massive around here. I guess the biggest
question is how to do it without modifying the original code bases.

Just out of interest, who else would see the ability to reload an
individual bean as useful in a dev environment?


dave







On Sep 14, 9:14 am, Mark Mandel <mark.man...@gmail.com> wrote:
> Yeah, but how do you know what things do outside of ColdSpring?
>
> Often CS beans get injected into handlers, and CS has no knowledge of that.
>
> Honestly, implementing a reload proxy that you can switch out for the
> objects you are working on seems to be the best fit as far as I can see.
>
> The tricky bit there would be to make it mimic the type of the original
> bean, while still giving it access to it's own BeanDefinition, so it can
> wire the underlying bean whenever it reloads.
>
> Or something like that, anyway ;o)
>
> Mark
>
> On Wed, Sep 14, 2011 at 8:55 AM, Dave <davidame...@gmail.com> wrote:
> > Maybe I'm being naive here - but if CS maintained a list of inbound
> > references for each bean as it was autowiring it, then doing a hot-
> > replacement of that bean would be fairly simple:  create and auto-
> > write the new bean like BeanInjector does, iterate through each of the
> > inbound references calling the public setters, passing in the new
> > bean.  You would use some sort of Builder plugin to select the bean to
> > re-inject, which would be passed to a web service on the app side that
> > had access to the beanFactory.
>
> --
> E: mark.man...@gmail.com
> cf.Objective(ANZ) + Flex - Nov 17, 18 - Melbourne Australiahttp://www.cfobjective.com.au

Brian Kotek

unread,
Sep 13, 2011, 8:53:26 PM9/13/11
to coldspri...@googlegroups.com
Not sure if you missed my earlier email, but as far as I can tell, the problem is that you have to reload the entire application just to test a change to one CFC. Which is why you should be testing changes with a unit test and not recreating the entire app just to see if your last change works.

Beyond that, based on what you mentioned earlier, it looks like the bulk of your startup time is in Mach-II, not ColdSpring? I imagine a 50,000 line Mach-II config takes a long time to set up. 

Mark is, of course, free to use his time as he thinks best. But I'm afraid my take is that per-bean re-creation would not be a trivial thing to do, and would open the door to potentially hair-pulling bugs caused by references to old instances that ColdSpring has no knowledge of. The fundamentally correct solution is to create an environment where you can test changes without being forced to reload the entire application each time, which is exactly what a unit test is for. If that's not an option for you (thought I can't imagine a valid reason why), the source for ColdSpring is openly available and you're free to alter it however you wish to in order to accommodate your particular situation. There's a lot of features I would argue are much more widely desired and useful in the queue which take priority over something like this. I know that's probably not the response you'd like to hear, but it's a realistic and honest response.




--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.


Josh Nathanson

unread,
Sep 13, 2011, 8:55:09 PM9/13/11
to coldspri...@googlegroups.com
We have implemented the ServiceFactory concept you mention at my place of employ, and it works a charm.

We have a ServiceManager which recurses our Services directory on app startup, and instantiates all services into an application-scoped struct.  In the process, all the services are passed a pointer to the ServiceManager.

Then when you're in one service, and you need to access another service, you just do:

var myValue = variables.serviceManager.getService( "someOtherService" ).otherServiceMethod();

No need for Coldspring, configuration or anything.  Super lightweight and 2-second reinit.

-- Josh

--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.


Mark Mandel

unread,
Sep 13, 2011, 9:02:48 PM9/13/11
to coldspri...@googlegroups.com
Josh - that doesn't really solve the problem where Services are taking up a lot of load time though, does it?

Mark

Dave

unread,
Sep 13, 2011, 10:16:45 PM9/13/11
to ColdSpring-Users
I think I can see how this would work.

function replaceSingleton(cfcPath)
{
variables.singletons.byName[arguments.cfcPath] =
createObject(cfcPath).init(this);
}

Singletons only need a reference to ServiceManager to get to other
singletons.

replaceSingleton could be a remote method invoked by a cfBuilder
plugin.

Doesn't help with injecting singletons into unknown/untrackable
places, but certainly would speed up reload time.





On Sep 14, 11:02 am, Mark Mandel <mark.man...@gmail.com> wrote:
> Josh - that doesn't really solve the problem where Services are taking up a
> lot of load time though, does it?
>
> Mark
>
> On Wed, Sep 14, 2011 at 10:55 AM, Josh Nathanson <joshnathan...@gmail.com>wrote:
>
>
>
>
>
>
>
>
>
> > We have implemented the ServiceFactory concept you mention at my place of
> > employ, and it works a charm.
>
> > We have a ServiceManager which recurses our Services directory on app
> > startup, and instantiates all services into an application-scoped struct.
> >  In the process, all the services are passed a pointer to the
> > ServiceManager.
>
> > Then when you're in one service, and you need to access another service,
> > you just do:
>
> > var myValue = variables.serviceManager.getService( "someOtherService"
> > ).otherServiceMethod();
>
> > No need for Coldspring, configuration or anything.  Super lightweight and
> > 2-second reinit.
>
> > -- Josh
>

Dave

unread,
Sep 13, 2011, 10:37:14 PM9/13/11
to ColdSpring-Users
Reloading the app for a testing dev changes is certainly one of the
issues. We have a similar scenario when playing with break points and
debugging, or even just reproducing errors/bugs - there are many times
you need to reload/refresh an app.

In the past, we have found that problem with unit testing is that if
your testing for A,B,C, your code will pass those unit tests for A,B,C
and break on D. You end up writing at least twice as much code but
you don't get twice the benefit. Your also need to do real testing
with your real framework in place, which brings us back to the same
problem :)

Unit testing in itself becomes complex when you look at code spread in
MVC. Getting and iterating through a query in the UI will result your
execution path going through at least 4 layers.

We are currently considering modifying CS to do what we want - but I
wanted to see if the Mark/the community think it's something worth
considering for general release. It appears it's not - which I find
strange, because I'm sure that other people have apps large startup
times.


Dave

Sean Corfield

unread,
Sep 13, 2011, 10:54:33 PM9/13/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 7:37 PM, Dave <david...@gmail.com> wrote:
> In the past, we have found that problem with unit testing is that if
> your testing for A,B,C, your code will pass those unit tests for A,B,C
> and break on D.  You end up writing at least twice as much code but
> you don't get twice the benefit.  Your also need to do real testing
> with your real framework in place, which brings us back to the same
> problem :)
>
> Unit testing in itself becomes complex when you look at code spread in
> MVC.  Getting and iterating through a query in the UI will result your
> execution path going through at least 4 layers.

I'm looking forward to Brian's response to this because I know he'll
be a lot more diplomatic than my first reaction to this...


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Brian Kotek

unread,
Sep 13, 2011, 11:00:54 PM9/13/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 10:37 PM, Dave <david...@gmail.com> wrote:
Reloading the app for a testing dev changes is certainly one of the
issues.  We have a similar scenario when playing with break points and
debugging, or even just reproducing errors/bugs - there are many times
you need to reload/refresh an app.


Of course, but with unit tests the need to run, let alone reload, the entire app is much more infrequent.
 
In the past, we have found that problem with unit testing is that if
your testing for A,B,C, your code will pass those unit tests for A,B,C
and break on D.  You end up writing at least twice as much code but
you don't get twice the benefit.  

I'm not really sure what you mean by testing for A,B,C and breaking on D. As far as benefit, I've written a lot of unit tests and if it's twice as much code, you're doing something wrong. But from experience I can say that some of the main benefits are avoiding the very problem you're talking about (long startup time) and being able to run some or all of the tests at any time to confirm that things work. Over and over again. Which is a gigantic benefit in my book. 
 
Your also need to do real testing
with your real framework in place, which brings us back to the same
problem :)


I'm not sure what "real testing" is, but if you mean integration testing, that's the kind of thing Selenium and WebDriver were made for. With the bonus that you can trigger a full integration test run upon SVN checkin and/or upon build/deploy. And you can do this on a separate test server so that while it runs you can go on doing other things.
 
Unit testing in itself becomes complex when you look at code spread in
MVC.  Getting and iterating through a query in the UI will result your
execution path going through at least 4 layers.

If it goes through four layers, then it's not a unit test, it's an integration test. But whether you run this yourself of via an integration testing system like Selenium, it's still far faster and easier to test separate parts of your application in isolation. 
 

We are currently considering modifying CS to do what we want - but I
wanted to see if the Mark/the community think it's something worth
considering for general release. It appears it's not - which I find
strange, because I'm sure that other people have apps large startup
times.


Large software systems require different solutions than small ones. Put it this way: do you think Microsoft recompiles and runs all 60 million lines of code in Windows 7 every time a developer changes a class? Of course not. But that's essentially what you're saying you want to do. So something to consider is the fact that maybe your process and methodology need to change to support building a system as large as the one you're working with.

Thanks,

Brian

 

Dave

unread,
Sep 13, 2011, 11:03:15 PM9/13/11
to ColdSpring-Users
hahahah :)

Would love to be proved wrong with info on how they are used in non-
trivial applications. - IE, any references to blog posts/etc on how
people in the real world use them in Mach-II/CS applications of any
real size.




Dave


On Sep 14, 12:54 pm, Sean Corfield <seancorfi...@gmail.com> wrote:
> On Tue, Sep 13, 2011 at 7:37 PM, Dave <davidame...@gmail.com> wrote:
> > In the past, we have found that problem with unit testing is that if
> > your testing for A,B,C, your code will pass those unit tests for A,B,C
> > and break on D.  You end up writing at least twice as much code but
> > you don't get twice the benefit.  Your also need to do real testing
> > with your real framework in place, which brings us back to the same
> > problem :)
>
> > Unit testing in itself becomes complex when you look at code spread in
> > MVC.  Getting and iterating through a query in the UI will result your
> > execution path going through at least 4 layers.
>
> I'm looking forward to Brian's response to this because I know he'll
> be a lot more diplomatic than my first reaction to this...
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
> Railo Technologies, Inc. --http://www.getrailo.com/

Sean Corfield

unread,
Sep 13, 2011, 11:31:04 PM9/13/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 8:03 PM, Dave <david...@gmail.com> wrote:
> Would love to be proved wrong with info on how they are used in non-
> trivial applications. - IE, any references to blog posts/etc on how
> people in the real world use them in Mach-II/CS applications of any
> real size.

Well, at World Singles we have a pretty large ColdBox application and
close to 300 unit tests (in CFML; we have another suite of unit tests
for our Clojure code). We run that fully automated test suite in just
a few minutes - probably less time than it takes your application to
fully reload, I bet? It's also worth noting that almost every unit
test creates an instance of ColdSpring (we have about 100 beans
defined) in order to easily access fully wired components for testing
(and where needed we mock dependencies) - so we're creating hundreds
of instances of ColdSpring in just a few minutes. Hmm, do you have
ColdSpring doing lazy initialization or have you turned that off?

Of course if we're working on an individual component, we can work on
and run just the unit tests for that component until we're satisfied
it "works", then run the full suite to make sure we haven't broken
anything else.

We also have a full suite of Selenium tests which exercise most of our
application paths. That full test suite - unit + integration +
Selenium scenarios - takes about 20 minutes to run.

When we push code to our main repo, our CI server pulls the new code
and runs the full suite and notifies us if the build failed.

Build artifacts can be created and pushed directly to a target server
using a simple script. Deployment is similarly scripted, including
applying all database migrations, rebuilding and redeploying any
libraries (e.g., we effectively use maven to manage dependencies in
our Clojure code - actually Leiningen - so our deployment process can
handle all of that automatically as well which ensures we always have
the right versions of all the libraries we use on each tier).

As your code base gets larger and more complex, the only way to
overcome the problem you're seeing is to adopt unit testing in my
opinion. MVC doesn't affect unit testing because you're testing at the
component level. If you find a situation D that breaks, you don't have
enough unit test coverage so you just add more tests. When a bug is
reported, the first thing you do is create a unit test that
demonstrates the bug, so you'll know when it is fixed (the test "turns
green").


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Gavin Baumanis

unread,
Sep 13, 2011, 11:57:43 PM9/13/11
to ColdSpring-Users
Hi Dave,

On Sep 14, 12:37 pm, Dave <davidame...@gmail.com> wrote:

> You end up writing at least twice as much code but
> you don't get twice the benefit.  Your also need to do real testing
> with your real framework in place, which brings us back to the same
> problem :)

I find that the tests do consume a bit of time and line count too.
In fact, we have determined that Line count is about 1:1.

Which surprised me at first - but we later came to realise the
following "overall" benefits;
* Tests are re-runnable, as often as is required.
* Tests provide a pseudo documentation for your "real" code.
* Tests provide confidence in changes / new work.
* Tests enable you to elegantly / deliberately describe a known
problem / bug

Speaking to line count though, we have found that using TDD
specifically (almost) guarantees that the "real code" is more elegant
and succinct.
You write the simplest code possible to get the test to pass - thus
less code,
Your code is NOT over-engineered - thus less code, again

So any given solution's real-code actually contains "roughly" 50% less
lines than what we would have previously written.
So a 1:1 ratio of test code to real-code - hasn't actually increased
our "typing" workload in any measurable manner.
Plus you get all the bonus that come with having appropriate tests,
too.

(I think) Sean mentioned, that if you had tests written in the first
place - you could / would have noted your start-up times a lot sooner
and perhaps chosen a different way to architect the application - or
at the very least explored some different architectural solutions - so
as, to at least , be in a position to have - (it's not quite the
right word but I want to say "defendable" postion) - for your current
application architecture choice(s).

I am "really" into process over results.
That is to say, a well designed / peer review/ed/able process will
lend itself to ensuring repeatable, beneficial results.
So, I am quite enjoying the discussion - I am sure you're not - but
let me say that I hope you're not taking the discussion as a "Let's
bash Dave and his silly idea".

I think the real message from everyone that has contributed so far is;
"Is your proposed solution, really, going to solve your problem?
Does your problem lie, not in CS, but in the existing architecture
choices?"

And - it goes without saying - even if you come to the conclusion that
a different architecture is an answer.... just having that as an
answer does not automatically lend itself to being the "right"
solution - especially given the size / complexity you report your
application to have.

Good luck - please keep us informed of how you go, regardless of the
path.

Gavin.

Dave

unread,
Sep 14, 2011, 12:03:06 AM9/14/11
to ColdSpring-Users


Agreed that proper unit testing reduces the number of times that you
need to reload the app, however even if we were doing extensive unit
tests, then as a developer I still need to do integration testing on
my local box before check it into SVN or send it to a build server.
I still need to sit there whilst selenium loads the app for the first
time.

If I'm tracking down a bug I still need to reload the app to some well
placed PrintLN's and cfDumps through the code path. Most of the time
I still need to reload the app just to set a break point, then reload
the app again to set another break point.


"do you think Microsoft recompiles and runs all 60 million lines of
code in Windows 7 every time a developer changes a class? Of course
not. But
that's essentially what you're saying you want to do. "

Nah - that's the opposite of what I want to do. I want to make a
change to a class and have the system reload only that class. However
the model of auto-wiring beans together to form a singleton service
layer means that essentially the entire app gets reloaded when making
changes in integration testing.

OK, so that reply is a little unfair, but then again so is the
question. In the ColdSpring/mach-ii layer, you are encouraged to use
DI, ie, your managers have runtime references to your service layer,
your service layer has references to your factories and gateways.



Even if I'm in an application context where I know that only
singleton's have references to other singletons I still need to reload
(in cf, recompile) my entire app for integration testing.







On Sep 14, 1:00 pm, Brian Kotek <brian...@gmail.com> wrote:

Mark Mandel

unread,
Sep 14, 2011, 12:13:03 AM9/14/11
to coldspri...@googlegroups.com
Why would you bother replicating the work of the build server?

We have a similarly set up build system, and generally I run the unit tests locally when making a change.

Depending on what aspect I'm working on, I *may* run some specific integration tests that may be high risk.

Then I shift it off to the CI server to do the long processing. I can then continue working on whatever I want while it goes on in the background.

In fact, if I'm developing on a feature branch for some new work, I will often set up a build for that branch, so I can push most of the testing up to the CI server, and keep on going, and then get notified when stuff breaks, without having to worry about breaking other developers code.

Mark

On Wed, Sep 14, 2011 at 2:03 PM, Dave <david...@gmail.com> wrote:
Agreed that proper unit testing reduces the number of times that you
need to reload the app, however even if we were doing extensive unit
tests, then as a developer I still need to do integration testing on
my local box before check it into SVN or send it to a build server.
I still need to sit there whilst selenium loads the app for the first
time.



Dave

unread,
Sep 14, 2011, 12:33:10 AM9/14/11
to ColdSpring-Users
Sean,

OK, I'm sold on unit tests, I have been converted!

If you can create 100's of instances in Coldspring, with 100 bean's in
the time it takes me to create one instance with 300 beans, then there
must be something wrong with our coldspring config or something else
crazy that we are doing.

The only reference to Lazy-Init in our coldspring.xml file for about
10 or so beans as follows: lazy-init="false". The rest don't specify
it, nor is there a default specified.


The vast majority of our coldspring managed singletons are similar in
their integration with coldspring: They either define a constructor
with dependencies as arguments or public setters. Gateways have a
single dependency (datasource), and looking at some random service
layer objects, I'm seeing around 5-10 dependencies
for each one.


Almost all beans specify singleton-true.

Only a few have constructor-args specified.

Whilst some (4-5) singletons will do a bit of work in their
constructor, most don't & certainly not enough to account for the time
differences.


Dave




On Sep 14, 1:31 pm, Sean Corfield <seancorfi...@gmail.com> wrote:
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
> Railo Technologies, Inc. --http://www.getrailo.com/

Dave

unread,
Sep 14, 2011, 12:46:03 AM9/14/11
to ColdSpring-Users

I'm not sure we are talking about the same thing?


Lets say you need to write a config UI for something - you write some
service layer calls that use some new gateway methods are return
queries/structs/arrays/whatever though your managers, you write some
mach-ii events, you then write the UI code.

Are you saying that you don't do a refresh or view that code on your
dev machine (ie, "integration testing")? That you have a separate
server to send your code to for viewing?



Dave







On Sep 14, 2:13 pm, Mark Mandel <mark.man...@gmail.com> wrote:
> Why would you bother replicating the work of the build server?
>
> We have a similarly set up build system, and generally I run the unit tests
> locally when making a change.
>
> Depending on what aspect I'm working on, I *may* run some specific
> integration tests that may be high risk.
>
> Then I shift it off to the CI server to do the long processing. I can then
> continue working on whatever I want while it goes on in the background.
>
> In fact, if I'm developing on a feature branch for some new work, I will
> often set up a build for that branch, so I can push most of the testing up
> to the CI server, and keep on going, and then get notified when stuff
> breaks, without having to worry about breaking other developers code.
>
> Mark
>
> On Wed, Sep 14, 2011 at 2:03 PM, Dave <davidame...@gmail.com> wrote:
> > Agreed that proper unit testing reduces the number of times that you
> > need to reload the app, however even if we were doing extensive unit
> > tests, then as a developer I still need to do integration testing on
> > my local box before check it into SVN or send it to a build server.
> > I still need to sit there whilst selenium loads the app for the first
> > time.
>
> --
> E: mark.man...@gmail.com
> cf.Objective(ANZ) + Flex - Nov 17, 18 - Melbourne Australiahttp://www.cfobjective.com.au

Sean Corfield

unread,
Sep 14, 2011, 12:46:07 AM9/14/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 9:03 PM, Dave <david...@gmail.com> wrote:
> the model of auto-wiring beans together to form a singleton service
> layer means that essentially the entire app gets reloaded when making
> changes in integration testing.

ColdSpring does lazy initialization so the startup / autowire time
should be spread out - the problem is that Mach-II does eager
initialization and calls ColdSpring to get beans to autowire into
listeners. So it's actually Mach-II that is the problem here - it's
forcing everything to be loaded at startup.

As I noted, our unit test suite loads hundreds of ColdSpring factories
in a few minutes, each containing 100 beans. It works because because
ColdSpring only does what it needs to satisfy each unit test.

If Mach-II loaded listeners lazily, you'd be fine for testing small
changes because Mach-II & ColdSpring would only initialize stuff as
you needed it.

One of my clients made that modification to Mach-II to lazy load
listeners and it helped them a lot (but their dependencies were so
complex that they still had startup problems)...


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Sean Corfield

unread,
Sep 14, 2011, 12:51:14 AM9/14/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 9:46 PM, Dave <david...@gmail.com> wrote:
> Are you saying that you don't do a refresh or view that code on your
> dev machine (ie, "integration testing")? That you have a separate
> server to send your code to for viewing?

You can certainly build and test the UI working off canned data -
which lets you ensure you can test all the edge cases of the UI. Then
you can build the real back end under unit tests and be sure that it
"does the right thing". Since you wrote the canned data and the unit
tests - effectively as a specification of the interface between front
end and back end - you can definitely test these in isolation with
confidence that the whole will work... and your CI server can confirm
that for you...

Certainly at World Singles when we're building new UI stuff, we often
use fake data that provides all the richness we need. After all,
mocking the other components is how you keep control over what you're
testing.


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Brian Kotek

unread,
Sep 14, 2011, 12:53:55 AM9/14/11
to coldspri...@googlegroups.com
On Wed, Sep 14, 2011 at 12:03 AM, Dave <david...@gmail.com> wrote:


Agreed that proper unit testing reduces the number of times that you
need to reload the app, however even if we were doing extensive unit
tests, then as a developer I still need to do integration testing on
my local box before check it into SVN or send it to a build server.
I still need to sit there whilst selenium loads the app for the first
time.

No, you wouldn't. That is what a CI server is for.
 

If I'm tracking down a bug I still need to reload the app to some well
placed PrintLN's and cfDumps through the code path.  Most of the time
I still need to reload the app just to set a break point, then reload
the app again to set another break point.


Arguably, that is not true. But even if it is true in some cases, you've VASTLY reduced the number of times you need to load the app.
 

"do you think Microsoft recompiles and runs all 60 million lines of
code in Windows 7 every time a developer changes a class? Of course
not. But
that's essentially what you're saying you want to do. "

Nah - that's the opposite of what I want to do.  I want to make a
change to a class and have the system reload only that class.  

No, that's exactly what you're saying. You can't recompile one class. Well, you can in some cases, but you're missing the point. The metaphor is accurate. You don't rebuild the compiler to allow changing one class. You change your process so you don't have to compile and run everything to test one change.
 
However
the model of auto-wiring beans together to form a singleton service
layer means that essentially the entire app gets reloaded when making
changes in integration testing.

Which is something that happens once per check in. How often do you check in? Twice a day? It doesn't matter anyway, because it all happens on another machine.
 

OK, so that reply is a little unfair, but then again so is the
question.  In the ColdSpring/mach-ii layer, you are encouraged to use
DI, ie, your managers have runtime references to your service layer,
your service layer has references to your factories and gateways.


In my opinion, anyone who DOESN'T use DI is crazy. But that has nothing to do with the fact that unit testing small parts of your app would fix your problem. People using Spring on huge Java apps, or Spring.NET on huge C# apps, have the same challenge.
 

Even if I'm in an application context where I know that only
singleton's have references to other singletons I still need to reload
(in cf, recompile) my entire app for integration testing.


Yes, when you run the integration tests. Which the CI server does.
 

Brian Kotek

unread,
Sep 14, 2011, 1:11:10 AM9/14/11
to coldspri...@googlegroups.com
We may be losing the point of the original topic in all this, which was modifying ColdSpring to allow changing a bean without reloading. I think we've definitively shown why this is a bad idea:
  • It's not easy to do well, and virtually impossible to do completely
  • It can't work on beans injected via constructors
  • It opens the door to insanely complex bugs if there are references pointing at old instances of the bean 
On the other hand, with unit and integration testing you:
  • Eliminate the loading problem because you're testing individual parts of the app
  • You gain the benefit of having tests you can run over and over
  • You move the bulk of the startup overhead to a CI server
  • You end up with better code, because code that is hard to test is almost always poorly designed
It's definitely not an easy change, especially this far into the development of what sounds like a large app. Arguably this should have been considered a long time ago. But its never too late to start, and it certainly sounds like you have valid reasons to propose this sort of change to your team and manager. :-)


Matt Quackenbush

unread,
Sep 14, 2011, 1:21:47 AM9/14/11
to coldspri...@googlegroups.com
+infinity

Gavin Baumanis

unread,
Sep 14, 2011, 1:29:28 AM9/14/11
to ColdSpring-Users
Well that's the more succinct / clear version of what I posted
earlier.
(albeit, my version didn't mention CI / production deployment
concerns)

None the less - it is certainly nice to have reputable peers agree -
it adds some "stock" to the "I'm not completely looney" bucket.

Gavin.



On Sep 14, 3:11 pm, Brian Kotek <brian...@gmail.com> wrote:
> We may be losing the point of the original topic in all this, which was
> modifying ColdSpring to allow changing a bean without reloading. I think
> we've definitively shown why this is a bad idea:
>
>    - It's not easy to do well, and virtually impossible to do completely
>    - It can't work on beans injected via constructors
>    - It opens the door to insanely complex bugs if there are references
>    pointing at old instances of the bean
>
> On the other hand, with unit and integration testing you:
>
>    - Eliminate the loading problem because you're testing individual parts
>    of the app
>    - You gain the benefit of having tests you can run over and over
>    - You move the bulk of the startup overhead to a CI server
>    - You end up with better code, because code that is hard to test is

Sean Corfield

unread,
Sep 14, 2011, 1:32:23 AM9/14/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 9:33 PM, Dave <david...@gmail.com> wrote:
> If you can create 100's of instances in Coldspring, with 100 bean's in
> the time it takes me to create one instance with 300 beans, then there
> must be something wrong with our coldspring config or something else
> crazy that we are doing.

Mach-II.

We can load ColdSpring hundreds of times with hundreds of beans
because ColdSpring does lazy initialization. Mach-II does not do lazy
initialization. When you reload Mach-II, it reloads the entire world
and all 300 of your beans - which ColdSpring on its own does not do.

I can't remember whether ColdBox does lazy or eager initialization (I
suspect the former) but our app does have a noticeable startup time
and takes a while to get warmed up. FW/1 is fully lazy and the startup
time is really small, even when you reload on every request - we're
building REST APIs based on FW/1 and plan to move off ColdBox at some
point for the main app...


--
Sean A Corfield -- (904) 302-SEAN

An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Railo Technologies, Inc. -- http://www.getrailo.com/

Dan Wilson

unread,
Sep 14, 2011, 7:55:50 AM9/14/11
to coldspri...@googlegroups.com
Model Glue has switched to lazy Instantiation of controllers, event handler parsing and several other bits of deferable workload.

It was a heap of work but very much worth it.

DW

--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.




--
Plutarch - "The mind is not a vessel to be filled but a fire to be kindled."

Sean Corfield

unread,
Sep 14, 2011, 12:21:22 PM9/14/11
to coldspri...@googlegroups.com
On Wed, Sep 14, 2011 at 4:55 AM, Dan Wilson <sipa...@gmail.com> wrote:
> Model Glue has switched to lazy Instantiation of controllers, event handler
> parsing and several other bits of deferable workload.
> It was a heap of work but very much worth it.

That's good to know - I bet it improved startup times?

Dan Wilson

unread,
Sep 14, 2011, 12:22:48 PM9/14/11
to coldspri...@googlegroups.com
It did. There are some charts on this page here showing some tests we did:




DW

--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.

Kurt Wiersma

unread,
Sep 14, 2011, 12:29:17 PM9/14/11
to coldspri...@googlegroups.com
> ColdSpring does lazy initialization so the startup / autowire time
> should be spread out - the problem is that Mach-II does eager
> initialization and calls ColdSpring to get beans to autowire into
> listeners. So it's actually Mach-II that is the problem here - it's
> forcing everything to be loaded at startup.

I just want to note that this is optional and can be turned off in
Mach II's ColdSpring property config.

> If Mach-II loaded listeners lazily, you'd be fine for testing small
> changes because Mach-II & ColdSpring would only initialize stuff as
> you needed it.

Mach II 1.9 BER has lazy loading of Mach II modules. You might
consider breaking your large application up into separate CS bean
factories and potentially Mach II modules. Then you can reload each
bean factor and optionally each Mach II modules separately when needed
using the excellent Mach II Dashboard.

> One of my clients made that modification to Mach-II to lazy load
> listeners and it helped them a lot (but their dependencies were so
> complex that they still had startup problems)...

That is pretty cool, could you ask them if they would be willing to
contribute the change back to the project?

--Kurt

Josh Nathanson

unread,
Sep 14, 2011, 12:59:12 PM9/14/11
to coldspri...@googlegroups.com
On Tue, Sep 13, 2011 at 6:02 PM, Mark Mandel <mark....@gmail.com> wrote:
Josh - that doesn't really solve the problem where Services are taking up a lot of load time though, does it?

Mark



 Well, we have about 80 beans and it takes about 2 seconds to refresh them.  If we wad several hundred it would probably take a bit longer, but definitely less than the several minutes required by the OP's reinit.  The key point is that because each bean has access to any other bean, via the service manager, you don't have to deal with resolving dependencies on startup.

Of course you don't have some of the upside of CS such as AOP, but for our use case it's well worth the trade-off.

-- Josh

Dave

unread,
Sep 14, 2011, 4:25:55 PM9/14/11
to ColdSpring-Users
Thanks Brian and everyone for your input - this conversation has been
a real eye opener.

The unit/integration testing model certainly seems like a great idea.
I have forwarded the idea & this thread to the architect/ceo.

In the mean time, I'm off to write a hot-reloader :) Our dependencies
are managed by CS and we know where references to our objects are &
even though I'm solving the wrong problem in the wrong way, I can save
a massive amount of time whilst the powers that be consider changing
the dev model.


Thanks again everyone, it's been very educational.

Dave





On Sep 14, 3:11 pm, Brian Kotek <brian...@gmail.com> wrote:
> We may be losing the point of the original topic in all this, which was
> modifying ColdSpring to allow changing a bean without reloading. I think
> we've definitively shown why this is a bad idea:
>
>    - It's not easy to do well, and virtually impossible to do completely
>    - It can't work on beans injected via constructors
>    - It opens the door to insanely complex bugs if there are references
>    pointing at old instances of the bean
>
> On the other hand, with unit and integration testing you:
>
>    - Eliminate the loading problem because you're testing individual parts
>    of the app
>    - You gain the benefit of having tests you can run over and over
>    - You move the bulk of the startup overhead to a CI server
>    - You end up with better code, because code that is hard to test is

Mark Mandel

unread,
Sep 14, 2011, 5:15:27 PM9/14/11
to coldspri...@googlegroups.com

If it's any consolation, I think I've mentally worked out how to implement a ReloaderProxy via a BeanPostProcessor in CS2.

It would still mean you would have to reload your model at least once, but you would then be able to mark out the objects you were working on, and then they would reload on each request to them.

Mark

Sent from my mobile doohickey.

Sean Corfield

unread,
Sep 14, 2011, 5:47:00 PM9/14/11
to coldspri...@googlegroups.com
On Wed, Sep 14, 2011 at 9:22 AM, Dan Wilson <sipa...@gmail.com> wrote:
> It did. There are some charts on this page here showing some tests we did:
> http://www.model-glue.com/blog/index.cfm/2010/12/21/ModelGlue-32-Alpha-2

Wow, those are impressive speedups!

Sean Corfield

unread,
Sep 14, 2011, 5:51:10 PM9/14/11
to coldspri...@googlegroups.com
On Wed, Sep 14, 2011 at 9:29 AM, Kurt Wiersma <kwie...@gmail.com> wrote:
> I just want to note that this is optional and can be turned off in
> Mach II's ColdSpring property config.

So Dave might try changing that setting to see if it improves things?
Or will the all-at-once loading of listeners defeat any savings from
that?

> Mach II 1.9 BER has lazy loading of Mach II modules.

Good to know.

Give the approach taken by ColdBox (I think?), FW/1 and Model-Glue -
esp. in light of the numbers Dan shared - it seems like it would be a
good idea for Mach-II to consider lazy loading of listeners as a
whole, at least as an option?

> That is pretty cool, could you ask them if they would be willing to
> contribute the change back to the project?

Well, the company got bought and I think they rewrote all their CFML
as Java (partly due to perceived performance problems such as this?)
but I'm still in contact with some of the folks from that place so
I'll see if they can reconstruct their solution and offer it up to the
Mach-II team (or find out why they didn't in the first place)...

Dave

unread,
Sep 14, 2011, 6:41:36 PM9/14/11
to ColdSpring-Users
Sounds fantastic.

Thanks for letting me know.

Dave


On Sep 15, 7:15 am, Mark Mandel <mark.man...@gmail.com> wrote:
> If it's any consolation, I think I've mentally worked out how to implement a
> ReloaderProxy via a BeanPostProcessor in CS2.
>
> It would still mean you would have to reload your model at least once, but
> you would then be able to mark out the objects you were working on, and then
> they would reload on each request to them.
>
> Mark
>
> Sent from my mobile doohickey.

Brian Kotek

unread,
Sep 14, 2011, 6:46:37 PM9/14/11
to coldspri...@googlegroups.com
So out of curiosity, what are you doing? Wrapping all the beans in proxy classes that forward method calls to the underlying bean via OnMissingMethod? Meaning you can swap out the bean within the Proxy without changing references to the Proxy itself?

Mark Mandel

unread,
Sep 14, 2011, 8:31:09 PM9/14/11
to coldspri...@googlegroups.com
Yeah probably - like I said, it's just a mental model atm. There's no code on the page ;o)

I'd probably use the build in DynamicProxyFactory[1] that comes with CS2 to do it all though, and the BeanPostProcessor[2] could tell the InvocationHandler[3] what the underlying object was, and could wire it back up when it was reloaded. Maybe make it reload on each method request, or maybe have it have a _targetReload() method on the proxy or something (or both). Just thinking out loud at this point.

The idea being the BeanPostProcessor would look for an annotation of some kind (or target interface, or whatever), and switch out the objects that needed to be 'reloadable' with the proxies. You would still get his with the initial overhead, but you could then subsequently reload those objects over and over very easily, as they are just wrapped with a proxy.

I think the theory is sound anyway ;o) No idea about it practice.

Mark


On Thu, Sep 15, 2011 at 8:46 AM, Brian Kotek <bria...@gmail.com> wrote:
So out of curiosity, what are you doing? Wrapping all the beans in proxy classes that forward method calls to the underlying bean via OnMissingMethod? Meaning you can swap out the bean within the Proxy without changing references to the Proxy itself?

On Wed, Sep 14, 2011 at 5:15 PM, Mark Mandel <mark....@gmail.com> wrote:

If it's any consolation, I think I've mentally worked out how to implement a ReloaderProxy via a BeanPostProcessor in CS2.

It would still mean you would have to reload your model at least once, but you would then be able to mark out the objects you were working on, and then they would reload on each request to them.

Mark

Sent from my mobile doohickey.


T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

cf.Objective(ANZ) + Flex - Nov 17, 18 - Melbourne Australia
http://www.cfobjective.com.au

Mark Mandel

unread,
Sep 14, 2011, 8:37:38 PM9/14/11
to coldspri...@googlegroups.com
Just a note on this (and something I believe came up in discussion on the CS2-Dev list as well).

Singletons aren't lazy initialised, unless you specifically set them up to be. From looking at CS1.2 (and copied from Spring and therefore the same in CS2), unless you specify lazy-init="true" on the singleton, it will get loaded as soon as CS loads up.

So you may also want to look at that aspect as well.

Sean - are you setting your singletons to lazy-init="true"?

I forget as well, in CS2, you can specify a global 'default-lazy-init' on your <beans> definition. Can you do the same on CS1.2?

Mark

On Wed, Sep 14, 2011 at 3:32 PM, Sean Corfield <seanco...@gmail.com> wrote:
We can load ColdSpring hundreds of times with hundreds of beans
because ColdSpring does lazy initialization.



Dennis Clark

unread,
Sep 14, 2011, 10:17:43 PM9/14/11
to coldspri...@googlegroups.com
On 15 September 2011 07:47, Sean Corfield <seanco...@gmail.com> wrote:
> On Wed, Sep 14, 2011 at 9:22 AM, Dan Wilson <sipa...@gmail.com> wrote:
>> It did. There are some charts on this page here showing some tests we did:
>> http://www.model-glue.com/blog/index.cfm/2010/12/21/ModelGlue-32-Alpha-2
>
> Wow, those are impressive speedups!

The benefits for applications such as Dave's may be even better than
what those charts suggest.

The timing test used for those charts were focused on the framework
internals and event handlers. At the time the test did not broadcast
any controller messages or use any application-model beans so those
results do not really demonstrate the benefits for applications with
complex ColdSpring-managed models.

After those charts were done I noticed the lack of broadcasts so I
added one to the timing test, and after reading this thread I decided
to go back again and add application-model beans as well.

The latest "big" timing test contains 1000 virtually-identical event
handlers, and 1000 virtually-identical controllers each with their own
injected bean (i.e. 1000 ColdSpring model beans). None of the 1000
event handlers broadcast any messages, but there is single "broadcast"
event handler that broadcasts a single message that all 1000
controllers listen to.

In my own COMPLETELY UNSCIENTIFIC testing on my laptop
(Win7-32bit/2.2GHzCore2Duo/3MB/IIS7/JRun4/CF9.01) the application took
about 70 seconds to start up in MG 3.1, but 20 seconds to start up in
MG 3.2 RC1.

My event processing times on MG 3.2 RC1:

- Regular event: 1st request ~130ms, 2nd request ~30ms.
- Broadcast event: 1st request ~30000ms, 2nd request ~1000ms.

These results suggest that of the 50 seconds of startup time saved by
lazy loading the timing test app, roughly 30 seconds comes from not
initializing all the controllers and application beans, and the
remaining 20 seconds comes from not initializing all the event
handlers.

These improvements will be a boon for developers working MG
applications with complex ColdSpring-managed application models, as
they won't need to wait for the entire application model to be
initialized on every framework reload.

PS. This "memoization" work for Model-Glue 3.2 is also an excellent
example of the benefits of unit testing. Dan rewrote huge portions of
the loading code to get those performance improvements. The degree of
change was quite scary, but the existing unit tests allowed him to
follow a TDD approach to create to a fully functional replacement of
the legacy loading code. Once he got all the tests passing again he
asked the rest of the dev team to test it against real applications.
At the time I was supporting a fairly complex MG app which I thought
for sure would fail with Dan's new code, but lo and behold it worked
without a hitch. I'm sorry for ever doubting you Dan! :-)

-- Dennis

Dennis Clark

unread,
Sep 14, 2011, 10:19:24 PM9/14/11
to coldspri...@googlegroups.com
On 15 September 2011 12:17, Dennis Clark <boom...@gmail.com> wrote:
> In my own COMPLETELY UNSCIENTIFIC testing on my laptop
> (Win7-32bit/2.2GHzCore2Duo/3MB/IIS7/JRun4/CF9.01)

That should have said 3GB (RAM of course)

Sean Corfield

unread,
Sep 14, 2011, 10:53:48 PM9/14/11
to coldspri...@googlegroups.com
On Wed, Sep 14, 2011 at 5:37 PM, Mark Mandel <mark....@gmail.com> wrote:
> Singletons aren't lazy initialised, unless you specifically set them up to
> be. From looking at CS1.2 (and copied from Spring and therefore the same in
> CS2), unless you specify lazy-init="true" on the singleton, it will get
> loaded as soon as CS loads up.

Line 233 of DefaultXmlBeanFactory:

<cfset var default_lazyInit = "true" />

Lines 259...:

<!--- see if default-lazy-init is set to anything --->
<cfif structKeyExists(arguments.XmlBeanDefinitions.beans,'XmlAttributes')
and structKeyExists(arguments.XmlBeanDefinitions.beans.XmlAttributes,'default-lazy-init')>
<cfset default_lazyInit =
arguments.XmlBeanDefinitions.beans.XmlAttributes['default-lazy-init']/>
</cfif>

Lines 311...:

<!--- look for lazy-init for this bean def --->
<cfif StructKeyExists(beanAttributes,'lazy-init')>
<cfset lazyInit = beanAttributes["lazy-init"] />
<cfelse>
<cfset lazyInit = default_lazyInit/>
</cfif>

So, CS1.2 is lazy by default.

All the examples I've seen for CS1.2 contain lazy-init= on beans only
when it's setting it false to force initialization at startup.

> Sean - are you setting your singletons to lazy-init="true"?

No, because CS1.2 is lazy by default :)

> I forget as well, in CS2, you can specify a global 'default-lazy-init' on
> your <beans> definition. Can you do the same on CS1.2?

Yes, you can set default-lazy-init="false" to override the default
behavior - see above.

Mark Mandel

unread,
Sep 14, 2011, 11:18:12 PM9/14/11
to coldspri...@googlegroups.com
Just chatting with Sean some more.

Total egg on my face - I'm totally wrong. CS1.2 does lazy-init by default.

CS2's current default is to not lazy init (which is what Spring does). Personally I never really got that, but wanted to stay true to what Spring and (what I thought) CS1.2 was doing.

Well, I can now make that change from setLazyInit(false); to setLazyInit(true); in the code, and will push it up when it passes unit tests.

Learn something new every day!

Mark

--
You received this message because you are subscribed to the Google Groups "ColdSpring-Users" group.
To post to this group, send email to coldspri...@googlegroups.com.
To unsubscribe from this group, send email to coldspring-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldspring-users?hl=en.

Mark Mandel

unread,
Sep 15, 2011, 9:40:36 AM9/15/11
to coldspri...@googlegroups.com
Okay, CS2 now also has lazy initialisation by default as well, up on git and updated the documentation as well.

Mark
Reply all
Reply to author
Forward
0 new messages