Parallelization in WCF - wcf

I create WCF service with Spring.NET framework. This service is math service
and provide some computations for client apps.
I have question about WCF service parallelization on multi-core server. For simple
example I have server with 20 cores.
First here is a simplified code.
//WS interface
public interface IMatlabService
{
List<ResultData> Calculate(byte [] data);
}
//WS class definition
[ServiceBehavior(Namespace = "http://server.com/MatlabService")]
public class MatlabService: IMatlabService
{
public IMatlabManager MatlabManager{get;set:}
//web metod for math computations
public List<ResultData> Calculate(byte [] data)
{
var result = new List<ResultData>();
//do math work in another thread
Task<List<ResultData>> task = Task.Factory.StartNew<List<ResultData>>(() =>
{
return MatlabManager.CalculateWithFiniteElementMethod(data);
});
result.AddRange(task.Result)
return result;
}
}
public interface IMatlabManager
{
List<ResultData> CalculateWithFiniteElementMethod(byte [] data);
}
public class MatlabManager : IMatlabManager
{
public List<ResultData> CalculateWithFiniteElementMethod(byte [] data)
{
// do some math work
}
}
With Spring.NET I configure web service and manager class as not singleton.
Spring.NET XML configuration is here.
Matlab manager configuration:
<object name="matlabManager"
type="MatlabManager"
singleton="false"/>
MatlabService configuration:
<object name="matlabService"
type="MatlabService"
singleton="false">
<property name="MatlabManager" ref="matlabManager"/>
</object>
WCF service configuration from web.config
<behavior name="Behavior1">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<services>
<service name="matlabService"
behaviorConfiguration="Behavior1">
<endpoint address=""
binding="basicHttpBinding"
contract="IMatlabService"
bindingNamespace="http://server.com/MatlabService"/>
<endpoint contract="IMetadataExchange"
binding="mexHttpBinding"
address="mex"/>
</service>
</services>
SVC file.
<%# ServiceHost Language="C#" Debug="true" Service="MatlabServiceService" Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>
I believe for each client web metod call is created new instance of
MatlabService and WCF service work is do on new thread (WCF service
thread) and OS assign this thread to CPU core.
Or I am wrong and behavior create new service object per call I must
define in ServiceBehavior property InstanceContextMode?
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
In web method Calculate of MatlabService I use
System.Threading.Tasks for parallelization so math work is do in
another thread (Math thread).
For each call is created WCF service thread and in WCF service
thread is created Math thread.
I am not sure if this is true.
Maybe is needed allow multi-threading in WCF service in
ConcurrencyMode?
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode
= ConcurrencyMode.Multiple)]
I would like heard ideas how can parallelize web metod calls for multi core CPU.
I google it but not find any clear and usefull for me because I use Spring.NET framework for creation WCF service.

The default instance context mode is PerCall, so setting that explicitly is redundant.
Yes, you're creating an additional thread to do the math operations, but you're not gaining anything because you're blocking until the task is complete. In fact, it is less efficient because you have the overhead of creating and mangaging an additional thread.
Each web call is already serviced in its own thread.
The only place I can see to add additional parallel computing is within the implementation of:
MatlabManager.CalculateWithFiniteElementMethod(data)
However, that looks like a call to Matlab. If you can reimplement that method using parallel code, you might be able to eek out some performance gains.
Whatever you do, profiling is the key to understanding if you're actually making it faster. Remember - parallel doesn't always mean faster. There is overhead in synchronizing these operations and creating the threads for them.

Related

Refactoring God objects in WCF services

