Highlighted

onApplicationStart display

Explorer ,
Sep 08, 2018

Copy link to clipboard

Copied

Hi all. I am using orms, so my application takes a while to start (about 3 minutes)

I would love to be able to display something to the user - e.g., Starting xxx, please wait...

When I add a <cfoutput> as the first line of onApplicationStart (output=true), nothing displays (index.cfm is executed).

If I add <cfflush> after the <cfoutput>, message displays (index.cfm is not executed!)

Any ideas?

BKBKCharlie Arehart
thank you so much for your insight and thoughtful suggestions. I tried them, along with several other variations, and had exactly the same problems as my original post - with a new addition.

  • Either nothing displays (depending on cfflush interval)
  • Displays, but stops execution (never goes to index.cfm)
  • Or a new one - I get an error message that I'm attempting to execute a cfflush when I can't (e.g. in a cfthread)

Apparently, cold fusion isn't going to allow you to display anything until onApplicationStart is completed, although I can't even begin to understand why that is.

Rather than beat my head against the wall with CF, I decided to try something entirely different - index.html to the rescue.

  • Renamed my index.cfm to start.cfm (to avoid default page issues for the website)
  • Created index.html

index.html

<!DOCTYPE html>

<html>

<head>
</head>
<body>

<h2>Application is loading, just a moment please</h2>

<script type="text/javascript" language="javascript">

window.location = "start.cfm";

</script>

</body>

</html>


Works perfectly. HTML is displayed, and sits there until CF gets around to fulfilling the request for start.cfm

Now that the issue is solved, I can even get fancy with an animated loading image, woo hoo!

I've been working with CF since version 5, now running CF 2016.
I too was totally amazed that I couldn't find an answer to displaying a start message without asking a question, especially with the introduction of orm in CF9, which impacts onApplicationStart execution time.

FYI, I've got a real ball buster of an Application.cfc, supporting 6 separate, yet interconnected sites. I got sick of having to change the same things in all 6, so I parameterized.
Application.cfc extends ApplicationMaster.cfc, and ApplicationMaster.cfc extends ApplicationVars.cfc

Application.cfc is the a series of this.xxx = ..., same template, different values commented/uncommented for each site, and executes an appInit in ApplicationMaster, and has the onError function
ApplicationMaster.cfc and ApplicationVars.cfc are exactly the same code for all sites, making liberal use of switch statements

Perhaps something to do with my complex structure is what caused your suggestions to not work properly?

Seems like the simplest solution evaded us while we were drinking CF kool-aid.

Still curious as to why CF blocks output until onApplicationStart is finished.

Perhaps I'll play around a bit more and see if I can figure out a work-around with CF

PS - Wouldn't it be nice if there was a place to put a template in CFAdmin for this, and have CF display the template when it's starting?

Views

699

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

onApplicationStart display

Explorer ,
Sep 08, 2018

Copy link to clipboard

Copied

Hi all. I am using orms, so my application takes a while to start (about 3 minutes)

I would love to be able to display something to the user - e.g., Starting xxx, please wait...

When I add a <cfoutput> as the first line of onApplicationStart (output=true), nothing displays (index.cfm is executed).

If I add <cfflush> after the <cfoutput>, message displays (index.cfm is not executed!)

Any ideas?

BKBKCharlie Arehart
thank you so much for your insight and thoughtful suggestions. I tried them, along with several other variations, and had exactly the same problems as my original post - with a new addition.

  • Either nothing displays (depending on cfflush interval)
  • Displays, but stops execution (never goes to index.cfm)
  • Or a new one - I get an error message that I'm attempting to execute a cfflush when I can't (e.g. in a cfthread)

Apparently, cold fusion isn't going to allow you to display anything until onApplicationStart is completed, although I can't even begin to understand why that is.

Rather than beat my head against the wall with CF, I decided to try something entirely different - index.html to the rescue.

  • Renamed my index.cfm to start.cfm (to avoid default page issues for the website)
  • Created index.html

index.html

<!DOCTYPE html>

<html>

<head>
</head>
<body>

<h2>Application is loading, just a moment please</h2>

<script type="text/javascript" language="javascript">

window.location = "start.cfm";

</script>

</body>

</html>


Works perfectly. HTML is displayed, and sits there until CF gets around to fulfilling the request for start.cfm

Now that the issue is solved, I can even get fancy with an animated loading image, woo hoo!

I've been working with CF since version 5, now running CF 2016.
I too was totally amazed that I couldn't find an answer to displaying a start message without asking a question, especially with the introduction of orm in CF9, which impacts onApplicationStart execution time.

FYI, I've got a real ball buster of an Application.cfc, supporting 6 separate, yet interconnected sites. I got sick of having to change the same things in all 6, so I parameterized.
Application.cfc extends ApplicationMaster.cfc, and ApplicationMaster.cfc extends ApplicationVars.cfc

Application.cfc is the a series of this.xxx = ..., same template, different values commented/uncommented for each site, and executes an appInit in ApplicationMaster, and has the onError function
ApplicationMaster.cfc and ApplicationVars.cfc are exactly the same code for all sites, making liberal use of switch statements

Perhaps something to do with my complex structure is what caused your suggestions to not work properly?

Seems like the simplest solution evaded us while we were drinking CF kool-aid.

Still curious as to why CF blocks output until onApplicationStart is finished.

Perhaps I'll play around a bit more and see if I can figure out a work-around with CF

PS - Wouldn't it be nice if there was a place to put a template in CFAdmin for this, and have CF display the template when it's starting?

Views

700

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 08, 2018 0
Adobe Community Professional ,
Sep 09, 2018

Copy link to clipboard

Copied

Index.cfm and other CFM pages are triggered by onRequestStart, not by onApplicationStart. But onRequestStart fires much later. That explains what you observe.

I have a suggestion you may like to test. It consists of 3 files: Application.cfc, waitOnStart.cfm and index.cfm,

Points to note:

  • I have assumed you have a recent version of ColdFusion.
  • Make wait-message user-friendly by calling the application by name. In this case, EmployeeAdmin.
  • When you estimate the value of the flush interval, take one character to be worth 1 byte, including space, carriage-return and characters in HTML tags.

Application.cfc

<cfcomponent>

    <cfscript>

        this.name = "EmployeeAdmin";

        this.applicationTimeout = createTimespan(1,0,0,0);

        this.sessionManagement = "true";

        this.sessionTimeout = createTimeSpan(0,0,20,0);

    </cfscript>

    <cffunction name="onApplicationStart" returntype="boolean">

        <!--- Displays "wait" message to user --->

        <cfinclude template="waitOnStart.cfm" runonce="true">

        <cfset application.isInitiated=true>

      

        <!---

        The business code here takes several minutes.

        Simulate by a sleep of 60 seconds, for example.

        --->

        <cfset sleep(60000)>

      

        <cfreturn true>

    </cffunction>

    <cffunction name="onRequestStart">

        <cfargument name = "targetPage" type="String" required="true">

        <!--- Displaying the wait message is relevant only when application.isInitiated is true. That is, only on application start. --->

        <cfif isDefined("application.isInitiated") and application.isInitiated>

        <script type="text/javascript">

         document.getElementById('loadApplication').style.display='none';

        </script>

      

        <cfset application.isInitiated=false>

        </cfif>

      

        <cfreturn true>

    </cffunction>

</cfcomponent>

waitOnStart.cfm

<cfflush interval="90">

<p id="loadApplication">

EmployeeAdmin is starting. <br>

Please wait a few minutes.  

</p>

index.cfm

Test page. The time is: <cfoutput>#now()#</cfoutput>

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 09, 2018 2
Adobe Community Professional ,
Sep 09, 2018

Copy link to clipboard

Copied

I think solving this is going to be more complicated than that. The issue is that I'm pretty sure CF will single-thread all requests (to a given app on its first execution) waiting for the onapplicationstart to finish. So no code will run in onrequestart until then.

This is an interesting challenge, and one I'm surprised to not have seen being asked about much before.

I'd propose a variation on this code: do the actual startup of the app (the real meat in onapplicationstart) in a cfthread that is allowed to run asynchronously. And wrap the execution of that code in a test that only allows it to run once, when being initiated this way.

Then that "first" request should be allowed to "end" by showing a message saying that the app is being started, and that they should wait and try again. The same should be shown for all other requests, until the app IS loaded. After it is, then any requests should be allowed to run as normal.

To be clear, the reason for using cfthread above is so that this first requester IS allowed to end quickly reporting that the app is still loading. More important, it allows the onapplicationstart method to finish for that first request (and not hold up it or others).

Of course, the code in the cfthread would end by setting an application variable tracking that the app IS now loaded, which would be detected on subsequent requests.

As for how the code in the cfthread should "only run once", that gets tricky in that it should handle both when this is the very first initiation of the app at server startup, as well as later if something triggers another app reload. At that point it SHOULD be allowed to run again of course, though--as before--only for the first request running at that time.

Hope that may be helpful. I would love to hear if anyone either finds another resource expanding on this or if anyone takes this ball and runs with it.

Finally, someone may want to point out that there are other ways to "warm up" the app by calling it before the first user would. There are various solutions for that,  such as the onserverstart cfc feature of CF. Note that won't help if the app is released mid-day. Same if someone might propose a nightly scheduled task.

Also note that IIS 8 and above offers an optional app warmup feature that can help here. (It's not an IIS feature installed by default with IIS.)

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 09, 2018 2
Adobe Community Professional ,
Sep 09, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Charlie+Arehart  wrote

I think solving this is going to be more complicated than that. The issue is that I'm pretty sure CF will single-thread all requests (to a given app on its first execution) waiting for the onapplicationstart to finish. So no code will run in onrequestart until then.

Thanks for your remark, Charlie Arehart​. In fact, the code in the above example takes account of this, It shows the user a message while onApplicationStart is still running. That is, before we get to onRequestStart. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 09, 2018 2
Adobe Community Professional ,
Sep 10, 2018

Copy link to clipboard

Copied

Sure, I appreciate that was your hope. You admitted it was something for martiehen2  to try. Had you confirmed it really worked, though? Your wording suggested otherwise ("suggestion you may like to test"). I wasn't at a computer as I wrote so was just contemplating things myself. I now have tested things, and I stand by my proposal.

But let's clarify something first: was your goal only to offer a message about the app initiating to the FIRST user? If so, then your code work, sure. But all other users are left with a hanging browser. I'm pretty sure that's what martiehen2 wanted to resolve also. I know I did. 🙂

The problem again is that at app startup, concurrent requests running during its initiation will HANG on the running of onapplicationstart (and won't run code in onrequestart) until the first request (which kicked off the application) finishes: CF will block all requests from running until the long-running onapplicationstart finishes. You don't account for that, even in replying here when I specifically discussed it.

Perhaps your presumption was that CF was hanging up when the long-running code in onappstart was running. (Your test for isinitiated in the include called from onappstart suggests that.) That's not the issue. Again that's why I proposed the use of cfthread to let it finish sooner.

We're both just trying to help, of course. And I finally have put together some code to demonstrate what I am saying, and I have confirmed that it works. I would welcome feedback. Note that I only offer the application.cfc (I took away the need of the included file). I also took out unneeded references to sessions (mgt and timeout, and app timeout).

<cfcomponent>

    <cfset this.name = "EmployeeAdmin">

    <cffunction name="onApplicationStart" returntype="boolean">

        <cfset application.isInitiated=false>

             <cfthread action="run" name="appstartup">

                 <!---

                 The business code here takes several minutes. Simulate by a sleep of 60 seconds, for example.

                 --->

                 <cfset sleep(10000)>

                 <cfset application.isInitiated=true>

             </cfthread>

        <cfreturn true>

    </cffunction>

    <cffunction name="onRequest">

        <cfargument name = "targetPage" type="String" required="true">

        <!--- Displaying the wait message is relevant only when application.isInitiated is false. That is, while application start logic is still running. --->

        <cfif not isDefined("application.isInitiated") or not application.isInitiated>

            <p>App is starting. <br>

            Please wait a few minutes and try again.

            </p>

        <cfelse>

            <cfinclude template="#arguments.targetPage#">

        </cfif>

    <cfreturn true>

    </cffunction>

</cfcomponent>

Finally, note the important change I made from onrequeststart to onrequest. For those not familiar, onrequestart differs from onrequest in that the former runs its code and THEN runs the page requested, whereas the latter does NOT run the page requested unless it's included. (It acts as a front-controller, for those familiar with the concept.) I leverage that by not including the page requested if the app is not yet initiated.

Someone could certainly change it back to using onrequeststart instead. Just beware that if there is some part of the app initiation that would need to be completed before that requested page could run, the requested page would fail. (Things like referring to application variables, or the very ORM setup that martiehen2 referred to, and so on.)

I also confirmed this code works find is applicationstop() is called (to force a reload of the application). I know there are many other ways people might try to force a reload of an app. I welcome hearing from them if they test this and find some need of improvement.

Indeed, I am admitting that this is a subject that I've not seen discussed much, and there may be something I am missing. I welcome feedback and hope we could get to a helpful conclusion for those facing this.

PS When I first posted this code, I had left the application name (in this.name) as "EmployeeAdmin1c", rather than the "EmployeeAdmin" used originally. I was making changes to that name because if you change the name, you create a new "application" to CF and it runs the onapplicationstart (without need to restart CF or call code to stop the app). It was a shortcut I was using and I left that in by mistake in pasting the code here. I have corrected it. I'm writing this (and not just changing the code) in case any of you get emailed on posts to the thread, and then you may not notice I changed this here.

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 10, 2018 2
Adobe Community Professional ,
Sep 11, 2018

Copy link to clipboard

Copied

Thanks again for your remarks, Charlie Arehart . You are right about one thing: this one's a tough nut to crack.

My suggestion will indeed work just for the initial user. That is, for the single, initial request the wait-message will work as intended. But if a crowd of requests were to come in while the application was starting, the others would have to wait, without receiving any message. That is a point that needs to be addressed.

Your proposed solution goes a long way. But it also has its own shortcomings. In fact, it has some fatal design flaws.

In your example, when onRequest fires, which happens after onRequestStart, the application is still busy starting. This means that some of the application-logic which the request might need is not yet available to the application. In the other direction, onApplicationStart might need to access parameters in the variables scope within the request that you're processing in onRequest. Many frameworks require that.

These flaws are caused by your use of concurrent threads in onApplicationStart.This circumvents the fact that onApplicationStart is deliberately designed to be single-threaded, a fact you yourself mention. There is a reason for that design.

So, what's happening in your onApplicationStart? On start-up, ColdFusion's application-start-up thread carries on as usual, single-threaded. It creates the custom thread, appStartup. This doesn't take long, because appStartup is asynchronous. So the application-start-up thread is quickly on its way, without any delay. OnApplicationStart soon returns true, implying ColdFusion has successfully started the application. This happens even though the custom thread, appStartup, is still busy running the startup.

Normally, onApplicationStart has a synchronous relationship not only with requests, but also with sessions. Application start-up might depend on the order in which the event-handlers fire. But the custom thread, appStartup, is asynchronous, that is, fire-and-forget. As such, its flow is out of kilter with the event-handlers.

Another problem is uncaught exceptions. OnApplicationStart is designed such that, if it were to throw an uncaught exception or return false, the application wouldn't start. Your design bypasses this vital safeguard.

Finally, you say,

The problem again is that at app startup, concurrent requests running during its initiation will HANG on the running of onapplicationstart (and won't run code in onrequestart) until the first request (which kicked off the application) finishes: CF will block all requests from running until the long-running onapplicationstart finishes.

I agree. That is the given problem that needs to be solved.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 11, 2018 1
Adobe Community Professional ,
Sep 11, 2018

Copy link to clipboard

Copied

But don’t you see that I put in code that indicates when and if the app finishes initializing (in the cfthread code)? And then the onrequest code doesn’t let requests really run until that finishes? I am accommodating the very concern you raise. I don’t see it having a “fatal flaw” in the respect you propose.

That said, I don’t account for errors in it, that is true. And I do recognize there may be other matters I didn’t account for. I am indeed open to feedback on it. But can you reconsider if you misread things?

/charlie

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 11, 2018 0
Adobe Community Professional ,
Sep 16, 2018

Copy link to clipboard

Copied

BKBK​, do you have any reply to my response to you above (https://forums.adobe.com/message/10615008#10615008​)?

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 16, 2018 0
Adobe Community Professional ,
Sep 16, 2018

Copy link to clipboard

Copied

I want to add to my post here showing the cfthread example. It's important to note (for those who may not do much with CFTHREAD) that you do need to take an extra step (not logical on first viewing) if you want to refer within that cfthread code to variables that would otherwise NOT be available to it (as they would to the page launching it). This includes the url, form, and cgi scopes.

You need to pass in such variables (individually or the whole scope) on the cfthread itself, and then refer to them in the cfthread with the attributes scope. Ray Camden had done a good post back in 2007 and it's just as valuable today:

https://www.raymondcamden.com/2007/06/21/Quick-examlpe-of-CFTHREAD-and-a-warning

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 16, 2018 0
Adobe Community Professional ,
Sep 16, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Charlie+Arehart  wrote

BKBK , do you have any reply to my response to you above (Re: onApplicationStart display )?

Sure. While the thread is busy, onSessionStart, onRequestStart and onRequest all run and all finish. In some circumstances, dissociating them from the code in onApplicationStart can cause problems.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 16, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

Well, no. Again, I accounted for that by having the onrequest not let the page proceed as long as initialization in the thread was still working.

(Perhaps there's need to add some protection in an onsessionstart. I didn't need one and the op didn't mention one.)

I have now implemented this sort of code in my own site and so far its proving very helpful. Requests no longer pile up waiting. Instead, requests get a "please wait and try again while site is initializing" sort of msg instead.

Are you giving my suggestion serious consideration? It seems you keep dismissing with concerns I have tried to address.

I am sincerely interested in finding any holes in the logic, if any.

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Charlie+Arehart  wrote

Well, no. Again, I accounted for that by having the onrequest not let the page proceed as long as initialization in the thread was still working.

They in fact do. By the time onRequest starts, onSessionStart and onRequestStart have already run. As the custom thread is still busy, the boolean not isDefined("application.isInitiated") or not application.isInitiated is true. This results in onRequest returning true and closing. To repeat my statement, while the thread is busy, onSessionStart, onRequestStart and onRequest all run and all finish.

You created concurrency. The custom thread that continues in onApplicationStart is separate from the application-startup thread.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

I'm getting a little confused by this back and forth, so I apologize in advance if I'm missing something. But wasn't the initial issue that the application start event was still running, not the session or request events? If so, it doesn't really matter whether you're doing additional stuff in onSessionStart, onRequestStart or onRequest - nothing's going to do anything until the application itself has been initialized (onApplicationStart). In my own personal experience, nothing works until the application has initialized, whether there's HTML being returned or whatever.

The way I've generally handled this is by making the application server unavailable during this initialization. In a multi-server environment, this is pretty easy, and that's pretty much all I work with nowadays. You script the server to drop from the load balancer pool, do whatever needs to be done, verify its return to proper working order, then add back to the load balancer pool.

Again, I'm sorry if I'm covering ground already trod.

Dave Watts, Fig Leaf Software

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 2
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Dave+Watts  wrote

The way I've generally handled this is by making the application server unavailable during this initialization. In a multi-server environment, this is pretty easy, and that's pretty much all I work with nowadays.

Wholesome enterprise solution, I'd say!

My preferred solution is similar to yours: inform users beforehand, with reminders, about an upcoming maintenance period. Then, come the date and time, do it without further ado. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

Well, no. In my code (but not his), isInitiated is not executed until the operations in the cfthread are done (at which time all the “initialization” stuff) should be completed.

And until that is true, the onrequest I wrote will not let a request complete but instead will give a message. If you’re feeling that onrequeststart and onsession also need such a check for isInitiated being true, then you’d want to add them, sure.

Are we getting close to agreement? I still feel like you are seeing something wrong that I just don’t. Help me if you still think it’s I who am wrong.

/charlie

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

Yep, Dave, I had alluded to that in my first reply:

"Finally, someone may want to point out that there are other ways to "warm up" the app by calling it before the first user would. There are various solutions for that..."

But I still stand by my code as a way to allow requests not to "hangup" while app initialization is happening.

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Explorer ,
Sep 17, 2018

Copy link to clipboard

Copied

So when you use that approach Dave, do the users get "Service not available" from IIS?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Explorer ,
Sep 17, 2018

Copy link to clipboard

Copied

Charlie - I still don't understand why your code works with the message, since when I tried it I got an error on the <cfflush> - can't use in <cfthread>

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 17, 2018

Copy link to clipboard

Copied

martiehen2, first I have no cfflush in my code. None is needed. Are you referring to some modification that you have done? Where in the code did you do it? If within the CFTHREAD, that won't work. The CFTHREAD code creates no output at all, because it runs on a thread separate from the request itself. Again, that's the key of doing the initialization code in a thread, so it runs asynchronously from the request that kicks off the app initialization. Maybe you're doing it somewhere else, but it should not be needed.

Second, I had responded to your last reply to me, but I don't see that you answered Re: onApplicationStart display. That may help also with trying to resolve questions that remain for you.

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0
Adobe Community Professional ,
Sep 18, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Charlie+Arehart  wrote

Well, no. In my code (but not his), isInitiated is not executed until the operations in the cfthread are done (at which time all the “initialization” stuff) should be completed.

And until that is true, the onrequest I wrote will not let a request complete but instead will give a message. If you’re feeling that onrequeststart and onsession also need such a check for isInitiated being true, then you’d want to add them, sure.

Are we getting close to agreement? I still feel like you are seeing something wrong that I just don’t. Help me if you still think it’s I who am wrong.

Hi Charlie Arehart​, I have reviewed the posts and experimented further with your example. Weird as it might seem, being a multithreaded solution to a single-threaded problem, it could be a viable solution.

You are a master of the art. Others who implement it have to tread with care around the caveats.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 18, 2018 0
Adobe Community Professional ,
Sep 18, 2018

Copy link to clipboard

Copied

Thanks for the kind regards, BKBK​, and glad to get your confirmation of things. And yep, folks do need to tread carefully. Hope the info (and replies by myself and you and others) may help any interested in this solution.

And again, I look forward to feedback from any who may have questions, concerns, or suggestions on it. So far so good in my using of it.

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 18, 2018 0
Explorer ,
Sep 11, 2018

Copy link to clipboard

Copied

BKBKCharlie Arehart
thank you so much for your insight and thoughtful suggestions. I tried them, along with several other variations, and had exactly the same problems as my original post - with a new addition.

  • Either nothing displays (depending on cfflush interval)
  • Displays, but stops execution (never goes to index.cfm)
  • Or a new one - I get an error message that I'm attempting to execute a cfflush when I can't (e.g. in a cfthread)

Apparently, cold fusion isn't going to allow you to display anything until onApplicationStart is completed, although I can't even begin to understand why that is.

Rather than beat my head against the wall with CF, I decided to try something entirely different - index.html to the rescue.

  • Renamed my index.cfm to start.cfm (to avoid default page issues for the website)
  • Created index.html

index.html

<!DOCTYPE html>

<html>

<head>
</head>
<body>

<h2>Application is loading, just a moment please</h2>

<script type="text/javascript" language="javascript">

window.location = "start.cfm";

</script>

</body>

</html>


Works perfectly. HTML is displayed, and sits there until CF gets around to fulfilling the request for start.cfm

Now that the issue is solved, I can even get fancy with an animated loading image, woo hoo!

I've been working with CF since version 5, now running CF 2016.
I too was totally amazed that I couldn't find an answer to displaying a start message without asking a question, especially with the introduction of orm in CF9, which impacts onApplicationStart execution time.

FYI, I've got a real ball buster of an Application.cfc, supporting 6 separate, yet interconnected sites. I got sick of having to change the same things in all 6, so I parameterized.
Application.cfc extends ApplicationMaster.cfc, and ApplicationMaster.cfc extends ApplicationVars.cfc

Application.cfc is the a series of this.xxx = ..., same template, different values commented/uncommented for each site, and executes an appInit in ApplicationMaster, and has the onError function
ApplicationMaster.cfc and ApplicationVars.cfc are exactly the same code for all sites, making liberal use of switch statements

Perhaps something to do with my complex structure is what caused your suggestions to not work properly?

Seems like the simplest solution evaded us while we were drinking CF kool-aid.

Still curious as to why CF blocks output until onApplicationStart is finished.

Perhaps I'll play around a bit more and see if I can figure out a work-around with CF

PS - Wouldn't it be nice if there was a place to put a template in CFAdmin for this, and have CF display the template when it's starting?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 11, 2018 0
Adobe Community Professional ,
Sep 13, 2018

Copy link to clipboard

Copied

Martiehen2, glad you found some workaround. But you wonder why “CF blocks output until onApplicationStart is finished.” Again, it does not. Instead, it single-threads execution of the onapplicationstart method, until the method completes.

What you see as it “blocking output” is instead just CF blocking the request you are running while that finishes--whether yours is the request that triggers the onapplicationstart (implicitly, by running as the first request when the app has not been started), or whether yours is a request trying to run while some other one has triggered that.

And again, this is why I offered in my code a way to get CF to NOT hangup during processing of onapplicationstart.

/charlie

/Charlie (server troubleshooter, carehart.org)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 13, 2018 0
Adobe Community Professional ,
Sep 16, 2018

Copy link to clipboard

Copied

martiehen2​, I am happy for you that you have a solution you are happy with. Your HTML solution appears to be neat. But, I suspect, there might be a caveat.

ColdFusion passes HTML, unprocessed, to the web server. Without any flush instructions, the web server might buffer the page content, resulting in the user seeing no message.

In any case, I hadn't considered HTML for a different reason. I had assumed your users could come in by means of requests to arbitrary CFM pages. That is, to arbitrary URLs, including perhaps, query-strings.

If, as you now say, all users must come in through index.cfm, then a purely CFML solution might be possible. Including the use of cfflush. I thought of something along the following lines:

<cfcomponent>

<cfscript>

this.name = "EmployeeAdmin";

this.applicationTimeout = createTimespan(1,0,0,0);

this.sessionManagement = "true";

this.sessionTimeout = createTimeSpan(0,0,20,0);

</cfscript>

  

<cfif isDefined("application.hasApplicationStarted") and not application.hasApplicationStarted>  

    <cfflush interval="60">

    <h2 id="loadApplication">EmployeeAdmin is loading. Please wait a few minutes.</h2>

</cfif>

  

<cffunction name="onApplicationStart" returntype="boolean" >

  

    <cfif not isDefined("application.hasApplicationStarted")>  

        <cfflush interval="60">

        <h2 id="loadApplication">EmployeeAdmin is loading. Please wait a few minutes.</h2>

  </cfif>

    <cfset application.hasApplicationStarted=false>

  

    <!---

    The business code here takes several minutes. Simulate by a sleep of 45 seconds, for example.

    Test this by making several CFM requests in the 45 second window.

    --->

  

    <cfset sleep(45000)>

  

    <cfset application.hasApplicationStarted=true>

          

    <cfreturn true>

</cffunction>

<cffunction name="onRequestStart">

        <cfargument name = "targetPage" type="String" required="true">

        <!--- Javascript to hide the message. The wait message is displayed only when application.hasApplicationStarted is true. --->

        <cfif isDefined("application.hasApplicationStarted") and application.hasApplicationStarted>

        <script type="text/javascript">

        document.getElementById('loadApplication').style.display='none';

        </script>

        </cfif>

        <cfreturn true>

    </cffunction>

</cfcomponent>

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 16, 2018 0
Explorer ,
Sep 17, 2018

Copy link to clipboard

Copied

I might give that a whirl, BKBK, but when I have put in the cfflush before the onApplicationStart, I got an error message saying that I used cfflush when I couldn't (cfthread)

My HTML is just html, no cf, so no cfflush needed - e.g., index.html, which is now the first default document instead of index.cfm

We are changing the 2 other links into the system to go through index.html (?module=xxx) to avoid the arbitrary urls. (although I imagine that google search arbitrary urls won't see the index.html). Mainly I'm concerned about the login (where index.cfm was sending them) and signup.
Any other requests into the system are posts or ajax, which will either work or timeout, but no user display is needed

BKBK  wrote

martiehen2 , I am happy for you that you have a solution you are happy with. Your HTML solution appears to be neat. But, I suspect, there might be a caveat.

ColdFusion passes HTML, unprocessed, to the web server. Without any flush instructions, the web server might buffer the page content, resulting in the user seeing no message.

In any case, I hadn't considered HTML for a different reason. I had assumed your users could come in by means of requests to arbitrary CFM pages. That is, to arbitrary URLs, including perhaps, query-strings.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2018 0