One app, multiple sites

30 views
Skip to first unread message

Thomas Messier

unread,
May 15, 2012, 9:40:10 AM5/15/12
to coldfu...@googlegroups.com
I'm setting up an app that runs on multiple site. So essentially, everything runs on the same code, only difference is depending on the URL it's a different site, so a few things get loaded from a different folder and the DSN is different. The rest stays the same. Right now, the way I have things done is I'm loading my bean factory (Lightwire) in the server scope. The bean factory instantiates my DAOs, and I ran into the problem of having the different DSN. It seemed to me it would be bad to just use application.dsn in the DAOs, so I had to find another way to get the DSN in there. Luckily, I have a small framework to load my objects (call it objectLoader) and inject all relationships into it, as well as provide me with an object to iterate over a recordset on a bean, kind of like the IBO concept, except the bean doesn't have the next() method, it's in a separate Iterator object that takes care of it. So what happens is the only thing I load in the application scope is objectLoader, and I pass the DSN into it. Then, every call in objectLoader call the appropriate DAO to run queries and each call (delete, update, get, getList) includes the DSN. So that way, I get to keep my DAOs in the server scope, but I don't have to pass in a DSN each time I make a call, and I don't have to hard code application.dsn inside my DAOs.

Now, however, I have another small problem. I'm starting to build some services, and they need to use objectLoader, except objectLoader is in the application scope and the services would be in the server scope (bean factory). So clearly I have an issue. I initially thought of just loading everything in the application scope in spite of the duplication, but then I checked the memory usage and I don't think that's gonna fly, there are way too many objects. So I thought maybe the way to go is to move my objectLoader to the bean factory so I can inject it into my services and then I could create some method in my base controller so that when I want to call a service, it'll run whatever call I want but automatically pass in the DSN from the application.dsn. Or would it just be easier to create some kind of façade object to access my DSN, pass it into the DAOs, and just have that façade return application.dsn? Or, finally, maybe using application.dsn from inside the DAOs wouldn't be all that bad? This is driving me nuts...

Nathan Strutz

unread,
May 16, 2012, 12:54:56 AM5/16/12
to coldfu...@googlegroups.com
Wow, see, that's a lot to take in, especially from a google group that isn't personally vested in your venture. Here's my idea.