We came across a god object in our system. The system consists of public service exposed to our clients, middle office service and back office service.
The flow is the following: user registers some transaction in public service, then manager from middle office service checks the transaction and approves or declines the transaction and finally manager from back office service finalizes or declines the transaction.
I'am using the word transaction, but in reality those are different types of operations like CRUD on entity1, CRUD on entiny2... Not only CRUD operations but many other operations like approve/send/decline entity1, make entity1 parent/child of entity2 etc etc...
Now WCF service contracts are just separated according to those parts of the system. So we have 3 service contracts:
PublicService.cs
MiddleOfficeService.cs
BackOfficeService.cs
and huge amount of operation contracts in each:
public interface IBackOfficeService
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void SendEntity2(Entity2 item);
....
}
The number of those operation contracts are already 2000 across all 3 services and approximately 600 per each service contract. It is not just breaking the best practices, it is a huge pain to just update service references as it takes ages. And the system is growing each day and more and more operations are added to those services in each iteration.
And now we are facing dilemma as how can we split those god services into logical parts. One says that a service should not contain more then 12~20 operations. Others say some different things. I realize that there is no golden rule, but I just would wish to hear some recommendations about this.
For example if I just split those services per entity type then I can get about 50 service endpoints and 50 service reference in projects. What is about maintainability in this case?
One more thing to consider. Suppose I choose the approach to split those services per entity. For example:
public interface IEntity1Service
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void ApproveEntity1(Entity1 item);
[OperationContract]
void SendEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void FinalizeEntity1(Entity1 item);
[OperationContract]
void DeclineEntity1(Entity1 item);
}
Now what happens is that I should add reference to this service both in public client and back office client. But back office needs only FinalizeEntity1 and DeclineEntity1 operations. So here is a classic violation of Interface segregation principle in SOLID. So I have to split that further may be to 3 distinct services like IEntity1FrontService, IEntity1MiddleService, IEntity1BackService.
The challenge here is to refactor your code without changing large portions of it to avoid potential regressions.
One solution to avoid large business code with thousands of lines would be to split your interfaces/implementations into multiple parts, each part representing a given business domain.
For instance, your IPublicService interface could be written as follows (using interface inheritance, one interface for each business domain):
IPublicService.cs:
[ServiceContract]
public interface IPublicService : IPublicServiceDomain1, IPublicServiceDomain2
{
}
IPublicServiceDomain1.cs:
[ServiceContract]
public interface IPublicServiceDomain1
{
[OperationContract]
string GetEntity1(int value);
}
IPublicServiceDomain2.cs:
[ServiceContract]
public interface IPublicServiceDomain2
{
[OperationContract]
string GetEntity2(int value);
}
Now for the service implementation, you could split it into multiple parts using partial classes (one partial class for each business domain):
Service.cs:
public partial class Service : IPublicService
{
}
Service.Domain1.cs:
public partial class Service : IPublicServiceDomain1
{
public string GetEntity1(int value)
{
// Some implementation
}
}
Service.Domain2.cs:
public partial class Service : IPublicServiceDomain2
{
public string GetEntity2(int value)
{
// Some implementation
}
}
For the server configuration, there is still only one endpoint:
<system.serviceModel>
<services>
<service name="WcfServiceLibrary2.Service">
<endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary2.IPublicService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Same for the client: still one service reference:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPublicService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary2/Service1/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPublicService"
contract="ServiceReference1.IPublicService" name="BasicHttpBinding_IPublicService" />
</client>
</system.serviceModel>
This allows to refactor your server side by splitting your huge services into multiple logical parts (each part associated with a given business domain).
This doesn't change the fact each of your 3 services still has 600 operations, so the client proxy generation would still take ages. At least your code would be better organized server-side, and the refactoring would be cheap and not-so-risky.
There is no silver-bullet here, that is just code reorganization for better readability/maintenance.
200 services with 10 operations for each vs 20 services with 100 operations for each is another topic, but what is sure is that the refactoring would require way more time, and you would still have 2000 operations. Unless you refactor your whole application and reduce this number (for instance by providing services that are more "high-level" (not always possible)).
Having too many operation contracts doesn't make sense in a given service as it will leads to maintenance issues. Having said that if operations like Add(), Delete, Update(), AddChildItem(), RemoveChildItem(), etc are supposed to be together, then don't worry about operation contract going up to 30-40 in number. Because things that should be together should come out from a single interface (cohesion).
But 600 operations in a given service contract is really overwhelming number. You can start identifying the operations:-
That are required to be together
And that are not required to be together in a given service.
Based on this you can split the operations into different services.
If some of the methods are not used by client directly, then consider exposing the method based on the BUSSINESS logic (as also suggested by "Matthias Bäßler").
Say you want to expose the MoneyTransfer functionality. Then you are not required to expose
SendEmail()
DebitAccount()
CreditAccount(), etc in the service used by your web application.
So here you can expose just an aggregate service to your web application. In this case it may be IAccountService with methods like just
TransferMoney()
GetBalance(),
Internally in your implementation you can create other service which provides related operation like:-
SendEmail()
DebitAccount()
CreditAccount(), etc. required for IAccountService. MoneyTransfer() method.
This way, the number of methods in a given service will come down to a maintainable level.
I don't have experience with WCF but I think god classes and overloaded interfaces seem to be a general OOD problem.
When designing a system you should look for behaviour (or business logic) instead of data structures and operations. Don't look at how you're going to implement it but how the client would use it and how he would name it. In my experience, having the right names for the methods usually provides a lot of clues about the objects an their coupling.
For me the eye-opener was the design of the Mark IV coffee maker, an excerpt from "UML for Java Programmers" by Robert C. Martin. For meaningful names I recommend his book "Clean Code".
So, instead of building an interface of discrete operations like:
GetClientByName(string name);
AddOrder(PartNumber p, ContactInformation i);
SendOrder(Order o);
Do something like:
PrepareNewOrderForApproval(PartNumber p, string clientName);
Once you've done this, you also might refactor into separate objects.
Your problem is not so much a god object problem, as it is a service composition problem. God objects are problematic for different reasons than huge, crud-based service interfaces are problematic.
I would certainly agree that the 3 service contracts you have described are reaching the point where they are effectively unmanageable. The pain associated with refactoring will be disproportionately higher than if this was in-process code, so it's very important you take the correct approach, hence your question.
Unfortunately, service composability in soa is such a huge topic it's unlikely you'll receive massively useful answers here; though obviously useful, the experiences of others will unlikely apply to your situation.
I have written about this on SO before, so for what it's worth I'll include my thoughts:
I find that it's best if service operations can exist at a level where
they have business meaning.
What this means is that if a business person was told the operation
name, they would understand roughly what calling that operation would
do, and could make a guess at what data it would require to be passed
to it.
For this to happen your operations should fulfill in full or in part
some business process.
For example, the following operation signatures have business meaning:
void SolicitQuote(int brokerId, int userId, DateTime quoteRequiredBy);
int BindPolicyDocument(byte[] document, SomeType documentMetadata);
Guid BeginOnboardEmployee(string employeeName, DateTime employeeDateOfBirth);
If you use this principal when thinking about service composition then
the benefit is that you will rarely stray far from the optimal path;
you know what each operation does and you know when an operation is no
longer needed.
An additional benefit is that because business processes change fairly
rarely you will not need to change your service contracts as much.

