Serializing a request for an ASP page containing COM objects

M

Max

Due to the behaviour of a particular COM object, I need to ensure that a
request for a particular ASP page is finalized before another request for
the page is processed. Does IIS have a way to ensure that subsequent
requests will be queued until the current request is completed?

If not, can IIS be configured to use seperate processes to satisfy requests
for a nominated ASP page?

Thanks in advance.

Max
 
B

Bobbo

Max said:
Due to the behaviour of a particular COM object, I need to ensure that a
request for a particular ASP page is finalized before another request for
the page is processed. Does IIS have a way to ensure that subsequent
requests will be queued until the current request is completed?

If not, can IIS be configured to use seperate processes to satisfy requests
for a nominated ASP page?

As far as I'm aware, you can only specify process isolation on a
per-application basis. This procedure varies with the version of IIS
you're using.

Here's the procedure for version 6 (my version):
http://www.microsoft.com/technet/pr...2ba-39fc-4332-bdb7-a0d9c76e4355.mspx?mfr=true
 
E

Egbert Nierop \(MVP for IIS\)

Max said:
Due to the behaviour of a particular COM object, I need to ensure that a
request for a particular ASP page is finalized before another request for
the page is processed. Does IIS have a way to ensure that subsequent
requests will be queued until the current request is completed?

If not, can IIS be configured to use seperate processes to satisfy
requests for a nominated ASP page?

Thanks in advance.

Hi Max, as long as you don't have more web servers that serve the same
website (ie url like www.yoursite.com) you can lock your page, through a
Mutex object.
A mutex, enables multiple processes on the same machine to synced single
access to a single event.
 
B

Bob Barrows [MVP]

Max said:
Due to the behaviour of a particular COM object, I need to ensure
that a request for a particular ASP page is finalized before another
request for the page is processed. Does IIS have a way to ensure that
subsequent requests will be queued until the current request is
completed?
If not, can IIS be configured to use seperate processes to satisfy
requests for a nominated ASP page?
If the object is not free-threaded, storing it in Application may accomplish
your goal. This is the reason we constantly advise against storing ADO
objects (such as Connections) in Application: they are apartment-threaded so
they can only service one thread at a time, in effect serializing all uses
of the object.
 
A

Anthony Jones

Bob Barrows said:
If the object is not free-threaded, storing it in Application may accomplish
your goal. This is the reason we constantly advise against storing ADO
objects (such as Connections) in Application: they are apartment-threaded so
they can only service one thread at a time, in effect serializing all uses
of the object.

It's a nice idea but the application object simply disallows
apartment-threaded objects.
 
A

Anthony Jones

Bobbo said:
As far as I'm aware, you can only specify process isolation on a
per-application basis. This procedure varies with the version of IIS
you're using.

Here's the procedure for version 6 (my version):
http://www.microsoft.com/technet/pr...2ba-39fc-4332-bdb7-a0d9c76e4355.mspx?mfr=true

On it's own it doesn't help serialise access to the page. It may be
possible to tweak the application metadata to allow only one worker thread
then only one request into the application can be processed at a time.

One approach might be to enable debugging. That limits the app to a single
thread but care needs to be taken that any configured debugger doesn't block
operation (e.g. Dr Watson style debugging is ok but script debugger will
just hang the process if there is an error).

If there is only one CPU then setting AspProcessorThreadMax to 1 might also
do it.

Anthony.
 
B

Bob Barrows [MVP]

Anthony said:
It's a nice idea but the application object simply disallows
apartment-threaded objects.
I'm not sure I'm following your point. Could you expand on what you mean by
"disallows"?
 
M

Michael D. Kersey

Max said:
Due to the behaviour of a particular COM object, I need to ensure that a
request for a particular ASP page is finalized before another request for
the page is processed. Does IIS have a way to ensure that subsequent
requests will be queued until the current request is completed?
If not, can IIS be configured to use seperate processes to satisfy requests
for a nominated ASP page?
Max
Use the Application.Lock and Application.Unlock methods:
....
Application.Lock
....
'Critical section of code.
....
Application.Unlock
....

While there may be several copies of that page executing, the lock
ensures that only one is be executing the critical section of code at
any time. If a page finds the Application object locked, it will wait.

It isn't necessary to store anything in the Application object. You're
merely using the Application object's methods as a mutex to enforce
serialized access to the critical section of code.

Of course, serializing access will result in queuing and will slow
response. So minimize the time and resources utilized in the critical
section of code, enter it as late as possible and exit it as soon as
possible.
 
M

Max

Bob Barrows said:
I'm not sure I'm following your point. Could you expand on what you mean
by "disallows"?

