WCF Service & Request queueing - multithreading

Is using a handrolled POCO queue class using pseudo code
T Dequeue() {
lock(syncRoot) {
if(queue.Empty) Thread.Wait();
}
}
void Enqueue(T item) {
queue.Enqueue(item);
Thread.Notify();
}
For WCF is request queueing a scalable approach?

WCF service throttling will queue requests internally without any additional code. What are you trying to do?

No it is not, because as you add more servers your solution can not scale, and is not reliable.
You should be using the built in WCF Queue Binding.

Related

Service fabric more than one communication listener for service remoting

I am developing few micro services using Azure Service Fabric. I have some use cases which need the communication between micro services and I read about service remoting https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting. I just wanted to know is it possible to support more than one listeners in a SF application. E.g. I have an existing stateless web api SF application which is having a listener like below
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext, ServiceEventSource.Current, "ServiceEndpoint"))
};
}
To the above list, I need to add a ServiceRemotingListener so that I can expose some data from Micro service for others. Is it possible or anything wrong with approach. I have done the Reverse proxy based communication, but bit concerned with the performance(since I am planning to perform a real time read operation from Service 1 to Service 2).
In your CreateServiceInstanceListeners method you are returning an array of listeners. This means that it is possible to create multiple listeners. Just add it like you would with any other array:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext => this.CreateServiceRemotingListener(serviceContext), "RemotingListener"),
new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext, ServiceEventSource.Current, "ServiceEndpoint"))
};
}
Note that even though the listener name is an optional parameter, you have to give your listeners a name. I've also experienced some problems with the service proxy trying to connect to the other endpoint. In order to solve this declare the remoting listener first and your other listeners second.

Polling storage queue for messages using console app webjob

I wanted to create a console app as a WebJob using .NET Core but the WebJobs SDK is not yet available in .NET Core.
I've been advised to handle the scenario of reading messages from Azure Storage Queue manually. Looks like all the WebJobs SDK does is to keep polling the queue anyway.
Is the following code the basic idea in doing this? It doesn't look very sophisticated but not sure how it can be more sophisticated.
static void Main(string[] args)
{
var runContinuously = true;
while (runContinuously)
{
ReadAndProcessMessage();
System.Threading.Thread.Sleep(1000);
};
}
private static void ReadAndProcessMessage()
{
// Read message
ReadMessage();
// Process message and handle the work
HandleWork();
}
That will work. And I like simplicity.
The QueueTriggerAttribute makes use of a random exponential back-off algorithm to help minimize your transaction costs. If you'd like to trace through the logic of how this is accomplished, starting with the QueueListener class is a good way to go. Clone the project and then hop over to the RandomizedExponentialBackoffStrategy class.

Domain events for local consumption in DDD

I'm familiarizing myself DDD lately and trying to get hold of the key concepts and I have a query incase of publishing domain events for the local subscribers, so can I assume that the event publisher, takes care of both publishing to remote subscribers thro AQMP while also leveraging observable to publish it towards the local subscribers, is this a scalable solution? or is there a familiar pattern to handle this?(Also advise if there is a reactive solution to the prblm, may be RxJava or the likes)
The locality of subscribers, local or remote, should be completely transparent to the domain entity raising an publishing the event.
Your thoughts are very similar to design I use. I use a quite primitive version of a local event publishers, which communicate via messaging middleware (AMQP to propagate events to all other local publishers).
I'm not doing that in Java, but in fact, for the local event "bus" I use Rx.Net (reactive extensions have an almost identical API in all languages, so RxJava would work)
a simplified version with transaction support ripped out would look like this:
public class EventHub
{
private readonly ISubject<object, object> _messages;
public EventHub()
{
var _subject = new Subject<object>();
m_messages = Subject.Synchronize(_subject);
}
public void Publish<T>(T message)
{
m_messages.OnNext(message);
}
public IObservable<T> AsObservable<T>()
{
return m_messages
.ObserveOn(ThreadPoolScheduler.Instance)
.OfType<T>()
.Synchronize()
.AsObservable();
}
}
Adding remote capability would be adding another subscriber, which would subscribe to all events and route them to other local EventHubs, and also listen to other eventhubs and publish their events on the local hub. It would not change the EventHub component.

