Skip to content

Instantly share code, notes, and snippets.

@carehart
Last active October 1, 2024 21:32
Show Gist options
  • Save carehart/1a959c382353f8b4bcfa23049d9760da to your computer and use it in GitHub Desktop.
Save carehart/1a959c382353f8b4bcfa23049d9760da to your computer and use it in GitHub Desktop.
CFLock preso demonstration code
This gist contains several files which demonstrate cflock (for Adobe ColdFusion and Lucee).
They're examples I showed in my talk on the topic at https://www.carehart.org/presentations/#cflock .
You could save all the files in a single folder.
Note that there's an Application.cfc (and cfm and OnRequestEnd, for those preferring that).
Otherwise, the files are numbered in the order presented in my talk, and are generally self-explanatory.
<!--- Timing info shown upon running this is found in application.cfc --->
<h2>I'm creating a lock and sleeping within it for 5 seconds</h2>
<cfflush>
And I'm willing to wait to obtain a lock for up to 1 second<br><br>
<cflock timeout="1">
<cfset sleep(5000)>
Sleep within lock finished<br>
</cflock>
<!--- Allows setting sleep and timeout times via URL vars, with defaults --->
<cfparam name="url.sleep" default="5">
<cfparam name="url.timeout" default="5">
<!--- Subsequent templates will rely on the cfparam lines being in application.cfc/cfm --->
<cfoutput>
<h2>I'm creating a lock and sleeping within it for #url.sleep# seconds</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<!---<cflock timeout="#url.timeout#" name="blocker" type="exclusive">--->
<cflock timeout="#url.timeout#" name="blocker">
<cfset sleep(url.sleep*1000)>
Sleep within lock finished<br>
</cflock>
</cfoutput>
<cfparam name="session.count" default="0">
<!--- Subsequent templates will rely on the cfparam line being in application.cfc/cfm --->
<cfoutput>
<h2>I'm creating a lock AND setting a session var within it, and sleeping within it for #url.sleep# seconds</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<cflock timeout="#url.timeout#" scope="session" type="exclusive">
<cfset session.count++>
<cfset sleep(url.sleep*1000)>
Sleep within lock finished, incremented session.count to #session.count#<br>
</cflock>
</cfoutput>
<cfoutput>
<h2>I'm getting the session var, without a lock</h2>
session.count is #session.count#<br>
</cfoutput>
<cfoutput>
<h2>I'm getting the session var, within a lock</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<cflock timeout="#url.timeout#" scope="session" type="readonly">
Within lock, session.count is #session.count#<br>
</cflock>
</cfoutput>
<cfoutput>
<h2>I'm setting a session var without a lock</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfset session.count++>
Incremented session.count to #session.count#<br>
</cfoutput>
<cfoutput>
<h2>I'm creating a lock AND setting an app var within it, and sleeping for #url.sleep# seconds</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<cflock timeout="#url.timeout#" scope="application" type="exclusive">
<cfset application.count++>
<cfset sleep(url.sleep*1000)>
Sleep within lock finished, incremented application.count to #application.count#<br>
</cflock>
</cfoutput>
<cfoutput>
<h2>I'm getting the application var without a lock</h2>
application.count is #application.count#<br>
</cfoutput>
<cfoutput>
<h2>I'm getting the application var, within a lock</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<cflock timeout="#url.timeout#" scope="application" type="readonly">
Within lock, application.count is #application.count#<br>
</cflock>
</cfoutput>
<cfoutput>
<h2>I'm setting a application var without a lock</h2>
<cfset application.count++>
Incremented application.count to #application.count#<br>
</cfoutput>
<cfoutput>
<h2>I'm creating a lock AND setting a var within that, and sleeping for #url.sleep# seconds</h2>
And while I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
I'm setting throwontimeout to false!
<cfflush>
<cflock timeout="#url.timeout#" scope="application" type="exclusive" throwontimeout="false">
<cfset request.importantvar="importantval">
Setting request.importantvar to #request.importantvar#<br>
</cflock>
My code set request.importantvar to #request.importantvar#<br>
</cfoutput>
<cfoutput>
<h2>I'm creating an app scope lock and sleeping for #url.sleep# seconds</h2>
And I'm willing to wait to obtain a lock for up to #url.timeout# seconds<br><br>
<cfflush>
<cflock timeout="#url.timeout#" scope="application" type="exclusive">
<cfset sleep(url.sleep*1000)>
Sleep within lock finished<br>
</cflock>
</cfoutput>
component {
// If you prefer to use application.cfm (and tags), I offer that as well.
// Indeed, beware that if both are in the same folder, CF runs application.cfc and NOT application.cfm
this.name="blocker";
this.sessionmanagement="yes";
function onrequeststart () {
cfparam(name="url.sleep",default="5");
cfparam(name="url.timeout",default="5");
cfparam(name="session.count",default="0");
cfparam(name="application.count",default="0");
writeoutput("Starting at #datetimeformat(now())#<br>");
start=gettickcount();
}
function onrequestend () {
end=gettickcount()-start;
writeoutput("
<br><br>Stopping at #datetimeformat(now())#<br>
Duration: #numberformat(end/1000,"0.00")# seconds<br><br>
(in application named '#application.applicationname#', in session with id: #session.sessionid#)<br>
")
}
}
<!---
- If you prefer to use application.cfc, I offer that (as script) as well.
- Indeed, beware that if both are in the same folder, CF runs application.cfc and NOT application.cfm
--->
<cfapplication name="blocker" sessionmanagement="yes">
<cfparam name="url.sleep" default="5">
<cfparam name="url.timeout" default="5">
<cfparam name="session.count" default="0">
<cfparam name="application.count" default="0">
<cfoutput>
Starting at #datetimeformat(now())#<br>
</cfoutput>
<cfset start=gettickcount()>
<!---
- This runs in conjunction with application.cfm, providing end-of-request functionality.
- If you prefer to use application.cfc, I offer that as well.
- Indeed, beware that if both are in the same folder, CF runs application.cfc and NOT application.cfm (nor this)
--->
<cfoutput>
<cfset end=gettickcount()-start>
<br><br>Stopping at #datetimeformat(now())#<br>
Duration: #numberformat(end/1000,"0.00")# seconds<br><br>
(in application named '#application.applicationname#', in session with id: #session.sessionid#)<br>
</cfoutput>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment