Tuesday, November 10, 2009

Lab #16: Working with Reliable Sessions

Members:

Rafael Zuniga, Stephen Cave

Summary:

The purpose of this lab is to test how reliable sessions allow for clients to survive interruptions in the network.

Procedure:

We begin by opening the solution in Chapter6/ReliableSessions/ under the labs folder. We compile and run it to make sure it is working:



Which it is, so next we check out the configuration files and notice that we have WSHttpBinding with session support set to true. After we've noticed that we modify the configuration for the client to support diagnostics by adding a diagnostics section to the system.ServiceModel section. We also add a system.diagnostics section which will allow us to create a service log. We run the host and client again and this time after clicking the button several times we end up with a clienttrace.svclog in the c:\logs directory. Opening up the log reveals:



Next we download TcpTrace from this cool looking site, modify the client configuration to use port 8080 instead of 8000, and the host to use 8000. Running the project again with TcpTrace recording we send the first message from the client, stop the trace when we're about to send the second message, allow the second message to attempt to go through, start TcpTrace quickly, and finally let the client close the proxy. This time viewing the log we can see that there was an error when the client was attempting to send:



We can see that the message was successfully sent after TcpTrace was enabled again since the activity in the left pane shows that subsequent messages were processed successfully.

Observations:

  1. Reliable sessions are easy to implement and are very useful if your application requires state retention
  2. I thought TcpTrace would be similar to Wireshark but instead it's a simple re-director, kinda cool
  3. Apparently there's a file association with svclog so you don't have to dig around looking for svctraceviewer.exe

Tuesday, November 3, 2009

Lab #15: Protecting Shared Resources from Concurrent Access

Members:

Rafael Zuniga, Stephen Cave

Summary:

The purpose of this lab is to create an asynchronous client proxy that will issue concurrent requests to a singleton service.

Procedure:

We begin by opening the solution in the Chapter5/Concurrency found in the labs directory. A service has already been made which allows clients to add words to a dictionary. The service runs as a single instance using ConcurrencyMode set to Single as well. In order for our client to be able to use the service we must generate a proxy by running:

svcutil /a /o:proxy.cs /config:app.config http://localhost:8000

This will generate a client proxy to be used by our client application. Next we must edit the client to actually use the service. The client already includes the three buttons to call the service but we must implement the actual event handlers by adding the following:

MessagingServiceClient proxy = new MessagingServiceClient();

And filling in the event handlers for each of the three buttons. We also modify the close event to close the client proxy. Building the solution and running it we see the following when the client buttons are used:



Next we modify the concurrency mode to multiple and test again. This time instead of seeing the ordered service call we see multiple exceptions:



In order to prevent multiple service calls from attempting to access the same variable at once we must synchronize access. The MessagingService.cs is modified to include locking mechanisms. First we modify SendMessage1 by adding a try/finally statement in which a Monitor is used to lock the current service object. The SendMessage2 function is synchronized in a different way; instead of using a monitor we use the lock statement to gain a lock on the service object. The final function, SendMessage3, is synchronized using an attribute:

[MethodImpl(MethodImplOptions.Synchronized)]

The project is then recompiled and tested again. This time the results are the same as the first screen shot, that is, no exceptions are thrown and we see each of the calls. Since the currently example locks the whole service object it isn't very efficient if there are multiple resources that require access. Instead of locking the whole object, this time we modify the existing code to use a mutex. A new dictionary variable is added along with a mutex for each of the variables. The first two SendMessage funtions are modified to the first mutex in order to access the first dictionary and the third SendMessage function is modified to lock the second mutex when accessing the second dictionary. Rebuilding and running it gives us the same effect as in the first screen shot, that is, there are no exceptions thrown.

Observations:
  1. There are many ways to lock a resource: mutexes, monitors, the lock keyword, etc
  2. If there's more than one resource it's more efficient to lock it singly instead of locking the whole service object which prevents other clients from accessing other services
  3. If I remember correctly another way to lock a section of code is to use the lock keyword but on a lock dummy object which should only block access to that object and not the whole service
  4. Blogger has problems with some C# code so a lot of it has been omitted
  5. I bet it's those angle bracket things

Lab #14: Controlling Service Instancing

Members:

Rafael Zuniga, Stephen Cave

Summary:

The purpose of this lab is to show how service calls work with PerCall, PerSession, and Single instancing modes.

Procedure:

We begin by opening the solution in Chapter5/Instancing under the labs directory. After successfully building the solution we run the host and client testing out each of the services using no exception. Currently the host is set to serve PerCall so the variable value is not kept between each call by the client:


Services that support sessions display the following:



Next we test the exception handling for each of the types of bindings. The BasicHttpBinding and WSHttpBinding without session behave the same, that is after the exception the client is still able to call the host server. The same is not so with bindings supporting sessions, after the exception is thrown and displayed another error is displayed stating that the communication object has been faulted:



When calling the service using the client's fault button all of the services are able to recover and call again. Modifying the service by setting the InstanceContextMode to PerSession and running the tests again results in bindings without session support not retaining their variable value while those that do support sessions successfully increment the variable to 2. Next we modify the ServiceContract to disallow sessions by setting SessionMode to NotAllowed. This time if we attempt to run the project we are hit with an exception due to certain bindings requiring a session.



Since we can't run the project with the named pipe and TCP bindings we comment them out in the configuration file. Running the tests again we find that disallowing sessions is similar to setting PerCall since for each call, even if the binding supports sessions, the variable is initialized again to 1. Next we modify the service to require sessions. Again an exception is thrown since certain endpoints do not support sessions, such as BasicHttpBinding, so we must comment them out in the application configuration file. Running the tests again we find that the variable value is kept in between calls to the service. Next we modify the service to use a single instance and run the tests again. This time we find that the variable value is kept across all calls, including for bindings without sessions:



Observations:

  1. The usual access denied error for TCP connections, have to run Visual Studio with administrator permissions
  2. Bindings which use sessions fault when an exception is thrown unless you actually throw a fault exception
  3. This lab was one of the few that was actually problem free