views:

123

answers:

1

My application overview is

alt text

ASP.Net webservice entertains requests from various applications for digital signing and verification via a client. The webservice will then route these requests to a smart card

When the system date changes, I want the following to happen.

  1. New request from the clients are made to wait

  2. Current work between webservice and smart card should get completed

  3. If there is any prior pending requests then they should get completed.

The reason why I need the above things to happen is, I need to close the existing sessions between the smartcard and webservice. This should happen only when there is no signing/verification of files. I cannot just close all the sessions as it might affect a file being processed by any one of the threads. So I need to make sure that there are no current active threads between webservice and smart card.

I wrote a piece of code which gives the total number of active threads between webservice and smartcard.

int vWorkerThreads,vWorkerThreadsMax;
int vPortThreads,vPortThreadsMax;
System::Threading::ThreadPool ^ vThreadPool;
vThreadPool->GetAvailableThreads(vWorkerThreads, vPortThreads);
vThreadPool->GetMaxThreads(vWorkerThreadsMax, vPortThreadsMax);
ActiveThreadCount = vWorkerThreadsMax - vWorkerThreads;

This means, I also need to make the client requests wait?

CLEANUP MECHANISM: Close the PKCS#11 API using C_CloseAllSessions and C_Finalize call which will free up the library so that it cleans all the session objects. This should be done once everyday.

Any ideas on how I can perform such a task?

UPDATE:

I could have been much more clearer in my query. I want to make it clear that my aim is not to shutdown the ASP.NET webservice. My aim is to reset the smartcard. As I am accessing the smartcard via ASP.NET webservice, I need a mechanism to perform this task of resetting the smart card.

I am giving the current process below

  1. Client detects Date change, At midnight
  2. Client calls the function WebService_Close_SmartCard
  3. Web Service receives the request WebService_Close_SmartCard and in turn calls PKCS11_Close_SmartCard. This Call will be served via one of the available threads from the Thread Pool. PKCS11_Close_SmartCard will close all the existing current sessions with the smartcard.
  4. At this point, I want to make sure that there are no threads with function calls such as PKCS11_DigitalSign_SmartCard/ PKCS11_DigitalVerify_SmartCard talking to smartcard, as PKCS11_Close_SmartCard will abruptly end the other ongoing sessions.

PS: I am new to ASP.NET and Multithreading.

+4  A: 

The question was updated in a big way, so bear with me...

Given that no threads are being created directly\indirectly by your web method code:

Quesiton So you are not explicitly creating any new threads or using ThreadPool threads directly\indirectly, you are simply receiving calls to your web method and executing your code synchronously?

Answer Yes, you are correct. There is a client API which calls the webservice. Then the webservice manages the threads automatically(creats/allocates etc) inresponse to the client's demands.The webservice talks to a smart card by opening multiple sessions for encryption/decryption.

It is more helpful to rephrase the original question along the lines of "requests" rather than threads, e.g.

When the system date changes I want to re-start my ASP.NET application and ensure that all requests that are currently executing are completed, and that any outstanding\queued requests are completed as well.

This is handled automatically as there is a concept of a request queue and active requests. When your ASP.NET application is restarted, all current and queued requests are completed (unless they do not complete in a timely fashion), and new requests are queued and then serviced when a new worker process comes back up. This process is followed when you recycle the Application Pool that your ASP.NET application belongs to.

You can configure your application pool to recycle at a set time in IIS Manager via the "Recycle" settings for the associated Application Pool. Presumably you want to do this at "00:00".

Update

I think I can glean from your comments that you need to run some cleanup code when all requests have been serviced and then the application is about to shut down. You should place this code in the global "Application_End" event handler.

Update 2

In answer to your updated question. Your requirements are:

When the application is restarted:

  1. New request from the clients are made to wait
  2. Current work between webservice and smart card should get completed
  3. If there is any prior pending requests then they should get completed.

This is supported by the standard recycling pattern that I have described. You do not need to deal with request threads yourself - this is one of the pillars of the ASP.NET framework, it deals with this for you. It is request orientated and abstracts how requests are handled i.e. serviced on multiple threads. It manages putting requests onto threads and manages the lifeclyle of those requests when the application is recycled.

Update 3

OK, I think we have the final piece of the scenario here. You are trying to shut down ASP.NET from your client by issuing a "CLOSED" web service call. Basically you want to implement your own ASP.NET shut down behaviour by making sure that all current and queued request are dealt with before you then execute your clean-up code.

You are trying to re-invent the wheel.

ASP.NET already has this behaviour and it is supported by:

a. Application Recycling It will service outstanding requests cleanly and start-up a new process to serve new requests. It will even queue any new requests that are received whilst this process is going on.

b. Application_End A global application event handler where you can put your clean-up code. It will execute after recycling has cleanly dealt with your outstanding requests.

You do not need your "CLOSED" command.

You should consider letting IIS recycle your application as it has support for recycling at a specified daily time(s). If you cannot configure IIS due to deployment reasons then you can you use web.config "touching" to force a recycle out-of-bounds of IIS:

a. Have a timer running in the server which can check for the date change condtion and then touch the web.config file.

b. Still have the client call a "CLOSED" web method, but have the "CLOSED" method just touch the web.config file.

IIS, then "a" are the most desirable.

Honestly Microsoft have already thought about it. :)

Update 4

@Raj OK, let me try and rephrase this again.

Your conditions are:

  1. You have a requirement to reset your smartcard once a day.
  2. Before resetting your smartcard, all current and queued web service requests must be completed i.e. the outstanding requests.
  3. After outstanding requests are completed, you reset your smartcard.
  4. Any new requests that come in whilst this process is happening should be queued and then serviced after the smartcard has been reset.

These conditions allow you to complete existing requests, queue any new requests, reset your smartcard, and then start processing new requests after the card has been reset.

What I am suggesting is:

  1. Place your smartcard reset code in "Application_End".
  2. Configure IIS to recycle your application at "00:00". Ensure that in advanced settings for the associated Application Pool that you configure "Disable Overlapped Recycle = True".
  3. At "00:00" application recycling ensures that all current and queued requests will be completed.
  4. After "00:00" application recycling ensures that all new requests will be queued whilst requests in "3" are completed and the application performs shutdown steps.
  5. After requests in "3" are completed, "Applicaton_End" will be called automatically. This ensures that your smartcard is reset after all current requests are completed.
  6. Application recycling ensures that your application is re-started in a new process, and that new requests queued in step "4" start to be processed. The important thing here is that your reset code has been called in "5".

Unless there is some detail missing from your question, the above appears to meet your conditions. You wish to do "x,y,z" and ASP.NET has built-in support which can be used to achieve "x,y,z" and gives you mature, guaranteed and well-documented implementations.

I am still struggling to understand why you are talking about threads. I do multi-threaded development, but talking about threads instead of requests when thinking about ASP.NET adds unnecessary complexity to this discussion. Unless your question is still unclear.

Perhaps you are missing the point I'm making here. I am drawing a parallel between the behaviour you require when you call "CLOSED" from your client application, and what happens when you recycle an application. You can use recycling and "Application_End" to achieve the required results.

I am trying to help you out here, as trying to implement this behaviour yourself is unnecessary and non-trivial.