ASP.Net Framework 4.0 WCF Concurrency

I am new to WCF, I am facing concurrency related issue in my hosted wcf service (.net framework 4.0) on IIS 7 / Windows 2008 server. I did all the possibilities after googling but still not able to fix my problem. I have created and inventory service which uses Entity Framework to fetch data from SQL Server tables like ItemHeadMaster, ItemMaster etc.
I referenced this WCF in my custom user search control for searching purposes. All is running well when 2 concurrent user hit search control placed on ASP.Net page.
My code looks like this:
namespace HIS.STORESERVICES
{
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class StoreMasterData : IStoreMasterData
{
public string GetAllItemHead(string strHospitalId)
{
using (DAL.ItemHeadMaster objItemHeadMasterDAL = new DAL.ItemHeadMaster())
{
List<STORE.MODEL.ItemHeadMaster> objItemHeamMasterList = new List<STORE.MODEL.ItemHeadMaster>();
objItemHeamMasterList = objItemHeadMasterDAL.GetAllItemHead(strHospitalId);
XmlSerializer Xml_Serializer = new XmlSerializer(objItemHeamMasterList.GetType());
StringWriter Writer = new StringWriter();
Xml_Serializer.Serialize(Writer, objItemHeamMasterList);
return Writer.ToString();
}
}
}
I did following after googling:
added in config but NO EFFECT
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>`
Added in config but NO EFFECT instead it gets more slow..
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" />
<serviceThrottling maxConcurrentCalls="32"
maxConcurrentInstances="2147483647"
maxConcurrentSessions="20"/>
Please help
Before WCF, to construct a service for cross process communications between processes in the same host, or in the same LAN, or in the Internet, you have to hand-craft transportation layers and data serializations for target environments and specific protocols.
With WCF, you just need to focus on creating data models (DataContracts after being decorated by attributes) and operation models (OperationContracts), and .NET CLR will "create" most if not all needed transportation layers and data serializations at run time, according to the configuration defined by you or the system administration in the target environment.
The defects in your codes:
WCF typically uses DataContractSerializer, NOT Xmlserializer to serialize things, and you don't need to call it explicitly, since the runtime will do it.
For most applications, you don't need ServiceBehaviorAttribute explicitly. You must know WCF in depth before using those advantage config which is not for beginner. And I rarely used them.
Your service interface function should comfortably return complex type rather the serialized text. In 99.9% of cases, if you have explicit serialization codes in WCF programs, the whole design is very dirty if not entirely wrong.
There are plenty of tutorials of creating Hello World WCF projects, and VS has one for you when creating a new WCF application. After you got familiar with Hello World, you may have a look at http://www.codeproject.com/Articles/627240/WCF-for-the-Real-World-Not-Hello-World
BTW, WCF serialization is very fast, check http://webandlife.blogspot.com.au/2014/05/performances-of-deep-cloning-and.html

Create proxy from a service with two contracts and endpoints

I am having trouble adding a service to my app.config that implements two contracts, and thus needs two endpoints.
See this question for a basic example of what I am trying to do:
WCF config for a service class implementing multiple contracts on separate endpoints
I really want to use the Service Reference in my clients to create and maintain the proxies for me, but when I try to do this with a service with two endpoints, I get the following error in the details when it tries to download the metadata:
Metadata contains a reference that cannot be resolved
Here is an example of how I have the service setup in my app.config in my wcf service library:
<service name="MyService">
<endpoint address="Address1" binding="wsDualHttpBinding" bindingConfiguration=""
name="Service1" contract="IService1" />
<endpoint address="Address2" binding="wsDualHttpBinding" bindingConfiguration=""
name="Service2" contract="IService2" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
name="mex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MyService/" />
</baseAddresses>
</host>
</service>
I feel like I am missing something simple. When I remove one of the end points, everything works fine. But if I have both end points in there, it can't resolve the metadata.
I have tried removing the base address and using full addresses, and with different ports but all paths I have tried lead to the same error.
Edit:
I should clarify why I am trying to do this in the first place I guess. I have a singleton service that I would like clients to be able to connect to. But there are some methods that I do not want clients to have access to. I thought separating the admin methods and the client methods into two separate contracts would be a good start.
To be even more clear, this is a game server. I want to be able to start new instances of the game server and send it a map and things like that.
I don't want gamers to have access to methods like LoadMap() or anything like that.
I really want to separate the methods and callbacks that the game client would have versus the methods and callbacks a match making service or server admin would have.
I also would like them to be separate contracts just to make it easier to read and maintain.
However, if there is a better way to do that, I am open for suggestions.
Took me a while to figure this out. I tore down my project and started rebuilding it from the beginning until it broke.
Apparently you cannot have two callback methods with the same name in your callback contracts if you try to do this.
Example:
public interface IService1Callback
{
[OperationContract(IsOneWay = true)]
void GetDataDone();
}
public interface IService2Callback
{
[OperationContract(IsOneWay = true)]
void GetDataDone();
}
If you then set these as the callback contracts on your service contracts like this:
[ServiceContract
(Namespace = "ServiceLib",
SessionMode = SessionMode.Required, CallbackContract = typeof(IService1Callback))]
public interface IService1
{
[OperationContract(IsInitiating = true)]
string GetData(int value);
}
[ServiceContract
(Namespace = "ServiceLib",
SessionMode = SessionMode.Required, CallbackContract = typeof(IService2Callback))]
public interface IService2
{
[OperationContract(IsInitiating = true)]
string GetOtherData(int value);
}
you will end up getting the error I mentioned in my original question.
I believe this is because the end points cannot figure out which callback contract the method comes from since they have the same name, so the metadata cannot resolve the reference.
Luckily I won't have callbacks with the same name, but I was stuck on this for a while because I had just setup some dummy methods to get things going.

WCF Design Approach

In my solution I have a Web application project and a Class library project that contains all the business logic and this also acts as a data access layer as I am using Entity Framework. This means that I have my edmx in this layer itself.
I have some 34 classes in this class library project and at an average 6 public methods in each class. These classes were getting called directly from the web application until now. No problems. Now I want to introduce the WCF Layer between the UI and the Business logic layer.
This means I will have to write wrapper methods for all my methods and expose them in a WCF Service. Does this mean that 34 * 6 = 204 methods (approximately) will appear in my service layer as Operation Contracts? As per OO, I think this is too large a class and so it feels wrong.
I know there is the Generic Service design pattern, but is there anything else that I am missing? Please advise.
You could try RIA services
http://www.silverlight.net/getstarted/riaservices/
What I'm using is this.
Create a WCF service
2.1. Point the SVC service to your implementation like:
<%# ServiceHost Language="C#" Debug="true" Service="BusinessLayer.Service" %>
BusinessLayer.Service is a class in your Class project. (reference in service is needed)
2.2. Point the service behavior to the contract:
<service behaviorConfiguration="ServiceBehavior" name="BusinessLayer.Service">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding" contract="BusinessLayer.IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
Edit the name (BusinessLayer.Service) and contract (Businesslayer.IService)
Create the contract interface BusinessLayer.IService (in your Class project):
namespace BusinessLayer
{
[ServiceContract]
public interface IService
{
[OperationContract]
void DoWork();
}
}
Modify the existing implementation which uses the interface (here is your existing code):
namespace BusinessLayer
{
public class Service:IService
{
Public void DoWork()
{
}
}
}
Why do you want to wrap the entire business logic layer in a WCF layer? I would look very closely at your reasons for this before jumping into this new approach. Do you have physical reasons that you simply can't get around like the business logic that accesses the database needing to be outside the DMZ? If so, ok. But if not, I'd think twice about going down this approach to start with.
Having said that, if you have no other choice, I'd avoid the monolithic WCF class that wraps every public method that your UI needs. First off, I'd introduce an interface on the web application side so that you can depend on abstracts in the UI rather than concrete implementations. Further, I'd look into using WCF REST services. You can use ServiceRoute's to avoid having to introduce any *.svc files. Then you can decorate the methods you want to expose with WebGet/WebInvoke attributes. This could potentially save a lot of coding.
Well,
We have a similar application but the number of classes is even higher. Your concern here is that you are reluctant to provide serialization (that is what is needed to pass objects by WCF) to core classes of your business logic server.
Provided you have a classical three-tier application where business logic server and a client access the same database. What you need to do is simply 1) ensure all your objects have a unique identification (this could be a string or Guid) and 2) pass object ID in all WCF calls. What that means is that you DO NOT expose any classes on WCF side.
This might be quite is safer since you have a web application.
It is wrong. Your services should not have much more than 20 operations. If you need exactly same operations you should create contract and service wrapper for each business class. This usually results in chatty interfaces which are not good solution for distributed scenario. In that case you should model your service layer as facade which compounds several calls into one.

Trouble using IAuthorizationPolicy with WCF and Castle-Windsor

I'm currently using Castle-Windsor with the WCF Facility to inject all my WCF services. I've just started adding permission requirements using a custom IAuthorizationPolicy, which seems to work when done on a per-method basis on the service, but when the service class itself is marked up with the requirements, I get an exception thrown.
I've set things up based on the example at How To – Use Username Authentication with Transport Security in WCF from Windows Forms. I didn't set up the custom HTTP Module class as I'm using an existing Membership implementation. My IAuthorizationPolicy implementation (HttpContextPrincipalPolicy) is essentially identical.
The essential part of my Web.config is:
<serviceBehaviors\>
<behavior name="MyBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="UserProvider">
<authorizationPolicies>
<clear/>
<add policyType="Website.FormsAuth.HttpContextPrincipalPolicy,Website"/>
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
Everything seems to work fine when I put the requirements on the method. This is being done like so:
[PrincipalPermission(SecurityAction.Demand, Role = RoleNames.USER_ADMINISTRATION)]
If this is on an OperationContract method, things work as expected. However, if it is moved to the class itself (which implements the ServiceContract) I get the following exception (with most of the extra stuff pruned out):
Castle.MicroKernel.ComponentActivator.ComponentActivatorException {
Message = "ComponentActivator: could not instantiate Services.UserService"
InnerException = System.Reflection.TargetInvocationException {
Message = "Exception has been thrown by the target of an invocation."
InnerException = System.Security.SecurityException {
Message = "Request for principal permission failed."
}
}
}
I've debugged and found that the constructor on HttpContextPrincipalPolicy is being called but Evaluate() is not when the demand is attached to the class. When it is attached to the method Evaluate() is being called. So at this point I've gone as far as my newbie .NET/WCF/Castle-Windsor skills will take me.
Is there a way to tell Castle-Windsor to invoke the service constructor while honoring the IAuthorizationPolicy? Or tell WCF that Evaluate() needs to be called for the creation of the class? Or is there some other way around WCF that does the same thing? I don't want to have to mark up every single method with the exact same bit of attribute declaration.
When you mark the class itself up with a PrincipalPermissionAttribute it's effectively saying to the runtime that at the point when the class is used the permission demand must be met. So now when Castle-Windsor is trying to instantiate the class, the permission demand is being made and of course it can't be fulfilled because the security context isn't established correctly at that point.
AFAIK, PrincipalPermissionAttribute is not supported on the class level for WCF due to the nature of its runtime even though it is allowed from a pure .NET perspective. Castle-Windsor is therefore unable to create your service instance for the same reason.