views:

1068

answers:

2

I have a site using CF8 and Fusebox 5. Anytime I need to add a new feature to the site, I usually have to add a new fuse to circuit.xml.cfm for either the controller, model, or view, or all. To enable these new features/pages, I go to the following url:

?fusebox.load=true&fusebox.parse=true&fusebox.password=password&fusebox.loadclean=true

The last parameter is one I recently picked up on and determined that using it would enable my new fuses; without it the new fuses are not recognized. However, when I do this, all of my parse files that were generated before are removed. This isn't much of a problem since they're regenerated on the fly when they are needed for the first time, but I have some pages that return errors when they are accessed. The error says directory not found, but they are there, each time this comes up it's because the parse file does not exist.

Here's an example of one error with the stack trace:

Error - Parsed File or Directory not found.

Date/Time: Apr 25 2009 12:26:02

Type: fusebox.missingParsedFile

Message: Parsed File or Directory not found.

Detail:

Attempting to execute the parsed file 'login.logout.cfm' threw an error. This can occur if the parsed file does not exist in the parsed directory or if the parsed directory itself is missing.
Stack Trace:
    coldfusion.runtime.CustomException: Parsed File or Directory not found.
    at coldfusion.tagext.lang.ThrowTag.doStartTag(ThrowTag.java:124)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cffusebox52ecfm1214986498.runPage(C:\example.com\fb5core\fusebox5.cfm:216)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cfindex2ecfm584653367.runPage(C:\example.com\index.cfm:3)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cfApplication2ecfc1103573364$funcONREQUEST.runFunction(C:\example.com\Application.cfc:36)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418)
    at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:360)
    at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:324)
    at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:56)
    at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:192)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:448)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:308)
    at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:74)
    at coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:243)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:269)
    at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
    at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.CfmServlet.service(CfmServlet.java:175)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
    at jrun.servlet.FilterChain.service(FilterChain.java:101)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:284)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
    at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
    at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

What I do to fix this problem is go to the following url, which is like the previous one, but without fusebox.loadclean=true:

?fusebox.password=password&fusebox.load=true&fusebox.parse=true

What I tried doing was after going to the first url, I would go to this second one, but the error still crops up.

What I'm looking for is the proper way to reload the circuits without generating these errors. I'm the third developer to get involved on this site, so the previous two may have had different styles of configuring each instance of circuit.xml.cfm. These files are used to determine the application flow of what includes are needed, additional security layers and specifying certain attributes. Here's the Fusebox method:

<!-- controller/circuit.xml.cfm -->
<circuit access="public">
 <fuseaction name="index">
  <set name="request.title" value="Account overview" />
  <do action="layout.header" />
  <do action="mdashboard.index" />
  <do action="vdashboard.index" />
  <do action="layout.footer" />
 </fuseaction>

 <fuseaction name="profile">
  <set name="request.title" value="Your Profile" />
  <do action="layout.header" />

  <!-- form submitted to the same page -->
  <if condition="isDefined('attributes.submit')">
   <true>
    <do action="mdashboard.updateprofile" />
    <do action="vdashboard.profile" />
   </true>
   <false>
    <do action="mdashboard.profile" />
    <do action="vdashboard.profile" />
   </false>
  </if>

  <do action="layout.footer" />
 </fuseaction>
</circuit>

<!-- model/circuit.xml.cfm -->
<circuit access="internal">
 <fuseaction name="index">
  <include template="sqlIndex" />
 </fuseaction>

 <fuseaction name="profile">
  <include template="sqlProfile" />
 </fuseaction>

 <fuseaction name="updateprofile">
  <include template="actUpdateProfile" />
 </fuseaction>
</circuit>

<!-- view/circuit.xml.cfm -->
<circuit access="internal">
 <fuseaction name="index">
  <include template="dspIndex" />
 </fuseaction>

 <fuseaction name="profile">
  <include template="dspProfile" />
 </fuseaction>
</circuit>

Here's the mixture of Fusebox and ColdFusion method:

