Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsGeneralPHPASPPerlColdFusionFlashHTML, CSS, ScriptsBrowsers

Webmaster Forum / ColdFusion / Advanced Techniques / July 2008



Tip: Looking for answers? Try searching our database.

Component in Application Scope and cflock

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
am2605 - 29 Jul 2008 12:29 GMT
Hi,

I have an CFC that I set in application scope in the onApplicationStart method
which contains some system parameters, one of which is a flag saying whether
the site is currently "Online".  I call a method on this CFC in the
Application.cfc "onRequest" method to see if the flag value has changed.

This method looks up a parameter set in the database that says whether the
site is "online" or "offline".  If the site is currently online, I want to only
redo the query every 5 mins.  However if the site is offline, I want to check
more frequently (every 5 secs) as to whether the flag has changed back.

What I am not sure of, is whether I need to be using <cflock> when I change
from "online" to "offline"?  There is only a single instance of this object,
but what happens if multiple requests are calling the "isSiteOnline" method
simultaneously?  Is this "safe"?

Some code snippets are attached to illustrate.

Any advice would be greatly appreciated.

Regards,
Andrew.

In Application.cfc:

<cffunction name="onApplicationStart">
   ....
   <cfset application.systemOptions = createObject("component",
"system.SystemOptions").init()>
   ....
</cffunction>

<cffunction name="onRequest">
   <cfset isOnline = application.systemOptions.isSiteOnline()>
</cffunction>

The SystemOptions CFC stores the current status in an instance variable.

eg.

SystemOptions.cfc

     
<cfcomponent name="SystemOptions" output="false">
 
    <cfset variables.hrxmlDatasource = "testdb">
     
    <cffunction name="init" access="public" returntype="SystemOptions"
output="false" hint="Create a new instance of SystemOptions">
        <cfset variables.instance = STRUCTNEW() />
        <cfset this.setDbOnlineCacheInterval()>
        <cfreturn this />
     </cffunction>  
 
  <cffunction name="isSiteOnline" access="public" output="false"
returntype="boolean">
 
    <cfset var siteOffline = false />
   
    <cfquery name="qIsOffline" datasource="#variables.hrxmlDatasource#"
Cachedwithin="#CreateTimeSpan(0, 0, 0, variables.instance.cacheInterval)#">
      ..... // query that returns a single row if the site is to be taken
offline
    </cfquery>
 
    <cfif qIsOffline.RecordCount gt 0>
      <cfset siteOffline = true>
      <cfset this.setDbOfflineCacheInterval()>
    <cfelse>
      <cfset this.setDbOnlineCacheInterval()>
    </cfif>
   
    <cfreturn siteOffline/>
 
  </cffunction>

  <cffunction name="setDbOnlineCacheInterval" access="public" output="false"
returntype="void">
    <!--- DO I NEED TO USE CFLOCK HERE???? --->
    <cfset variables.instance.cacheInterval = 300 /> <!--- When online check
for a change every 5 mins --->
  </cffunction>

  <cffunction name="setDbOfflineCacheInterval" access="public" output="false"
returntype="void">
    <!--- AND DO I NEED TO USE CFLOCK HERE???? --->
    <cfset variables.instance.cacheInterval = 5 /> <!--- When offline checks
for a change every 5 secs --->
  </cffunction>

</cfcomponent>
BKBK - 30 Jul 2008 06:16 GMT
[i]<!--- DO I NEED TO USE CFLOCK HERE???? --->[/i]
 No.

 [i]<!--- AND DO I NEED TO USE CFLOCK HERE???? --->[/i]
No.

Even though requests share the instance [i]application.systemOptions[/i],
locks are unnecessary. When one request makes the call
[i]application.systemOptions.isSiteOnline()[/i], it is independent of another
request's call.
Adam Cameron - 30 Jul 2008 09:46 GMT
> <!--- DO I NEED TO USE CFLOCK HERE???? --->

No, in either situation.

Ask yourself... what would the ramifications be of two requests hitting
that line of code "simultaneously"?  The end result is that both of them
are setting the variable to the same static value... so that's what's going
to end up happening: variables.instance.cacheInterval is going to be set to
300 (or 5) in each situation.

You could well with to lock a block of code which - if called
simultaneously via more than one request - could act on shared storage
space (server, application or session data) differently and incorrectly
than is intended.

eg:
<!--- application bootstrap process --->
<cfif not structKeyExists(application, isInitialised and not
application.isInitialised>
    <!--- initialisation process, whatever it is --->

    <cfif allOK>
        <cfset application.isInitialised = true>
    <cfelse>
        <cfset application.isInitialised = false>
    </cfif>
</cfif>

So a sequence of events could be (say the user is hitting the site with two
different browsers):

REQUEST1: application.isInitialised doesn't exist
REQUEST1: starts the init process
REQUEST2: application.isInitialised STILL doesn't exist
REQUEST2: starts the init process *again*
REQUEST1: sets the application.isInitialised value
REQUEST2: sets the application.isInitialised value

Obviously one does not want two request running the initialisation code.

note this is a slightly contrived example, as if one has an
OnApplicationStart() method, then it will only run once, and that's where
one would have the init code, but it demonstrates the issue.

Google "race condition".  Those are the situations in which one needs to
lock blocks of code.

Signature

Adam

am2605 - 30 Jul 2008 11:37 GMT
Thank you for your replies.  That makes it a lot clear.  Much appreciated.

Regards,.
Andrew.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.