Question

I am having some concurrency issues in cfwheels.

I have some code in events/onrequeststart.cfm that is being executed every time the user is requesting something.

Test case: User A - request time: 10sec User B - request time: 2sec

If the user B issues a request while the user A is already working on a request, user's B settings will go into user A and user A will display results based on user's B request.

I tried using cflock on the onrequeststart.cfm but it doesn't seem to work. I don't have much experience with cfwheels so I maybe trying to do something that is logically wrong.

This is part of the code that gets confused.

    <cfquery name="currentUser" datasource="#application.ds#">
        select * from clientadmin where clientAdminid ='#session.clientadminid#'
    </cfquery>

    <cfquery name="currentClient" datasource="#application.ds#">
        select * from clientBrands where clientbrandID ='#currentUser.ClientBrandID#'
    </cfquery>



<cfset application.clientAdminSurveys = application.generalFunctions.clientSurveys(clientAdminID=session.clientAdminID, clientBrandID = currentUser.clientBrandID)>
<cfset application.AssociatedDoctors = application.generalFunctions.AssociatedDoctors(clientAdminID=session.clientAdminID, clientBrandID = currentUser.clientBrandID)>

So, I guess my question is, how to avoid this from happening?

Was it helpful?

Solution

1) The Application scope is "application wide" (all users of site wide) - you shouldn't be setting per user settings there, ever, as as you've discovered, user B overwrites user A. Use the session scope for per user stuff. So in your last two lines you're setting application scope stuff using session scope data!

2) As a side note, in wheels you can use application.wheels.datasourcename to get the database name

OTHER TIPS

I would put that code into a function inside the controller(controller.cfc) and run it using a filter.

see: http://cfwheels.org/docs/1-1/chapter/filters

This has worked for me without issues for similar tasks.

Also I would drop any reference to application. because that's likely where items are getting mixed up. The correct place to put these functions is into events/functions.cfm

of course this is without seeing more of your code...

As mentioned by Neokoenig, you are utilizing a shared scope to store user specific data, you should store that in SESSION. If you need the data in application scope you should be using a lock while setting that data, but it looks like you should be running this in onSessionStart once and not on every request. If you need to run it on every request you may want to continue using the onRequestStart but utilize the user specific session storage and not the global application layer.

Just remember: Application variables will show the same data for all users. So if user a sets application.foo = 1 and user b sets application.foo = 2 then user one try to access application.foo, user 1 will see user 2's value of 2. If this was using session scope you would not have this same issue. If user 1 sets SESSION.foo = 1 and user 2 sets SESSION.foo = 2. When the user accesses the SESSION.foo variable it will only contain the data set by that user (ex: user 1 will output SESSION.foo and see the value, 1)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top