<!-- controller/circuit.xml.cfm -->
<circuit access="public">
 <fuseaction name="index">
  <set name="request.title" value="Account overview" />
  <do action="layout.header" />
  <include template="ctrlIndex" />
  <do action="layout.footer" />
 </fuseaction>

 <fuseaction name="profile">
  <set name="request.title" value="Your Profile" />
  <do action="layout.header" />
  <include template="ctrlProfile" />
  <do action="layout.footer" />
 </fuseaction>
</circuit>

<!-- model/circuit.xml.cfm -->
<circuit access="internal">
</circuit>

<!-- view/circuit.xml.cfm -->
<circuit access="internal">
</circuit>

<!-- controller/ctrlProfile.cfm -->
<cfif isDefined("attributes.submit")>
 <cfinclude template="../model/actUpdateProfile.cfm">
</cfif>

<cfinclude template="../model/sqlPaymentOptions.cfm">
<cfinclude template="../view/dspPaymentOptions.cfm">

Both methods are employed throughout the site, and I'm not opposed to using either one, but my objective is to reduce any error that could come up when the user tries to access a particular page. I was thinking that maybe the problem is the mixed method of configurations, that I should stick with, say, the Fusebox method only, but I have not been able to find a common trend in this error. The error handler we have in place emails me each time a page receives an error, so I'm thinking that I could automatically call my 2nd url and redirect them back to the page that generated the error when this specific error occurs, but this has the potential for an infinite loop, and it doesn't address the real problem.

Am I going about this incorrectly? Is there set of attributes I can include in the url that will force the site to recognize new fuses without clearing my parse files? CF itself isn't difficult to code, but I'm still relatively new to it, so I could be going about this backwards. Thanks!

+2  A: 

NOTE: New fuses do not need a fusebox reload - only new fuseactions require one.

I'm not entirely certain if the errors you're getting are what I think they are, but the following is good practise regardless...

When you have made changes and need to reload fusebox, what you should do is this:

  1. Deploy the latest code to a pre-Live 'staging' area on the same server.
  2. Generate your parsed files in this area using fusebox.parseall=true and fusebox.loadclean=true
  3. Copy all files from there into your Live webroot.
  4. Perform a fusebox fusebox.load=true on the Live site - nothing else (except password).

(Note: if necessary, before step 3 set your site to offline/maintenance mode, and then after step 4 put it back online again)

Peter Boughton
That's exactly what I'm looking for. Moving my parse files from my staging to live site is a great idea. The changes I make to fuseactions on the staging site requires me to use item #2, but what about when I upload the changes to the live site? Just run fusebox.load?
Mathachew
After uploading the parsed files I mean.
Mathachew
Do not confuse "staging area" with "staging site" (i.e. testing/UAT).You should have an area *on the live server* but *outside the main webroot* where you can generate your parsed files, copy all changed files from that area to the webroot then only fusebox.load is necessary on the live site.Your staging/testing/UAT server does not enter into this process.
Peter Boughton
Sorry but I'm still a little fuzzy on the differences. I'm not accustomed to staging area and staging site (terminology and understanding the application), just live and dev (or sandbox) site. The live site and sandbox are on the same machine but in separate folders, so what you described is what would be happening when I'm ready to make my changes live. Thanks again.
Mathachew
Peter Boughton
I never did change the mode of the sandbox when I took over this project several months ago, so it's running in production mode as well. Under the circumstances in which I took this project on, I didn't set time to understand things like that. Even as a general practice I never looked into it, but it's certainly something I'm open to if it means making myself a better developer. Writing something up isn't necessary, but if you're up for the task then at least one person would appreciate it.
Mathachew
Well this is one of the many things I've been meaning to write up for a while now - you've simply given me an excuse to actually do it. :)
Peter Boughton
A: 

Is there any reason do not use fusebox.mode = "development-full-load" (set in fusebox.xml) ? This can make your live a bit easier, if you are not developing in this mode yet.

Sergii
Since he's talking about users connecting to the site, he's either live or test, not development, so should use mode="production".
Peter Boughton