<!--- Application.cfc --->
component {
   this.name = cgi.server_name;
   ... etc ...

Every web site now has its own unique application scope. Put your persistent objects there. Yes you've got copies of all your objects, but unless you have hundreds or thousands of objects (or sites), you should be ok. I did something like this once, but had a central database and a lookup table to note certain domains that are the same application as another domain. Worked out ok.

Maybe you ought to think of a smarter (more customized) bean factory that caches certain objects in the server, some in the application and some in the request scope, and remember which goes where. I bet you could add markings to a typical spring-beans.xml type of file to annotate the desired scope, then extend lightwire to pick up and distribute as appropriate.

There is nothing terribly wrong with <cfquery datasource="#application.dsn#">. If you need it to come from somewhere else later on, that's a pretty simple find & replace. If it causes problems, fix and refactor it, but not until it actually causes problems.

By the way congrats on having an awesome mental model of a complex application in your head. Now don't over-think what could be a simple solution.

nathan strutz
[www.dopefly.com] [hi.im/nathanstrutz] [about.me/nathanstrutz]


On Tue, May 15, 2012 at 6:40 AM, Thomas Messier <thomas....@gmail.com> wrote:
I'm setting up an app that runs on multiple site. So essentially, everything runs on the same code, only difference is depending on the URL it's a different site, so a few things get loaded from a different folder and the DSN is different. The rest stays the same. Right now, the way I have things done is I'm loading my bean factory (Lightwire) in the server scope. The bean factory instantiates my DAOs, and I ran into the problem of having the different DSN. It seemed to me it would be bad to just use application.dsn in the DAOs, so I had to find another way to get the DSN in there. Luckily, I have a small framework to load my objects (call it objectLoader) and inject all relationships into it, as well as provide me with an object to iterate over a recordset on a bean, kind of like the IBO concept, except the bean doesn't have the next() method, it's in a separate Iterator object that takes care of it. So what happens is the only thing I load in the application scope is objectLoader, and I pass the DSN into it. Then, every call in objectLoader call the appropriate DAO to run queries and each call (delete, update, get, getList) includes the DSN. So that way, I get to keep my DAOs in the server scope, but I don't have to pass in a DSN each time I make a call, and I don't have to hard code application.dsn inside my DAOs.

Now, however, I have another small problem. I'm starting to build some services, and they need to use objectLoader, except objectLoader is in the application scope and the services would be in the server scope (bean factory). So clearly I have an issue. I initially thought of just loading everything in the application scope in spite of the duplication, but then I checked the memory usage and I don't think that's gonna fly, there are way too many objects. So I thought maybe the way to go is to move my objectLoader to the bean factory so I can inject it into my services and then I could create some method in my base controller so that when I want to call a service, it'll run whatever call I want but automatically pass in the DSN from the application.dsn. Or would it just be easier to create some kind of façade object to access my DSN, pass it into the DAOs, and just have that façade return application.dsn? Or, finally, maybe using application.dsn from inside the DAOs wouldn't be all that bad? This is driving me nuts...

--
You received this message because you are subscribed to the Google Groups "Object-Oriented Programming in ColdFusion" group.
To view this discussion on the web visit https://groups.google.com/d/msg/coldfusionoo/-/j0kgoF4ARLEJ.
To post to this group, send email to coldfu...@googlegroups.com.
To unsubscribe from this group, send email to coldfusionoo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldfusionoo?hl=en.

Thomas Messier

unread,
May 16, 2012, 10:06:14 AM5/16/12
to coldfu...@googlegroups.com
I'm concerned with replicating the objects for every application because we're talking about potentially a lot of sites, and yes, there will be hundreds of (possibly approaching a thousand) objects to load. But I did take your advice on not over-thinking and just created a Datasource object with a simple getName() function that returns the dsn from the application scope. That way, if something changes, I can hopefully make the change only in that place. This way, I've been able to just move my object loader to the server scope and everything works swimmingly. Thanks for the comment, it really got me moving forward as opposed to wasting countless hours agonizing over it.


On Wednesday, May 16, 2012 12:54:56 AM UTC-4, Nathan Strutz wrote:
Wow, see, that's a lot to take in, especially from a google group that isn't personally vested in your venture. Here's my idea.

<!--- Application.cfc --->
component {
   this.name = cgi.server_name;
   ... etc ...

Every web site now has its own unique application scope. Put your persistent objects there. Yes you've got copies of all your objects, but unless you have hundreds or thousands of objects (or sites), you should be ok. I did something like this once, but had a central database and a lookup table to note certain domains that are the same application as another domain. Worked out ok.

Maybe you ought to think of a smarter (more customized) bean factory that caches certain objects in the server, some in the application and some in the request scope, and remember which goes where. I bet you could add markings to a typical spring-beans.xml type of file to annotate the desired scope, then extend lightwire to pick up and distribute as appropriate.

There is nothing terribly wrong with <cfquery datasource="#application.dsn#">. If you need it to come from somewhere else later on, that's a pretty simple find & replace. If it causes problems, fix and refactor it, but not until it actually causes problems.

By the way congrats on having an awesome mental model of a complex application in your head. Now don't over-think what could be a simple solution.

nathan strutz
[www.dopefly.com] [hi.im/nathanstrutz] [about.me/nathanstrutz]


On Tue, May 15, 2012 at 6:40 AM, Thomas Messier wrote:
I'm setting up an app that runs on multiple site. So essentially, everything runs on the same code, only difference is depending on the URL it's a different site, so a few things get loaded from a different folder and the DSN is different. The rest stays the same. Right now, the way I have things done is I'm loading my bean factory (Lightwire) in the server scope. The bean factory instantiates my DAOs, and I ran into the problem of having the different DSN. It seemed to me it would be bad to just use application.dsn in the DAOs, so I had to find another way to get the DSN in there. Luckily, I have a small framework to load my objects (call it objectLoader) and inject all relationships into it, as well as provide me with an object to iterate over a recordset on a bean, kind of like the IBO concept, except the bean doesn't have the next() method, it's in a separate Iterator object that takes care of it. So what happens is the only thing I load in the application scope is objectLoader, and I pass the DSN into it. Then, every call in objectLoader call the appropriate DAO to run queries and each call (delete, update, get, getList) includes the DSN. So that way, I get to keep my DAOs in the server scope, but I don't have to pass in a DSN each time I make a call, and I don't have to hard code application.dsn inside my DAOs.

Now, however, I have another small problem. I'm starting to build some services, and they need to use objectLoader, except objectLoader is in the application scope and the services would be in the server scope (bean factory). So clearly I have an issue. I initially thought of just loading everything in the application scope in spite of the duplication, but then I checked the memory usage and I don't think that's gonna fly, there are way too many objects. So I thought maybe the way to go is to move my objectLoader to the bean factory so I can inject it into my services and then I could create some method in my base controller so that when I want to call a service, it'll run whatever call I want but automatically pass in the DSN from the application.dsn. Or would it just be easier to create some kind of façade object to access my DSN, pass it into the DAOs, and just have that façade return application.dsn? Or, finally, maybe using application.dsn from inside the DAOs wouldn't be all that bad? This is driving me nuts...

--
You received this message because you are subscribed to the Google Groups "Object-Oriented Programming in ColdFusion" group.
To view this discussion on the web visit https://groups.google.com/d/msg/coldfusionoo/-/j0kgoF4ARLEJ.
To post to this group, send email to coldfu...@googlegroups.com.
To unsubscribe from this group, send email to coldfusionoo+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages