--
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.
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.
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)
--
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.
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/
--Kurt
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/
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.
Could you break up your ColdSpring bean factory and use the parent
bean factory feature to "modulize" the ColdSpring setup?
--
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.
--
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.
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/
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.
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/
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.
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/
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/
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.
Nah - that's the opposite of what I want to do. I want to make a
"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. "
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.
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/
--
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.
That's good to know - I bet it improved startup times?
--
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.
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 - that doesn't really solve the problem where Services are taking up a lot of load time though, does it?Mark
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.
Wow, those are impressive speedups!
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)...
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.
We can load ColdSpring hundreds of times with hundreds of beans
because ColdSpring does lazy initialization.
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
That should have said 3GB (RAM of course)
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.
--
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.