Sharing application variables

12 views
Skip to first unread message

Andrew

unread,
Sep 10, 2008, 1:51:43 AM9/10/08
to model-glue
Hi,

I currently have a web project that is structured something like this:

<CF_ROOT>/ (let's call this "app1" - it's not a model-glue app)
Application.cfc
index.cfm
etc.

<CF_ROOT>/administration/ (let's call this "app2" - this is a model-
glue MG:U app)
Application.cfc (a model glue app)
config/
controller/
views/
etc.

I have just written a caching mechanism which is put in application
scope of the "app1". What I had hoped to do was to refresh the data
when it's updated by in the administration section (ie. "app2"). But
now I've realised that app2 has a different application scope to
app1...

Is there any way for app2 to access the cache I have in app1?

I did find this suggestion via google but I'm not sure how it'll work
when I'm using MG:

http://www.bennadel.com/blog/1247-Ask-Ben-Dynamically-Executing-ColdFusion-Application-cfc-Instances.htm

Any thoughts or suggestions on how I can best tackle this problem, or
whether my architecture is just completely flawed (stupid
perhaps? :-))

Thanks,
Andrew.


Chris Peterson

unread,
Sep 10, 2008, 6:35:19 AM9/10/08
to model...@googlegroups.com
If I were you, I would make some type of event in App1 that can be requested to instruct it to 'update its cache' (however you want it to happen).  Then every time you save something in app2, just fire off a request to app1 to 'update' whatever you just saved.  You could be really granular and update individual records in cache, or simply remove the data from App1 and force it to re-load, but if you were to use app2 to make a http request to app1, then they can both maintain their own application scopes.

I have an application that is kinda like that, with the 'user' side of things and the 'admin' side both sharing an application scope w/ Transfer caching, so any changes on the admin side are instantly synced to the user side of things.  I think perhaps it would have been easier to work with to share the applications between both, but if your user side is simpler and does not require model-glue, then perhaps you made the right call. 

The other thing you could do is simply set the administration application.cfc to extend your root application.cfc.  Then they could share app scope perhaps, if your variable naming allowed that.

Just some rambling ideas, hope one of em helps =)

Chris Peterson
--
Hey! I dont tell you how to tell me what to do, so dont tell me how to do what you tell me to do! ~ Bender (Futurama)

Mike Brunt

unread,
Sep 10, 2008, 6:50:34 AM9/10/08
to model...@googlegroups.com
Andrew a quick question, specifically what variables or kind of
variables (DSN etc?) do you want to share I think that is important to
know. Also bear in mind that the internals of ModelGlue are retained
in the Application scope. What you might consider is using the Server
scope but you would have to be careful in my opinion and only put
those variables that have to be shared between CFApplications.

Kind Regards - Mike Brunt

On Wed, Sep 10, 2008 at 1:51 AM, Andrew <am2...@gmail.com> wrote:
>

--
Kind Regards - Mike Brunt
Senior Server Engineer
Cell: 562.243.6255
MSN: webap...@hotmail.com

Andrew Myers

unread,
Sep 10, 2008, 7:28:03 AM9/10/08
to model...@googlegroups.com
Hi Mike & Chris,

Thanks to you both for your suggestions.

Basically app1's application scope has an instance of a CFC which
holds a Struct which in turn will contain various frequently used
variables - they can be anything from queries to HTML fragments.

I think Chris's suggestion might be the best option without having to
entirely re-architect my application. I could probably use a cfhttp
call to a page which in turn calls a "refresh" function.

That might be the simplest way to go I think...

Andrew.

2008/9/10 Mike Brunt <go2r...@gmail.com>:

Dan Wilson

unread,
Sep 10, 2008, 8:14:24 AM9/10/08
to model...@googlegroups.com
One idea that hasn't been talked about yet is the concept of a Parent Bean Factory in ColdSpring.

As you know, your MG application instantiates a bean factory from ColdSpring. By using a Parent Bean Factory for your CS bean factories in App1 and App2, you can share instances of objects without having to try to communicate across scopes.

