I'm not sure how java internals of cfloop/collection work, but chances
are it's dangerous to loop through a collection you are deleting/adding
items to/from.


Perhaps change to CFLOOP list=StructKeyList(application.UsersInof)  and
then retreive the item if it's there...  


Also, How do you keep the person "online"... it seems like the following
undesirable timeline is possible:


8:00 User logs in, gets a now() timestamp
8:14 User hits a page.  Since still has a timestamp, nothing happens
8:16 User is deleted, since the 8:00 stamp expired, even though user hit
2 minutes ago...


You should update a user's timestamp on each hit... I'd write it like
this:


when user logs in,
<Cfset Session.Stamp=structnew()>
<Cfset session.stamp.last=now()>
<Cfset application.UsersInfo[session.userid]=session.stamp>


Then whenever a user hits the page, you have
<Cfif session.isloggedin and isdefined("Session.stamp.last")>
<Cfset session.stamp.last=now()>
</cfif>


Since session.stamp is a reference to a struct, which also exists in
application.usersinfo, it doesnt get destroyed with the session....


Just a thought
HTH
d


Dov Katz
Enterprise & Client Technology
Morgan Stanley
<mailto:[EMAIL PROTECTED]>

  _____  

From: Sung Woo [mailto:[EMAIL PROTECTED]
Sent: Wednesday, September 15, 2004 9:15 AM
To: CF-Talk
Subject: Users Online, Take 2

So I've finally gotten around to rewriting the "who is online?" portion
of my site, and it turns out that I didn't have to do much rewriting at
all.  The script below was using CFID to keep track, which, as many
people pointed out, was not a good idea.  I keep a session variable
(session.UserID) in my application, so this was a much better idea.  So
the script is as follows:

<!--- keep a list of online users --->

<cfif Session.LoggedIn>
<cfif NOT IsDefined("Application.UsersInfo")>
    <cflock timeout="15" scope="APPLICATION" type="EXCLUSIVE">
        <cfif NOT IsDefined("Application.UsersInfo")>
            <cfset Application.UsersInfo = StructNew()>
        </cfif>
    </cflock>
</cfif>
<cfif NOT StructKeyExists(Application.UsersInfo, session.UserID)>
    <cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
        <cfif NOT StructKeyExists(Application.UsersInfo,
session.UserID)>
            <cfset StructInsert(Application.UsersInfo, session.UserID,
now())>
        </cfif>
    </cflock>
</cfif>
<cfloop collection="#Application.UsersInfo#" item="itmUser">
    <cflock name="session_lock_#itmUser#" timeout="15">
        <cfif StructKeyExists(Application.UsersInfo, itmUser)>
            <cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
                <cfset StructDelete(Application.UsersInfo, itmUser)>
            </cfif>
        </cfif>
    </cflock>
</cfloop>
</cfif>

My question involves the StructDelete portion of the code, namely:

<cfloop collection="#Application.UsersInfo#" item="itmUser">
    <cflock name="session_lock_#itmUser#" timeout="15">
        <cfif StructKeyExists(Application.UsersInfo, itmUser)>
            <cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
                <cfset StructDelete(Application.UsersInfo, itmUser)>
            </cfif>
        </cfif>
    </cflock>
</cfloop>

I have this script in the application.cfm file, which means this loop is
activated with every single click.  Sure, it isn't that much load, but I
don't see any reason why this should kick in so often.  So I cut it out
of the application.cfm file and created a separate file, called
cleanup_online_users.cfm.  Then I used Scheduled Tasks to schedule this
snippet of code -- and it doesn't work.  It's very strange -- if I run
it manually, it doesn't work, either.  However, if I manually run it AND
THEN force a refresh, it works.  I was wondering if CF was somehow
caching this page, so I changed the page to this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>cleanup</title>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
</head>

<body>

<!--- cleanup_online_users.cfm --->

<cfloop collection="#Application.UsersInfo#" item="itmUser">
    <cflock name="session_lock_#itmUser#" timeout="15">
        <cfif StructKeyExists(Application.UsersInfo, itmUser)>
            <cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
                <cfset StructDelete(Application.UsersInfo, itmUser)>
            </cfif>
        </cfif>
    </cflock>
</cfloop>

</body>
</html>

Still doesn't work.  The only way to make it work is if I load it
manually and then refresh.  What am I doing wrong?

I'm running Win2K & CFMX 6.1.

- Sung
  _____
[Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]

Reply via email to