Multithreaded Singleton in a WCF - What is the appropriate Service Behavior?

I have a class (ZogCheckPublisher) that implements the multithreaded singleton pattern. This class is used within the exposed method (PrintZogChecks) of a WCF service that is hosted by a Windows Service.
public class ProcessKicker : IProcessKicker
{
public void PrintZogChecks(ZogCheckType checkType)
{
ZogCheckPublisher.Instance.ProcessCheckOrCoupon(checkType);
}
}
ZogCheckPublisher keeps track of which 'checkType' is currently in the process of being printed, and rejects requests that duplicate a currently active print request. I am trying to understand ServiceBehaviors and the appropriate behavior to use. I think that this is appropriate:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
One instance of the service that is multithreaded. If I am understanding things rightly?
Your understanding is correct.
The service behavior will implement a single multithreaded instance of the service.
[ServiceBehaviorAttribute(Name = "Test", InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple]
In a singleton service the configured concurrency mode alone governs the concurrent execution of pending calls. Therefore, if the service instance is configured with ConcurrencyMode.Multiple, concurrent processing of calls from the same client is allowed. Calls will be executed by the service instance as fast as they come off the channel (up to the throttle limit). Of course, as is always the case with a stateful unsynchronized service instance, you must synchronize access to the service instance or risk state corruption.
The following links provide additional Concurrency Management guidance:
Multithreaded Singleton WCF Service
http://msdn.microsoft.com/en-us/library/orm-9780596521301-02-08.aspx
Regards,

.NET 4.5 Increase WCF Client Calls Async?

I have a .NET 4.5 WCF client app that uses the async/await pattern to make volumes of calls. My development machine is dual-proc with 8gb RAM (production will be 5 CPU with 8gb RAM at Amazon AWS) . The remote WCF service called by my code uses out and ref parameters on a web method that I need. My code instances a proxy client each time, writes any results to a public ConcurrentDictionary, and then returns null.
I ran Perfmon, watching the thread count on the system, and it goes between 28-30. It takes hours for my client to complete the volumes of calls that are made. Yes, hours. The remote service is backed by a big company, they have many servers to receive my WCF calls, so the more calls I can throw at them, the better.
I think that things are actually still happening synchronously, even though the method that makes the WCF call is decorated with "async" because the proxy method cannot have "await". Is that true?
My code looks like this:
async private void CallMe()
{
Console.WriteLine( DateTime.Now );
var workTasks = this.AnotherConcurrentDict.Select( oneB => GetData( etcetcetc ).Cast<Task>().ToList();
await Task.WhenAll( workTasks );
}
private async Task<WorkingBits> GetData(etcetcetc)
{
var commClient = new RemoteClient();
var cpResponse = new GetPackage();
var responseInfo = commClient.GetData( name, password , ref (cpResponse.aproperty), filterid , out cpResponse.Identifiers);
foreach (var onething in cpResponse.Identifiers)
{
// add to the ConcurrentDictionary
}
return null; // I already wrote to the ConcurrentDictionary so no need to return anything
responseInfo is not awaitable beacuse the WCF call has ref and out parameters.
I was thinking that way to speed this up is not to put async/await in this method, but instead create a wrapper method where I can make things await/async, but I am not that is the smartest/safest way to work it.
What is a smart way to get more outbound calls to the service (expand IO completion thread pool, trick calls into running in the background so Task.WhenAll can complete quicker)?
Thanks for all ideas/samples/pointers. I am hitting a bottleneck somewhere.
1) Make sure you're really calling it asynchronously, rather than just blocking on the calls. Code samples would help here.
2) You may need to do this:
ServicePointManager.DefaultConnectionLimit = 100;
By default it only allows 2 simultaneous connections to the same server.
3) Make sure you dispose the proxy object after the call is complete so you're not tying up resources.
If you're doing things asynchronously the threadpool size shouldn't be a bottleneck. To get a better idea of what kind of problem you're having, you can use Interlocked.Increment and Interlocked.Decrement to track the number of pending calls and see if it's being limited somewhere.
You could also substitute your real call with a call to a very simple method that you know will not have any bottlenecks, to see if the problem is in the client or server.

Resources