#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    138
    Rep Power
    19

    Proper use of CFLOCK


    So i'm a bit confused. I've got a race condition happening with an intranet application.

    Intermittently users are getting the wrong IDs and it's causing some minor hiccups with showing who created posts and events and what not.

    my problem is I've set up some cflock tags to try to prevent this but they don't appear to be working; Now i'm wondering if i'm using them correctly.

    Basically our staff are extremely technically challenged.... We auto log them into the intranet application once they are logged into their windows account(not really secure, i know but it doesn't matter here).

    then under <!--- Staff permissions check ---> i check to see if the have an account generated and if they do i return the ID that matches their session.name. Then through out their session that ID is used to track and identify who they are and what they do as well as their access level.

    Now I've added a cflock at the top of this because i was getting users with mixed up IDs but it doesn't seems to have worked. Should i be placing the lock around the calls in application.cfc or in the WhosOnline.cfc itself around the query that pulls all this info? I've gone through the docs and maybe i'm missing something or i just don't get it.


    Code:
    <cffunction
            name="OnSessionStart"
            access="public"
            returntype="void"
            output="false"
            hint="I fire when a new session begins.">
    
            <cflock scope = "Application"
                    timeout = "10" type = "Exclusive">
    
                <!--- Set up session variables. --->
                <CFSET SESSION.domain = "GL\">            
                <cfset SESSION.LoggedIn = false />
                <cfset SESSION.Name = "#REPLACENOCASE(AUTH_USER,'#session.domain#','')#" />
                <cfset session.filestore = "/documents/">
                <CFSET session.hostname="#CreateObject("java", "java.net.InetAddress").getByName("#cgi.REMOTE_HOST#").getHostName()#">
    
                <CFSET session.todayodbc = #createodbcdate(now())#>
                <CFSET SESSION.usercheck = false>
    
                <cfset session.securityRedirect = "/securitywarning.cfm" >
    
                <!--- Staff permissions check --->
                <CFSET objNewUser = CreateObject("component", "cfc.WhosOnline")>
                <cfset qryNewUser = #objNewUser.newusercheck(session.name)#>
                <cfset session.staffid = #qryNewUser#>
    
                <!---Staff Name --->
                <cfset objName = CreateObject("component", "cfc.WhosOnline")>
                <cfset qryName = #objName.staffName(session.staffid)#>
                <cfset session.StaffName = '#qryName#'>
    
                
                <cfset session.root = "E:\web-sites\intranet2\">
                
                <!--- Return out. --->
                <cfreturn />
    
            </cflock>
        </cffunction>
    Last edited by dsfx; May 16th, 2016 at 09:45 AM. Reason: spelling
  2. #2
  3. No Profile Picture
    Moderator

    Join Date
    Jun 2002
    Location
    Raleigh, NC
    Posts
    5,307
    Rep Power
    970
    OnSessionStart() should already be locked for the session scope, so you shouldn't need to use cflock here. But you're using an exclusive application-wide lock here, which should be single-threading access to this code across all requests. So if you're having some sort of race condition, it doesn't look like it is coming from this block of code.
  4. #3
  5. No Profile Picture
    Moderator

    Join Date
    Jun 2002
    Location
    Raleigh, NC
    Posts
    5,307
    Rep Power
    970
    Actually your issue could be related to the way you're creating WhosOnline. You're creating the component but you're not creating a new instance of the component for each session. You usually want to use "new cfc.WhosOnline()" to invoke a constructor and ensure that you've got a new instance of the object, or explicitly call a constructor function (like 'CreateObject("component", "cfc.WhosOnline").init()'. Either way, the issue could actually be with WhosOnline.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    138
    Rep Power
    19
    I thought the CF lock was a bit overkill but it keeps popping up and i'm not sure why. I'll remove the CFLOCK and ensure i'm invoking a new object for each session by appending .init() to CreateObject. The other thing i was wonder and somebody pointed out is i've not scoped my variables

    Would this be a more correct way of doing this?
    Code:
                <cfset session.objNewUser = CreateObject("component", "cfc.WhosOnline").init()>
                <cfset session.qryNewUser = #objNewUser.newusercheck(session.name)#>
                <cfset session.staffid = #qryNewUser#>
    The only other clue i can give is it's intermittent. So i was able to recreate it once with my profile but upon page refresh it corrected itself and I've never seen it again. Over hundreds of page loads.

    Thanks for the advice it's given me some reading and research for the night.

    DSFX
  8. #5
  9. No Profile Picture
    Moderator

    Join Date
    Jun 2002
    Location
    Raleigh, NC
    Posts
    5,307
    Rep Power
    970
    You should make it common practice to var scope all method-local variables (e.g. <cfset var objNewUser = .... />). Whether that could be the problem depends on whether the CFC containing your OnSessionStart() method is created per-request or is a singleton (application-scoped). It wouldn't hurt to make sure you're always var scoping (both in this code, and in your WhosOnline CFC, and all other CFCs).

IMN logo majestic logo threadwatch logo seochat tools logo