In a situation where the ColdSpring bean factory in your MG application has a Parent Bean Factory, dependancies are resolved by looking in the child factory first, the parent second. That means you need to create your cache object in the single Parent Bean Factory and not in either of your ModelGlue CS bean factories.

For more information on how to implement this:

Section: II.VIII Hierarchical Bean Factories

Let me know if you go this route, and I'll add more detail.


DW
--
"Come to the edge, he said. They said: We are afraid. Come to the edge, he said. They came. He pushed them and they flew."

Guillaume Apollinaire quotes

Andrew

unread,
Oct 23, 2008, 1:44:44 AM10/23/08
to model-glue
Hi Dan,

As discussed off-list I have finally decided to bite the bullet and
try this option.

However I am going to need some help with the nuts and bolts of
actually doing it.

Say I create a Bean Factory in app1 called "app1BeanFactory":

ie. Somewhere in app1:

<cfset app1BeanFactory=
createObject("component","coldspring.beans.DefaultXmlBeanFactory").init()/
>
<cfset app1BeanFactory.loadBeansFromXmlFile("/path/to/file.xml",true)/
>

Then in app2's Application.cfm do I do the same thing again?

<cfset app1BeanFactory=
createObject("component","coldspring.beans.DefaultXmlBeanFactory").init()/
>
<cfset app1BeanFactory.loadBeansFromXmlFile("/path/to/file.xml",true)/
>

Then I am going to need to do something like this, right?

<cfset app2BeanFactory.setParent(app1BeanFactory)>

But it won't be app2BeanFactory will it - what is the correct way to
reference MG's bean factory?

I hope what I'm trying to say makes sense...it's not fully clear in my
own mind yet. :-)

Andrew.

Andrew

unread,
Oct 23, 2008, 1:47:56 AM10/23/08
to model-glue

Andrew

unread,
Oct 23, 2008, 1:53:00 AM10/23/08
to model-glue
Then again, that thread is talking about having both sharing the same
Application.cfc, which is what I was trying to avoid. Or is that the
only way?

On Oct 23, 4:47 pm, Andrew <am2...@gmail.com> wrote:
> Hold that thought, I may have found the answer!
>
> http://groups.google.com.au/group/model-glue/browse_thread/thread/e2d...

Jared Rypka-Hauer

unread,
Oct 23, 2008, 3:29:24 AM10/23/08
to model...@googlegroups.com
Andrew, based on what I've read from your posts, you've got more going on here than just needing a parent bean factory.

1) Application scopes.
If you want to keep these two applications running against different application scopes, you're going to need to get sort of creative. OTOH, if you don't mind them sharing application scopes (like there's not going to be some horrendous name collision), all you really need to do is have 2 Application.cfc files, and put the administrative application where-ever you want. ColdFusion will join the application scopes together and app 2 will have access to app 1's application scope variables. I just tested it and it works. The only proviso is this: if you hit app 1 first, then onApplicationStart() for app 2 won't fire... so you'll have put something in onRequestStart() to check for something in the application scope (like application.app1inited and application.app2inited) and call onApplicationStart() manually (with the correct double if statement). I recommend doing this in each app so that it doesn't matter which one starts first, the other one will run right.

The nice thing about this approach is that ModelGlue gives you an easy way to apply a parent bean factory to the captive beanfactory instance owned by ModelGlue... just edit the index.cfm file for the MG application and uncomment the line that sets modelglue_PARENT_BEAN_FACTORY. Change it to something like this:

<cfset modelglue_PARENT_BEAN_FACTORY = application.beanfactory />

That's it, that's all. Since they're not both MG apps, there shouldn't be an issue with 2 instances of ColdSpring, the MG framework (and you can change the name of the application scope variable via index.cfm if you need to... check the comments there) and whatever else the non-MG app needs in the application scope. I can't think of any reason this won't work.

2) Different application scopes.
If you really really need this thing to work wtih different application scopes, you're going to need to do something like this in App 1's onApplicationStart():

<cfset server.apps[application.applicationname] = application>

Then in your MG app, when you need to reload the CFC in App 1's application scope, just do something like this:

<cfset server.apps.app1.constants = createObject("component","some.foo.path.to.Constants").init()>

where the string literal "constants" is replace by the actual name of the application scope variable that contains the CFC full of variables that app 1 needs. If you need to enable 2-way communication between these applications, then just add <cfset server.apps[application.applicationname] = application> to app 2's onApplicationStart() as well, so you could call things back and forth between them.

Another way to do this is to use Application.cfm with your MG app and leave off the name="" attribute. Do that, then dump the application scope. Shocking, no? Anyway, it's one way to make sure that an application has access to the application scopes of every application on the server. Great for server control apps and stuff... but at this point I don't think it works with Application.cfc (when you leave off the name, stuff gets really effed up with Application.cfc).

Anyway, just deciding to use hierarchical bean factories isn't enough for your situation... you need to either have 2 apps with the same application name or you need to provide a way for applications to cross the application scope boundaries... there's only 2 ways to do that and I've just hilited both of them. Frankly, there aren't many disadvantages either way, so I don't think either one is superior. Personally I'm always looking for opportunities to use the server scope, so I'd probably have my applications register with the server scope... but that's just me and only cuz I think it's the cooler of the 2 options. ;)

Laterz,
J

On Oct 23, 2008, at 12:44 AM, Andrew wrote:


Hi Dan,

As discussed off-list I have finally decided to bite the bullet and
try this option.

However I am going to need some help with the nuts and bolts of
actually doing it.

Say I create a Bean Factory in app1 called "app1BeanFactory":

ie. Somewhere in app1: ...

Andrew

unread,
Oct 23, 2008, 6:44:26 PM10/23/08
to model-glue
Hi Jared,

Thanks for the reply. I think I just got into the mindset that my MG
app *had* to be in a different application scope to the parent app,
but when I think about this it may not be a necessity.

It looks like I've got the parent bean factory working successfully
now, so all is good.

Thanks again to all who took the time to point me in the right
direction.

Andrew.

Brian G

unread,
Oct 24, 2008, 4:04:38 PM10/24/08
to model-glue

On Oct 23, 3:44 pm, Andrew <am2...@gmail.com> wrote:
> It looks like I've got the parent bean factory working successfully
> now, so all is good.

I'm a little late to the party and I'm not sure 100% that this would
help solve your problem but I ran into something similar this week
with trying to share the Application scope between two "logical"
applications. In my case I wanted to share the Application scope but
disable session management in one of the two logical applications.
This might be helpful:

http://www.ghidinelli.com/2008/10/24/sharing-application-scope-between-multiple-logical-applications

This is similar to Model-Glue "sub-applications" and shares some
similar issues which might also be helpful:

http://www.ghidinelli.com/2008/05/29/model-glue-sub-applications-with-coldspring-and-transfer

(pardon the code formatting on the second link; something goofy with
my code highlighting plugin...)

Cheers,


Brian

Andrew

unread,
Nov 27, 2008, 8:54:35 PM11/27/08
to model-glue
Sorry to re-open this thread but I now have another problem I need
some help with...

Just to refresh the memory my architecture now looks like this:

/root (main application - contains a ColdSpring bean factory
application.beanfactory)
/root/admin (ModelGlue application)

/root/admin/index.cfm now contains this line:

<cfset ModelGlue_PARENT_BEAN_FACTORY = application.beanfactory />

Now in my /root/admin/config/ColdSpring.xml (the "child one" in the
model glue app) I have this:

<alias alias="ormAdapter" name="ormAdapter.Transfer" />
<alias alias="ormService" name="ormService.Transfer" />
<bean id="transferConfiguration"
class="transfer.com.config.Configuration">
<constructor-arg name="datasourcePath"><value>/admin/config/
transfer/Datasource.xml</value></constructor-arg>
<constructor-arg name="configPath"><value>/admin/config/transfer/
Transfer.xml</value></constructor-arg>
<constructor-arg name="definitionPath"><value>/admin/model/data/
transfer</value></constructor-arg>
</bean>

