Is it possible to test WCF throttling behaviour through Wcftest client?
If Yes then How?
I have a code below for ServiceHost
ServiceThrottlingBehavior stb = _servicehost.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if (stb == null)
{
stb = new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls = 1;
stb.MaxConcurrentInstances = 1;
stb.MaxConcurrentSessions = 1;
_servicehost.Description.Behaviors.Add(stb);
}
My service has a method such as:
public string ThrottlingCheck()
{
Thread.Sleep(new TimeSpan(0, 0, 0, 5, 0));//5 seconds
return "Invoke Complete";
}
In the event that you are using “web” bindings, you could use the open-source soapUI/loadUI test tools.
SoapUI is a free and open source cross-platform Functional Testing solution. With an easy-to-use graphical interface, and enterprise-class features, SoapUI allows you to easily and rapidly create and execute automated functional, regression, compliance, and load tests.
Reference:
http://www.soapui.org/
http://www.soapui.org/Load-Testing/using-loadui-for-loadtesting.html
As your request is taking 5 seconds, you can easily test this by invoking two operations at the same time by using two WCF Test Client or by opening two tabs in the same WCF client.
An integration test is certainly a better choice to check this behavior.
In addition, if your want to check that the behavior is really applied to your service, you could use WCF diagnostics such as WCF counters, especially "Percent of Max Concurrent XXX".
No, it is not possible using WCF Test Client. If you have Visual Studio Ultimate you can use load tests/performance tests to test the throttling.
http://blogs.msdn.com/b/rickrain/archive/2009/06/26/wcf-instancing-concurrency-and-throttling-part-3.aspx?Redirected=true
If you company has a copy of LoadRunner (hp product), you'll be able to build up enough fake transaction to actually test throttling.
In our case, we actually built a multi-instance, multi-threaded program to slam our web service with 1000+ concurrent (fake) users, each uploading 40 files. It was only then that we were able to see the throttling begin to take effect.
BTW, we tried a bunch of different combinations to see if we could tweek the settings and increase the performance, but in the end, the fastest we were able to get our web service running was under the default settings for throttling ... in other words, no throttling at all, just letting WCF manage the traffic and queue. Weird, huh?
Related
I'm currently developing a secure WCF service that will receive large numbers of calls, e.g. over 3000. My original approach has been to call the webservice methods using 'async' however rather quickly I realised that I needed to use the Task.WaitAll to ensure that all the calls were successfully made before the execution dropped out.
However, by utilising the WaitAll I'm now overloading the service with 70% of calls returning a combination of 'CommunicationException' and 'ServerTooBusyException' type messages. I have reviewed the WCF throttling options but still finding that these do not appear to have any direct effect, i.e. (Note: the webservice is being ran locally in this instance on Local IIS)
<serviceThrottling
maxConcurrentCalls="4096"
maxConcurrentSessions="65536"
maxConcurrentInstances="2147483647"/>
Running the webservice call sychronously works fine but runs too slow and I'm not terribly bothered about waiting for any callback from the webservice - I literally just need to 'fire and forget' these calls to the service.
Here's a rough example of what I'm doing on the client-side...
var numberOfIterations = 3000;
var allCalls = new List<Task>();
using (var service = new WebserviceServiceClient())
{
for (var n = 0; n < numberOfIterations; n++)
{
var someObject = new SomeObject(DateTime.UtcNow);
allCalls.Add(service.WebserviceMethodAsynch(SomeObject));
}
}
Task.WaitAll(allCalls.ToArray());
Can anyone advise on an elegant approach to bombarding a WCF webservice from a client without an attritional amount of failed calls?
Note: one approach would be utilise queues (in this case Azure Queues), ironically the service being called is performing some minor preprocessing prior to adding the object onto a queue to be picked up by a separate, more intensive process.
Thanks in advance
Your client and your web service are not on the same machine, right? Anyway, I believe you'd better use a Load Test to achieve the results that you're looking for:
http://www.sandeepsnotes.com/2013/05/load-and-performance-testing-of-wcf.html
I'm new to WCF. I've created a basic service and engineer tested it with the debugger and WCFTestClient. I've never written my own WCF client. Now I need to build unit tests for the service.
My classes:
IXService
CXService
CServiceLauncher
(Yes, I know the C prefix does not meet current standards, but it is required by my client's standards.)
My service functionality can be tested directly against XService, but I need to test CServiceLauncher as well. All I want to do is connect to a URI and discover if there is a service running there and what methods it offers.
Other questions I read:
AddressAccessDeniedException "Your process does not have access rights to this namespace" when Unit testing WCF service -
starts service host in unit test
WCF Unit Test - recommends
hosting the service in unit test, makes a vague reference to
connecting to service via HTTP
WCF MSMQ Unit testing -
references MSMQ, which is more detailed than I need
Unit test WCF method - I never knew I could auto generate tests, but the system isn't smart enough to know what to assert.
Test outline:
public void StartUiTest()
{
Uri baseAddress = new Uri("http://localhost:8080/MyService");
string soapAddress = "soap";
IUserInterface target = new CServiceLauncher(baseAddress, soapAddress);
try
{
Assert.AreEqual(true, target.StartUi());
/// #todo Assert.IsTrue(serviceIsRunning);
/// #todo Assert.IsTrue(service.ExposedMethods.Count() > 4);
Assert.Inconclusive("This tells us nothing about the service");
}
finally
{
target.StopUi();
}
}
I just needed to build a simple client.
Reference:
http://webbeyond.blogspot.com/2012/11/wcf-simple-wcf-client-example.html
Add Service Reference to test project
Add to test file:
using System.ServiceModel;
using MyTests.ServiceReferenceNamespace;
Code inside try is now:
Assert.AreEqual(true, target.StartUi());
XServiceClient client = new XServiceClient();
client.GetSessionID();
Assert.AreEqual(CommunicationState.Opened, client.State, "Wrong communication state after first call");
It's not a real answer so please take it easy.
I have been trying to do similar things and what I have learnt that integration testing is difficult. It is difficult because there are many hidden tasks that you need to do, such as:
Make sure you can run the tests regularly
Make sure integration tests can run on the test environment
Maintain different config files, as your environment will be different from the test one
Configure the thing that would automate running of integration tests (CI)
Pray there will be no changes to the paths, test environment, config, hosting platforms etc
Fight security permissions, as usually test thing is not able to host WCF services without admin permissions
Maintain your test harness
To me, this was huge headache and little gain. Don't get me wrong, integration testing is a positive thing, it just requires a lot of time to develop and support.
What have I learnt? Is that do not bother with integration testing of WCF services. Instead I write a lot of unit-tests, to test the contract, state and behaviour. By covering those, I can become sure in a quality of software. And I fight integration of WCF during deployment. This is usually a single battle to configure environment or VM and then next time, deployment goes nice and smooth in an (semi-)automated manner.
Most people would also automate deployment with Chef and alike, those tools can fully configure environment and deploy WCF service.
My project was standalone application then I decided to split it as client & server because I need powerful CPU usage and portability at the same time. Now multiple clients can connect to one server.
It was easy when 1 by 1 processing did the job. Now I need to call the same function & scope area again & again at the same time -via client requests-
Please can anyone give me some clue how should I handle these operations, I need to know how can I isolate clients' processes from each other at the server side? My communication is asynchronous, server receives a request and starts a new thread. I think I pass a parameter which one carries the client information, and another parameter as job id -to help client back, client may ask for multiple jobs and some jobs finish quicker than others-
Should I instantiate the class Process on each call? Can I use a static method, etc, any explanation will be of great help!
Below is the part of my code to need modification
class static readonly Data
{
public variable listOfValues[]
}
class Process
{
local variable bestValue
function findBestValue(from, to)
{
...
if(processResult > bestValue) bestValue = processResult
...
}
...
for(i=0;i<10;i++) startThread(findBestValue(i*1000,i*1000+999));
...
}
EDIT: I think I have to instantiate a
new Process class and call the
function for each client and ignore
the same client for same job since job is already running.
Not getting into your application design, since you didn't talk much about it, I think that your problem is ideal for using WCF WebServices. You get client isolation by design because every request will start in it's own thread. You can create WCF host as standalone application/windows service.
You can wrap your communication with WCF service and configure it to be PerCall service (meaning each request will be processed separately from others).
So you'll clean up your buisness logic from syncronization stuff. That's the best way, because managing and creating threads is not difficult to implement, but it is difficult to implement correctly and optimized for resources consumption.
I'm working on a Mono application that will run on Linux, Mac, and Windows, and need the ability for apps (on a single os) to send simple string messages to each other.
Specifically, I want a Single Instance Application. If a second instance is attempted to be started, it will instead send a message to the single instance already running.
DBus is out, as I don't want to have that be an additional requirement.
Socket communication seems to be hard, as windows seems to not allow permission to connect.
Memory Mapped Files seems not to be supported in Mono.
Named Pipes appears not to be supported in Mono.
IPC seems not to be supported on Mono.
So, is there a simple method to send string messages on a single machine to a server app that works on each os, without requiring permissions, or additional dependencies?
On my ubuntu (10.10 mono version: 2.6.7) I've tried using WCF for interprocess communication with BasicHttpBinding, NetTcpBinding and NetNamedPipeBinding. First 2 worked fine, for NetNamedPipeBinding I got an error:
Channel type IDuplexSessionChannel is
not supported
when calling ChannelFactory.CreateChannel() method.
I've also tried using Remoting (which is a legacy technology since WCF came out) with IpcChannel; example from this msdn page started and worked without problems on my machine.
I suppose you shouldn't have problems using WCF or Remoting on Windows either, not sure about Mac though, don't have any of those around to test. Let me know if you need any code examples.
hope this helps, regards
I wrote about this on the mono-dev mailing list. Several general-purpose inter-process messaging systems were considered, including DBus, System.Threading.Mutex class, WCF, Remoting, Named Pipes... The conclusions were basically mono doesn't support Mutex class (works for inter-thread, not for inter-process) and there's nothing platform agnostic available.
I have only been able to imagine three possible solutions. All have their drawbacks. Maybe there's a better solution available, or maybe just better solutions for specific purposes, or maybe there exist some cross-platform 3rd party libraries you could include in your app (I don't know.) But these are the best solutions I've been able to find so far:
Open or create a file in a known location, with exclusive lock. (FileShare.None). Each application tries to open the file, do its work, and close the file. If failing to open, Thread.Sleep(1) and try again. This is kind of ghetto, but it works cross-platform to provide inter-process mutex.
Sockets. First application listens on localhost, some high numbered port. Second application attempts to listen on that port, fails to open (because some other process already has it) so second process sends a message to the first process, which is already listening on that port.
If you have access to a transactional database, or message passing system (sqs, rabbitmq, etc) use it.
Of course, you could detect which platform you're on, and then use whatever works on that platform.
Solved my problem with two techniques: a named mutex (so that the app can be run on the same machine by different users), and a watcher on a message file. The file is opened and written to for communication. Here is a basic solution, written in IronPython 2.6:
(mutex, locked) = System.Threading.Mutex(True, "MyApp/%s" % System.Environment.UserName, None)
if locked:
watcher = System.IO.FileSystemWatcher()
watcher.Path = path_to_user_dir
watcher.Filter = "messages"
watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite
watcher.Changed += handleMessages
watcher.EnableRaisingEvents = True
else:
messages = os.path.join(path_to_user_dir, "messages")
fp = file(messages, "a")
fp.write(command)
fp.close()
sys.exit(0)
For your simple reason for needing IPC, I'd look for another solution.
This code is confirmed to work on Linux and Windows. Should work on Mac as well:
public static IList Processes()
{
IList<Process> processes = new List<Process>();
foreach (System.Diagnostics.Process process in System.Diagnostics.Process.GetProcesses())
{
Process p = new Process();
p.Pid = process.Id;
p.Name = process.ProcessName;
processes.Add(p);
}
return processes;
}
Just iterate through the list and look for your own ProcessName.
To send a message to your application, just use MyProcess.StandardInput to write to the applications standard input. This only works assuming your application is a GUI application though.
If you have problems with that, then you could maybe use a specialized "lock" file. Using the FileSystemWatcher class you can check when it changes. This way the second instance could write a message in the file and then the first instance notice that it changes and can read in the contents of the file to get a message.
I am looking for a way to use a WCF WebServiceHost without having to rely on the HttpListener class and it's associated permission problems (see this question for details).
I'm working on a application which communicates locally with another (third-party) application via their REST API.
At the moment we are using WCF as an embedded HTTP server. We create a WebServiceHost as follows:
String hostPath = "http://localhost:" + portNo;
WebServiceHost host = new WebServiceHost(typeof(IntegrationService), new Uri(hostPath));
// create a webhttpbinding for rest/pox and enable cookie support for session management
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.AllowCookies = true;
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IIntegrationService), webHttpBinding, "");
host.Open()
ChannelFactory<IIntegrationService> cf = new ChannelFactory<IIntegrationService>(webHttpBinding, hostPath);
IIntegrationService channel = cf.CreateChannel();
Everything works nicely as long as our application is run as administrator. If we run our application on a machine without administrative privileges the host.Open() will throw an HttpListenerException with ErrorCode == 5 (ERROR_ACCESS_DENIED).
We can get around the problem by running httpcfg.exe from the command line but this is a one-click desktop application and that's not really as long term solution for us.
We could ditch WCF and write our own HTTP server but I'd like to avoid that if possible.
What's the easiest way to replace HttpListener with a standard TCP socket while still using all of the remaining HTTP scaffolding that WCF provides?
Your problem is not related to HttpListener.
Your problem is:
* You have a oneClick application with limited permissions that
* Tries to open a Server port.
This is a contradiction. An untrusted limited permission application should NOT OPEN A SERVER PORT. This is why this is not allowed per definition.
Have you tried opening a normal socket port? It should not work either.
In general, limited trust end user applications should not host a web service ;)
That said, I ahve been in a similar situation trying to use WCF in a driver communication scenario - thank heaven my application runs with full permission.
You can easily compose your own stack via CustomBinding, using the higher level protocol stuff "as is", and rolling your own version of HttpTransport that isn't backed by HttpListener or IIS. Do-able, sure, but it's a lot of work. Take the existing HttpTransport bits apart with Reflector- there are a LOT of moving parts in there. You could probably hack up a simple PoC over Socket in a day or two if you don't need anything fancy like HTTPS or chunking, but making it robust will be tricky. Here's a good wrapup of a bunch of resources (may be a bit dated now).
You could also look at ripping apart enough of Cassini to make it hostable in your app, and loading the WCF pipeline in there (via .svc files and the service activation handler)- it'd require writing very little new code that way, but still give you a fairly robust and tested webserver.