--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"
My thanks to Bobbo, Anthony, Egbert and Bob for their input.

Unfortunately I may have some input on the setup of our clients web server
but not on the machine it runs on. As I cannot guarantee a single
processor, I cannot use your "set AspProcessorThreadMax to 1" suggestion.

I am still looking at the suggestion to enable debugging although the
possibility of the process just hanging on the customers site would not be
acceptable.

I am interested in Anthonys suggestion to "tweak the application metadata to
allow only one worker thread" but am not sure which metadata values I would
need to set to accomplish this.

The COM object that I am using is marked as single threaded and doesn't
appear to have any protection when IIS makes overlapping requests for the
ASP page using it. We may be able to use a mutex but performance would be an
issue.

I have been looking into the use of a web garden (in IIS6) which appears to
offer multiple processes on the same application. Do you think that using a
web garden would be useful in this situation? Perhaps in combination with
allowing only one worker thread as suggested by Anthony?

Thanks in advance,

Max
 
A

Anthony Jones

Bob Barrows said:
I'm not sure I'm following your point. Could you expand on what you mean by
"disallows"?

<%

Dim o: Set o = Server.CreateObject("MSXML2.DOMDocument.3.0")

Set Application("x") = o

%>

ASP just errors saying that assigning this sort of object into the
application object is disallowed.
You can only assign free-threaded objects into the application object.

Assigning into the session is allowed but that will affiliate the session ID
with a thread and all requests containing that session cookie will only ever
be serviced be the affiliated thread (this doesn't help in the OP's case).
Over time this will mean requests will queue up to be serviced even though
worker threads are available because their affiliated thread is busy with
another request. What's really annoying is that even if the object
reference is only fleeting stored in the session object and then removed the
thread will still remain affiliated.
 
A

Anthony Jones

Michael D. Kersey said:
Use the Application.Lock and Application.Unlock methods:
...
Application.Lock
...
'Critical section of code.
...
Application.Unlock
...

While there may be several copies of that page executing, the lock
ensures that only one is be executing the critical section of code at
any time. If a page finds the Application object locked, it will wait.

It isn't necessary to store anything in the Application object. You're
merely using the Application object's methods as a mutex to enforce
serialized access to the critical section of code.

Of course, serializing access will result in queuing and will slow
response. So minimize the time and resources utilized in the critical
section of code, enter it as late as possible and exit it as soon as
possible.

It should be pointed out that this will affect all uses of application
locks. If the application is to contain other pages (not connected with the
problem in question) use application locks these pages will be affected
also.

IOW the Application object itself can be used as a single global mutex.
Personally I prefer Egbert's solution.
 
B

Bob Barrows [MVP]

Anthony said:
<%

Dim o: Set o = Server.CreateObject("MSXML2.DOMDocument.3.0")

Set Application("x") = o

%>

ASP just errors saying that assigning this sort of object into the
application object is disallowed.

Interesting. I've never tried that so I never encountered that error. I have
just confirmed what you are saying, however.

You can only assign free-threaded objects into the application object.

ADO objects aren't free-threaded (unless marked as such in the registry) ...
why does IIS allow people to store ADO recordsets and connections in
application?
 
A

Anthony Jones

Bob Barrows said:
Interesting. I've never tried that so I never encountered that error. I have
just confirmed what you are saying, however.



ADO objects aren't free-threaded (unless marked as such in the registry) ....
why does IIS allow people to store ADO recordsets and connections in
application?

ADO uses a free threaded marshaller in this case. Hence the object
reference the application stores is in fact a free threaded proxy for the
ADO object rather than a reference to the object itself. Of course as soon
as anything tries to call a method on the proxy the calling thread will
block while the call is marshalled across to the thread that originally
created the object. If that thread is busy with another request (or some
other marshalled call from yet another thread) then the call blocks.
Therefore as you say it is not a good idea to store ADO objects in the
application object.
 
B

Bob Barrows [MVP]

Anthony said:
ADO uses a free threaded marshaller in this case. Hence the object
reference the application stores is in fact a free threaded proxy for
the ADO object rather than a reference to the object itself. Of
course as soon as anything tries to call a method on the proxy the
calling thread will block while the call is marshalled across to the
thread that originally created the object. If that thread is busy
with another request (or some other marshalled call from yet another
thread) then the call blocks. Therefore as you say it is not a good
idea to store ADO objects in the application object.
OK, that makes sense ... thanks. We never stop learning.
 
M

Michael D. Kersey

Anthony said:
<%

Dim o: Set o = Server.CreateObject("MSXML2.DOMDocument.3.0")

Set Application("x") = o

%>

