ASP Page Counter

P

Paul W Smith

I have written a hit counter, which I believe counts the times my page is
hit by a user for each unique session by the user.

The relevant part of my code is below:


If IsEmpty(Session("TotalCount")) Then

' Increment or reset the count
If Weekday(Date(),vbSunday) = 1 And dtDate <> Date then
iCount = 1
Else
iCount = iCount + 1
End If
dtDate = Date

End If

Session("TotalCount")= iCount

The page is www.middlesexccl.com


My issue is I cannot believe the number of hits I am getting - or more
accurately should I trust the number of hits I am getting.

When I first go to the URL I see the count increased by one, but it does not
incredment if I reload the page.

Is there any techniques that the clubs involved could be using, i.e. some
sort of 'fancy' linking to the page from their web site which might be
causing the count to be incremented unduely? I am sorry if that sounds a
little vague but I cannot udnerstand where the hits are coming from.

If anyone has any other odeas on how to test this please let me have
details.

Many thanks to all those who give this isue their attention.

Paul Smith
 
P

Paul W Smith

Check your raw Web log files.

They'll identify the date, time, and ip address of each "hit".

FTP into your site; if you can't find them then ask your Web host.

Thank for that great advice - found some explainations of web pages on web,
and after some integration of the log files for the week, I can see that my
hit count is actually pretty accurate!
 
E

Evertjan.

Paul W Smith wrote on 15 aug 2008 in
microsoft.public.inetserver.asp.general:
If IsEmpty(Session("TotalCount")) Then

' Increment or reset the count
If Weekday(Date(),vbSunday) = 1 And dtDate <> Date then
iCount = 1
Else
iCount = iCount + 1
End If
dtDate = Date

End If

Session("TotalCount")= iCount

This will only increment iCount once every session.

Seems to me the above is not the whole story.

Please show a minimal working example.
 
D

Daniel Crichton

Paul wrote on Fri, 15 Aug 2008 11:53:57 +0100:
I have written a hit counter, which I believe counts the times my page
is hit by a user for each unique session by the user.
The relevant part of my code is below:

If IsEmpty(Session("TotalCount")) Then
' Increment or reset the count
If Weekday(Date(),vbSunday) = 1 And dtDate <> Date then iCount
= 1
Else iCount = iCount + 1
End If dtDate = Date
Session("TotalCount")= iCount
The page is www.middlesexccl.com

My issue is I cannot believe the number of hits I am getting - or more
accurately should I trust the number of hits I am getting.
When I first go to the URL I see the count increased by one, but it
does not incredment if I reload the page.
Is there any techniques that the clubs involved could be using, i.e.
some sort of 'fancy' linking to the page from their web site which
might be causing the count to be incremented unduely? I am sorry if
that sounds a little vague but I cannot udnerstand where the hits are
coming from.
If anyone has any other odeas on how to test this please let me have
details.
Many thanks to all those who give this isue their attention.
Paul Smith


The Session object is a per-session object, so you'll only see a TotalCount
value for your own session. Also, as you only increment if
Session("TotalCount") is empty, it will only increment once. Looking at the
code you posted, there is no way that could be the only code handling the
counter on that site.

For a counter that tracks sessions for you site, look into using the
Application object in the Session_OnStart event in global.asa. This would
allow you to increment the counter by 1 for each new Session that is
created, and is visible to any page that can read the Application object.

For instance, look at this: http://www.asptutorial.info/script/activeuserscounter/

However, note that this only records the number of active sessions - to get
the total number of sessions since reset, drop the Session_OnEnd event code.
If you want actual hits to pages, you will need to add code into every ASP
page on your site to increment an Application variable, eg.

Application.Lock
If IsEmpty(Application("TotalHits")) then
Application("TotalHits") = 1
Else
Application("TotalHits") = Applicaton("TotalHits") + 1
End If
Application.Unlock

You could then, if you wanted, display the number of sessions and the number
of hits as counters on your site. You might want to combine this with the
Application_OnStart even in global.asa to initialise the "TotalHits" value,
then you only need the incrementing line in each page rather than the entire
If ... End If block.

Don't forget that the figures will be lost if the IIS process is
recycled/stopped/started though.
 
E

Evertjan.

Daniel Crichton wrote on 18 aug 2008 in
microsoft.public.inetserver.asp.general:
Application.Lock
If IsEmpty(Application("TotalHits")) then
Application("TotalHits") = 1
Else
Application("TotalHits") = Applicaton("TotalHits") + 1
End If
Application.Unlock

I do not think a lock will be usefull/neccesary for a single statement.
Don't forget that the figures will be lost if the IIS process is
recycled/stopped/started though.

So it is not usefull at all, methinks,
better use a database or a single file.

---------------

The application stored counter could be used for counting the number of
"active" visitors, since they are zero at a new application start anyway.

The count up and count down could be put in the global asa session subs.

Perha[s the OP wanted that.
 
D

Daniel Crichton

Evertjan. wrote on 18 Aug 2008 15:47:38 GMT:
Daniel Crichton wrote on 18 aug 2008 in
microsoft.public.inetserver.asp.general:

I do not think a lock will be usefull/neccesary for a single statement.

Probably not, but it's been a while since I looked into the effects of
locking.
So it is not usefull at all, methinks, better use a database or a
single file.

It's useful if you only need a rough idea of what's going on.
---------------
The application stored counter could be used for counting the number of
"active" visitors, since they are zero at a new application start
anyway.
The count up and count down could be put in the global asa session
subs.
Perha[s the OP wanted that.

Which is what I linked to :)
 
A

Anthony Jones

Evertjan. said:
Daniel Crichton wrote on 18 aug 2008 in
microsoft.public.inetserver.asp.general:


I do not think a lock will be usefull/neccesary for a single statement.



Request A arrives
Request B arrices

Thread handling A reads Totalhits (its 10)
Thread handling B reads TotalHits (its still 10)
Thread handling B assigns 11 to TotalHits
Thread handling A also assigns 11 to TotalHits

Technically then the Lock is necessary although in reality it might not
actually matter.
 
E

Evertjan.

Anthony Jones wrote on 20 aug 2008 in
microsoft.public.inetserver.asp.general:
Request A arrives
Request B arrices

Thread handling A reads Totalhits (its 10)
Thread handling B reads TotalHits (its still 10)
Thread handling B assigns 11 to TotalHits
Thread handling A also assigns 11 to TotalHits

Technically then the Lock is necessary although in reality it might not
actually matter.

That could be true, but it also could be,
that ASP in singlethreaded on a per statement basis.
 
A

Anthony Jones

Evertjan. said:
Anthony Jones wrote on 20 aug 2008 in
microsoft.public.inetserver.asp.general:


That could be true, but it also could be,
that ASP in singlethreaded on a per statement basis.

The only time that would be true is if the whole site is single threaded due
to debugging being enabled.
 
E

Evertjan.

Anthony Jones wrote on 21 aug 2008 in
microsoft.public.inetserver.asp.general:
The only time that would be true is if the whole site is single
threaded due to debugging being enabled.

Why?

There is no advantage to multithread a single "let" statement,
and in global.asa it even is detrimental.
So it is just the choice of the VBS interpreter programmer.

Do we know, or can we test this?
 
A

Anthony Jones

Evertjan. said:
Anthony Jones wrote on 21 aug 2008 in
microsoft.public.inetserver.asp.general:



Why?

There is no advantage to multithread a single "let" statement,
and in global.asa it even is detrimental.
So it is just the choice of the VBS interpreter programmer.

Do we know, or can we test this?

I don't think you've quite grasped the concept yet.

Let me step you through my earlier example more slowly (to keep things
simple I'll assume one cpu)

Request A arrives
ASP takes a session object matching the Session cookie
ASP takes an existing scripting context not currently in use
ASP takes the script that the path indicates
ASP takes an idle thread from a thread pool (we'll give this thread an
ID of 1)
ASP puts this lot together and starts executing the script on thread 1

Request B arrives

ASP takes a session object matching the Session cookie
ASP takes an existing scripting context not currently in use
ASP takes the script that the path indicates
ASP takes an idle thread from a thread pool (we'll give this thread an
ID of 2)
ASP puts this lot together and starts executing the script on thread 2


Thread 1 handling A reads Totalhits (its 10)
Dispite what may seem the line:-
Application("TotalHits") = Applicaton("TotalHits") + 1
is not a single atomic operation
There is a read, there is an add and there is a write (with plenty in
between)
all of which may be pre-empted at any time.
At this point thread 1 has merely read the value then its pre-empted
and the scheduler starts executing Thread 2

Thread 2 handling B reads TotalHits (its still 10)
Here thread 2 has read the same value neither thread has written yet.
Hence it has read the same value

Thread 2 handling B assigns 11 to TotalHits
The addition is performed and the value written back to the application
object
Thread 2 completes in the knowledge of a job well done.

Thread 1 handling A also assigns 11 to TotalHits
Thread 1 resumes where it left off
It has just read the value it has no idea that it has changed since
It performs the addition and writes the value 11 back to the application
Thread 2 complete in the knowledge of a job well done.

Do you see it now?
 
E

Evertjan.

Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:
Thread 1 handling A reads Totalhits (its 10)
Dispite what may seem the line:-
Application("TotalHits") = Applicaton("TotalHits") + 1
is not a single atomic operation
There is a read, there is an add and there is a write (with plenty in
between)
all of which may be pre-empted at any time.
At this point thread 1 has merely read the value then its pre-empted
and the scheduler starts executing Thread 2
[ etc ]


You are so wrong in thinking,
that because it is logical,
it is implemented that way.

While it could very well be the case,
the logic does not prove the factual implementation.

Ony the source code or the testing can prove it.
 
A

Anthony Jones

Evertjan. said:
Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:
Thread 1 handling A reads Totalhits (its 10)
Dispite what may seem the line:-
Application("TotalHits") = Applicaton("TotalHits") + 1
is not a single atomic operation
There is a read, there is an add and there is a write (with plenty in
between)
all of which may be pre-empted at any time.
At this point thread 1 has merely read the value then its pre-empted
and the scheduler starts executing Thread 2
[ etc ]


You are so wrong in thinking,
that because it is logical,
it is implemented that way.

While it could very well be the case,
the logic does not prove the factual implementation.

Ony the source code or the testing can prove it.


Here is a fact the VBScript engine has no idea what an application object
is.

Here is another fact VBScript does not compile to native code.

Here is another fact VBScript doesn't create a zillion critical sections
around simple assignment statements.

You can lead a horse to water but you can't make it drink.
 
E

Evertjan.

Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:
Here is a fact the VBScript engine has no idea what an application object
is.

Here is another fact VBScript does not compile to native code.

Here is another fact VBScript doesn't create a zillion critical sections
around simple assignment statements.

You can lead a horse to water but you can't make it drink.

All these things are circumstancial,
and do not prove a thing.

It still might be that a let statement in global.asa is internally
singlethreaded, because it was felt convenient.
 
A

Anthony Jones

Evertjan. said:
Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:


All these things are circumstancial,
and do not prove a thing.

It still might be that a let statement in global.asa is internally
singlethreaded, because it was felt convenient.


(sigh) Well you're entitled to hold to whatever beliefs you want to.

For the record so that no one else under any illusion this:-

application("thing") = application("thing") + 1

is not threadsafe. In order ensure the value is updated correctly the
application object must be locked.
 
E

Evertjan.

Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:
(sigh) Well you're entitled to hold to whatever beliefs you want to.

For the record so that no one else under any illusion this:-

What record?
application("thing") = application("thing") + 1

is not threadsafe. In order ensure the value is updated correctly the
application object must be locked.

This is probably true, bot only probably so.

Have you any reason to be more sure than that?
 
A

Anthony Jones

Evertjan. said:
Anthony Jones wrote on 22 aug 2008 in
microsoft.public.inetserver.asp.general:


What record?


This is probably true, bot only probably so.

Have you any reason to be more sure than that?


I'm sorry you seem to me to be pre-disposed to reject any reason or facts I
present to you.

I have debugged at the machine level VB and VBScript applications.
I have built applications which act as scripting hosts (ASP is such an
application).
I have sufficient insight into what is going on under-the-hood to know that
what I've stated is a fact.

You are under the mistaken belief that ASP is somehow cleverer than it is.
ASP has no idea how a script runs (it doesn't even know what language it is
and certainly cannot influence implementation). VBScript when executed in a
script context created by ASP has no idea what ASP is so it has no way to
know that placing a critical section around the subject line of code would
be useful or needed.

This is called loose coupling and is well know approach to reducing code
complexity. The downside to such modularisation is that it makes the
computer stupid. What seems like a natural and intiutive thing to do the
human is completely beyond the computers grasp.
 
E

Evertjan.

Anthony Jones wrote on 23 aug 2008 in
microsoft.public.inetserver.asp.general:
I'm sorry you seem to me to be pre-disposed to reject any reason or
facts I present to you.

I am not, I constantly say that your idea is probably true,
but it is not true, simply because you say so.
I have debugged at the machine level VB and VBScript applications.
I have built applications which act as scripting hosts (ASP is such an
application).

Good for you, I have not read your c.v., you did not tell me your
credentials till now, you either are well versed in VB ans VBS, or at least
you think you are.

That all does not mean that others like me should believe you an your word.
I do not think for a moment that you are dishonest, btw.
I have sufficient insight into what is going on under-the-hood to know
that what I've stated is a fact.

Oh, Anthony, it is not about what you yourself think to be a fact,
that you have proved beond reasonable doubt.

However, your stand that that is enough reason to require that others
believe you, is, perhaps also because of your self expressed infallability,
unreasonable.

You did not express, that you tested the let assignment line in
interpreting global.asa to be internally multitreaded, or have looked at
the assembly or intermediate code for that.

You only express fact from inference that you believe it is generally that
way.
 
C

Chris Hohmann

Evertjan. said:
Anthony Jones wrote on 23 aug 2008 in
microsoft.public.inetserver.asp.general:


I am not, I constantly say that your idea is probably true,
but it is not true, simply because you say so.


Good for you, I have not read your c.v., you did not tell me your
credentials till now, you either are well versed in VB ans VBS, or at
least
you think you are.

That all does not mean that others like me should believe you an your
word.
I do not think for a moment that you are dishonest, btw.


Oh, Anthony, it is not about what you yourself think to be a fact,
that you have proved beond reasonable doubt.

However, your stand that that is enough reason to require that others
believe you, is, perhaps also because of your self expressed
infallability,
unreasonable.

You did not express, that you tested the let assignment line in
interpreting global.asa to be internally multitreaded, or have looked at
the assembly or intermediate code for that.

You only express fact from inference that you believe it is generally that
way.

http://msdn.microsoft.com/en-us/library/ms525184.aspx

From the Application.Lock documentation:
"A page does not need to lock the application object to edit the application
collection. If one page tries to edit the application collection without
locking and a second page also tries to edit the collection, no error is
sent by IIS and the Application object ends up in an inconsistent state."
 
E

Evertjan.

Chris Hohmann wrote on 27 aug 2008 in
microsoft.public.inetserver.asp.general:
http://msdn.microsoft.com/en-us/library/ms525184.aspx

From the Application.Lock documentation:
"A page does not need to lock the application object to edit the
application collection. If one page tries to edit the application
collection without locking and a second page also tries to edit the
collection, no error is sent by IIS and the Application object ends up
in an inconsistent state."

One would need to know what they mean by "not need" in this case, Chris.
How can a state ever be inconsistent?

And I doubt the documentation writers of MS always know what past
implementors did manage to put in the code. Remember the still present
"endif" allowance bug in VBS single line if-else-then?

The next interesting Q is, how we could ever test this inconsistency,
and more so prove the possible absense of such inconsistency.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top