chibacity
Can you please explain what you mean by directly/indirectly?>>Given that no threads are being created directly\indirectlyIn my case, when everytime, the client triggers an initialisation function, i beleive a new thread is created, if there are no current threads available.In terms of process rephrasing, i notonly want to clear the current process, i also want to not to allow the incoming requests. I need to put a lock on the current cleaning up process. Does System::Threading::BeginCriticalRegion will help?
Raj
@Raj If by "the client triggers an initialisation function" you mean the client makes a web service call, then what is happening here is that a new request is being created and yes that will be executed on a request thread. The recycling mechanism I have described will ensure that current and queued requests are completed when you recycle. Any new requests will be queued until the recycle has finished. If your client is making initialization\web services calls sequentiality, I'm not seeing any really complex behaviour here.
chibacity
@Raj Could you explain in more detail what your cleanup process is - perhaps edit your question with a description and some code. I think that maybe your question is too abstract and I'm missing something.
chibacity
@Raj A good description of client\server communications and cleanup lifecycle would be helpful.
chibacity
@chibacity. I have added more details. thanks. I am doing the cleanup from the smart card point of view rather than the webservice cleanup. Webservice for me is just the medium which talks to my smartcard.
Raj
@Raj Super update to the question. One question, is each web service call a unit of work that is independent of all other calls from a client, or are there dependencies between calls? Are the web methods stateful?
chibacity
@Raj I have updated my answer. I think the core thing here is grokking that the ASP.NET runtime abstracts the concept of thread management with requests. You do not deal with the request threads yourself, this is something the Framework is designed to do for you.
chibacity
@Chibacity I understand the concept of recycling. In my case, during cleanup ie when the client detects date change, it throws a call called close to the webservice. This call should be handled only after all the current requests are handled. If this is not the case, then it will terminate the already ongoing process, say sigining/verifying.; This is the aspect i beleive will not allow me to use the reclycling. So YES, This call CLOSE depends on other calls like Sign/Verify. I donot understand what you mean by stateful? Thanks
Raj
@Raj You are missing a very crucial point I detailed in my answer. You get IIS to manage recycling for you at the specified time. It is all there for you and baked in. You do not need to try and do this work yourself. They already thought of this.
chibacity
@Raj Putting the responsibility on the client to handle the server's lifecycle does not appear to be a good separation of responsibilities. The server should be responsibly for itself via IIS. If this is not possible e.g. you cannot configure IIS in your deployment scenario, then you could either get the server to run a timer and check for the date change, or you could still do this from the client. In any case if you "touch" the web.config file as part of your CLOSED call, or on a server timer, then it will cause the application to recycle itself and you will get a clean shut down.
chibacity
@Chibacity Many thanks for participating in this query. I have gone through a lot of information pointed out by you interms of recycling. I have actually updated my query with some more information. My aim is to reset the smart card and not the webservice. Since i am accessing the smartcard via webservice, i require a mechanism to do so. I think, recycling helps to maintain the health of the threads without affecting the ongoing process. But in my case, one the threads(PKCS11_Close_SmartCard) will actually shutdown the smart card. If this thread gets in before the other threads gets done.
Raj
@Raj I was trying to draw a parallel between what you want to acieve and what happens when an ASP.NET application shuts down as part of recycling - there is a pattern. I have updated my answer and tried to spell things out more clearly.
chibacity
@chibacity I now understand the concept. I sincerely thank you for your time and effort.
Raj
@chibacity i donot find an advanced setting in IIS6.0 where i can set this value up, "Disable Overlapped Recycle = True". I am able to find this property using metabase explorer and using cmd line CScipt.Exe adsutil.vbs SET w3svc/AppPools/DisallowOverlappingRotation "1"; But this cmd line allows me to do it for the whole of the Application pools rather than just my pool. Can you please point me on how i can find this "Disable Overlapped Recycle = True" in Advanced setting? Thanks
Raj
@Raj This link shows how to disable OverlappedRecylce for a specific application pool: http://serverfault.com/questions/84620/disabling-overlapped-recycling-in-iis-6-0
chibacity
@Chibacity Thanks for the link. If you look at the conversations in the link, it indicate that the scripts don't work for individual app pools.
Raj
@Raj Well it is an unaccepted answer actually where you read that. I presume you have tried it and it does not work. Do the decent thing, vote it up and add a comment me old china. :) Is there any real reason why you cannot just turn this off for all application pools? I am using II7, so can't really look into this too further. Perhaps you could strat a new question on ServerFault, point back to the old answer and say it doesn't work. Cheers, T.
chibacity