You failed to lock the Application object in your example, which should
read:
<%
Dim o: Set o = Server.CreateObject("MSXML2.DOMDocument.3.0") Application.Lock
Set Application("x") = o Application.UnLock
%>

Assuming, of course, that the object is free-threaded.
 
M

Michael D. Kersey

Anthony Jones wrote:
It should be pointed out that this will affect all uses of application
locks. If the application is to contain other pages (not connected with the
problem in question) use application locks these pages will be affected
also. IOW the Application object itself can be used as a single global mutex.

As clearly documented by Microsoft.
Personally I prefer Egbert's solution.

Certainly Egbert's is the most general solution. But no debugged code
was provided.

In it's favor, my suggestion is quick, easy to apply, clearly works as
designed by Microsoft and the tested code is provided above.

My suggestion will work until that mutex method is written and debugged.
Or even forever, if need be. [Yes, billions and billions of ASP pages
running until the _end_ _of_ _time_, bwaahaahaaahaaaa!]

My suggestion is certainly better than the two you suggested earlier:
1-enable debugging or
2-setting AspProcessorThreadMax to 1
which were both very amusing. Thanks for the laugh.

All in all, I think you're embarrassed that you missed this most obvious
suggestion, one designed by Microsoft. Reason I say that is that, in the
example you gave where you stored an object into the Application object,
you neglected to lock and unlock the Application object, a common newbie
error. Just a guess; I could be wrong, of course.
 
B

Bob Barrows [MVP]

Michael said:
Anthony Jones wrote:
It should be pointed out that this will affect all uses of
application locks. If the application is to contain other pages (not
connected with the problem in question) use application locks these
pages will be affected also. IOW the Application object itself can
be used as a single global mutex.

As clearly documented by Microsoft.
Personally I prefer Egbert's solution.

Certainly Egbert's is the most general solution. But no debugged code
was provided.

In it's favor, my suggestion is quick, easy to apply, clearly works as
designed by Microsoft and the tested code is provided above.

My suggestion will work until that mutex method is written and
debugged. Or even forever, if need be. [Yes, billions and billions of
ASP pages running until the _end_ _of_ _time_, bwaahaahaaahaaaa!]

My suggestion is certainly better than the two you suggested earlier:
1-enable debugging or
2-setting AspProcessorThreadMax to 1
which were both very amusing. Thanks for the laugh.

All in all, I think you're embarrassed that you missed this most
obvious suggestion, one designed by Microsoft. Reason I say that is
that, in the example you gave where you stored an object into the
Application object, you neglected to lock and unlock the Application
object, a common newbie error. Just a guess; I could be wrong, of
course.

Is there some history between you two here? This is verging on being
insulting (perhaps even crossing the line), and Im not sure the insult
was called for. From what I could see, Anthony was expressing a
preference for a technique, not disparaging yours, which he did
acknowledge would accomplish the OP's purpose.

I am sure that Anthony is aware of the need to lock Application, and
simply left it out of his example because he was sure I was aware of the
need to do that as well.
 
B

Bob Barrows [MVP]

Anthony said:
IOW the Application object itself can be used as a single global
mutex. Personally I prefer Egbert's solution.

How does one create a mutex in vbscript without using
application.lock...unlock?
I was not aware that thread could be created in scripting ...
 
A

Anthony Jones

Michael D. Kersey said:
Anthony Jones wrote:
It should be pointed out that this will affect all uses of application
locks. If the application is to contain other pages (not connected with the
problem in question) use application locks these pages will be affected
also. IOW the Application object itself can be used as a single global
mutex.

As clearly documented by Microsoft.
Personally I prefer Egbert's solution.

Certainly Egbert's is the most general solution. But no debugged code
was provided.

In it's favor, my suggestion is quick, easy to apply, clearly works as
designed by Microsoft and the tested code is provided above.

My suggestion will work until that mutex method is written and debugged.
Or even forever, if need be. [Yes, billions and billions of ASP pages
running until the _end_ _of_ _time_, bwaahaahaaahaaaa!]

My suggestion is certainly better than the two you suggested earlier:
1-enable debugging or
2-setting AspProcessorThreadMax to 1
which were both very amusing. Thanks for the laugh.

I agree. I was just enjoying thinking up mad ways to achieve this like I
said Egbert's is best if although better yet would be to design out the
requirement altogether.
All in all, I think you're embarrassed that you missed this most obvious
suggestion, one designed by Microsoft. Reason I say that is that, in the
example you gave where you stored an object into the Application object,
you neglected to lock and unlock the Application object, a common newbie
error. Just a guess; I could be wrong, of course.

It is of course possible that you are wrong. I've posted a question in
another branch perhaps you can enlighten this 'newbie' rather than just
being obnoxious. (Is that spelt right?)
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top