<bean id="Transfer" factory-bean="ormService" factory-
method="getTransfer" />
<bean id="transaction" factory-bean="ormService" factory-
method="getTransaction" />

However, I now have the case where I want to use transfer outside of
the ModelGlue app. I tried putting the code above into the parent
BeanFactory (ie. /root/coldpring.xml) but it's giving the error:

There is no bean registered with the factory with the id ormService

Presumably ormService is something that MG sets up, so it is not
available in the parent.

Is my best option to create a separate transfer bean in the parent
app, and leave the ModelGlue app's ColdSpring.xml as is, or is there
some other way? Is the ormService even necessary if I don't intend to
use Scaffolds?

Sean Corfield

unread,
Nov 27, 2008, 9:05:53 PM11/27/08
to model...@googlegroups.com
On Thu, Nov 27, 2008 at 5:54 PM, Andrew <am2...@gmail.com> wrote:
> <alias alias="ormAdapter" name="ormAdapter.Transfer" />

Keep that in the child.

> <alias alias="ormService" name="ormService.Transfer" />

Change that to:

<alias alias="ormService" name="transferFactory" />

(and keep it in the child)

Then add a transferFactory bean definition to the parent XML (defined
exactly like MG's ormService.Transfer bean, just renamed). Like this:

<bean id="transferFactory" class="transfer.TransferFactory">
<constructor-arg name="configuration"><ref
bean="transferConfiguration" /></constructor-arg>
</bean>

> <bean id="transferConfiguration"
> class="transfer.com.config.Configuration">
> <constructor-arg name="datasourcePath"><value>/admin/config/
> transfer/Datasource.xml</value></constructor-arg>
> <constructor-arg name="configPath"><value>/admin/config/transfer/
> Transfer.xml</value></constructor-arg>
> <constructor-arg name="definitionPath"><value>/admin/model/data/
> transfer</value></constructor-arg>
> </bean>

Move that into the parent XML.

> <bean id="Transfer" factory-bean="ormService" factory-
> method="getTransfer" />
> <bean id="transaction" factory-bean="ormService" factory-
> method="getTransaction" />

Change "ormService" to "transferFactory" and move them into the parent XML.
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Andrew

unread,
Nov 27, 2008, 9:16:22 PM11/27/08
to model-glue
Awesome - thank you Sean!

Brian G

unread,
Nov 30, 2008, 3:58:59 PM11/30/08
to model-glue

Andrew,

In addition to Sean's advice, I have gone through a similar experience
as you and have a couple of blog posts that summarized some of the
things I have learned from multiple model-glue applications using a
single coldspring/transfer instance:

http://www.ghidinelli.com/2008/05/29/model-glue-sub-applications-with-coldspring-and-transfer

and a little more about reusing the parent beanfactory:

http://www.ghidinelli.com/2008/10/24/sharing-application-scope-between-multiple-logical-applications

Hope those help,


Brian

Andrew

unread,
Dec 9, 2008, 10:21:43 PM12/9/08
to model-glue
And now my next installment in what has proved to be a lengthy thread.

Previously I had something like this in the Application.cfm of my MG
app, to prevent anyone from accessing any of the cfms other than
index.cfm

<cfsetting showDebugOutput="false" />
<cfsilent>
<cfapplication name="app1" sessionmanagement="true"/>
<cfif right(cgi.script_name, Len("index.cfm")) NEQ "index.cfm">
<cflocation url="/app1/index.cfm" addtoken="no">
</cfif>
</cfsilent>

I'm pretty sure I don't want to move this up to the index.cfm of my
"parent" app as I want to allow access to other cfm files there.

Should I try and rework this with the whole path (eg. to stop access
to anything other than index.cfm in the "app1" directory?). Or is
there another strategy that is better?

Regards,
Andrew.
Reply all
Reply to author
Forward
0 new messages