I want to add server-side retry behavior if something specific happens during operation.
Custom IOperationInvoker looks like a good candidate for this functionality, but...
Unfortunately instance on which operation should be performed is already created/resolved, so to correctly implement retry logic everyone should write stateless service implementations which is quite limiting, sometimes it's nice to have InstanceContextMode.PerCall mode and state which lives only during request lifetime.
Is there any place or possibility to force WCF to re-create/resolve service and invoke operation again?
Not so easy to imlement retry logic on your own. You will have to deal with a number of issues like those:
What if all attempts failed?
Should there be an interval between attempts?
What if you server is down between the first and second attempt?
etc.
Fortunately there is an out of the box solution which already does everything for you. Take a look at the MSMQ WCF binding.
It will put you contract object to the dead letter queue if you wish, so you can easyly keep track of such messages and even force to process them again.
You can set an interval between the attempts. So if you server is down for 10 minutes not all attempts are shot.
You can configure it to be durable. It will store the messages on disk, So when your server is back it will try to process the message again.
Etc. Take a look at the MSMQ binding you will find a lot of useful features.
Here's a good article about the queuing in WCF
So in the long run your design will be something like that:
Client Call -> MSMQ -> Service
Please note you don't have to make any changes to the code you have now at all, you just change the binding configuration and set up MSMQ which is fairly easy.
Just in case you can't use msmq binding directly with you client, you can always go with an special server side service which just puts the messages to the queue. So the design will be:
Client service -> HTTP -> QueueService (one method which puts messages to a queue) -> MSMQ -> ProcessService
Hope it helps!
Related
I have a web application that uses the jquery autocomplete plugin, which essentially sends via ajax a request containing text that has been typed into a textbox to our web server, once the web server receives this request, it is then handed off to rabbitmq.
I know that we do get benefits from using messaging, but it seems like using it for blocking rpc calls is a misuse and that something like WCF is far more appropriate in this instance, is this the case or is it considered acceptable architecture?
It's possible to perform RPC synchronous requests with RabbitMQ. Here it's explained very well, with its drawback included! So it's considered an acceptable architecture. Discouraged, but acceptable whenever the synchronous response is mandatory.
As a possible counter-effect is that adding RabbitMQ in the middle, you will add some latency to the solution.
However you have the possibility to gain in terms of reliability, flexibility, scalability,...
What benefit would you get from it? And in fairness if you put the message in the queue how is is synchronous? unless the same process that placed the message in the queue is the one removing it, but that is pretty much useless no?
Now, if all you want to do is place the message in the queue and process it later on is grand.
Also the fact that you had WCF to the mixture is IMHO a symptom that something is perhaps not clear enough. You could use WCF as an API gateway and use it to write the message to the queue so this is not really about WCF or Queues, but more like sync vs async.
The way you are putting your ideas, does not look alright to me.
I am trying to create a XAMLX service that I can fire and forget.
But how can I do something like that with a XAMLX? I have no access to the Contract Interface to add the [OneWay] attribute.
I thought that if I did something like
and put the response before the rest of the activities, the service would return at that point but it didn't. It returns only after the whole workflow is completed.
IS it possible to make the service return at that point and than continue with the processing. the other activities would not affect the returned value of the service.
Is it possible to create a fire and forget XAMLX service
Can I somehow make the client fire a normal service as oneWay, if the previous 2 points are not possible?
If you want one-way processing your Receive activity should not have any corresponding SendReply activity.
The reason the response isn't send immediately is the way the workflow scheduler works internally where it waits for the workflow to go idle. Nothing much you can do about the scheduler but if you add a Delay below the SendResponse with a duration of 1 millisecond.
As Ladislav said, remove the SendResponse and you get a one way message.
Not quite sure what you want with fire and forget. If you start a workflow service it will keep on running even if you don't send any more WCF requests to it. Even if it is long running or does other async work. No problems there.
I'm thinking of adding a queue function in a product based on a bunch of WCF services. I've read some about MSMQ, first I thought that was what I needed but I'm not sure and are considering to just put the queue in a database table. I wonder if somone here got some feedback on which way to go.
Basicly I'm planning to have a facade WCF service called over http. The facade service should only write all incoming messages to a queue to give a fast response to the calling system. The messages in the queue should then be processed by another component, either a WCF service or a Windows service depending om my choice of queue.
The product is running in a load balanced enviroment with 2 to n web servers.
The options I'm considering and the questions I got are:
To let the facade WCF write to a MSMQ and then have anothther WCF service reading from this queue to do the processing of the messages. What I don't feel confident about for this alternative from what I've read is how this will work in a load balanced enviroment.
1A. Where should the MSMQ(s) be placed? One on each web server? One on a separate server? Mulitple on a separate server? (not considering need of redundance and that data in rare cases could be lost and re-sent)
1B. How it the design affected if I want the system redundant? I'd like to be alble to lose a server (it never comes up online again) holding the MSMQ without losing the data in that queue. From what I've read about MSMQ that leaves me to the only option of placing the MSMQ on a windows cluster. Is that correct? (I'd like to avoid using a windows cluster fo this).
The second design alternative is to let the facade WCF service write the queue to a database. Then have two or more Windows services to do the processing of the queue. I don't have any questions on this alternative. If you wonder why I don't pick this one as it seems simpler to me then it is because I'd like to build this not introducing any windows services to the solution, that I beleive the MSMQ got functionality I don't want to code myself and I'm also curious about using MSMQ as I've never used it before.
Best Regards
HÃ¥kan
OK, so you're not using WCF with MSMQ integration, you're using WCF to create MSMQ messages as an end-product. That simplifies things to "how do I load balance MSMQ?"
The arrangement you use is based on what works best for you.
You could have multiple webservers sending messages to a remote queue on a central machine.
Instead you could have a webservers putting messages in local queues with a central machine polling the queues for new arrivals.
You don't need to cluster MSMQ to make it resilient. You can instead make your code resilient so that it copes with lost messages using dead letter queues, transactional queues, journaling, and so on. Hardware clustering is the easy option :-)
Load-balancing MSMQ - a brief
discussion
Oil and water - MSMQ transactional
messages and load balancing
After reading some more on the subjet I haver decided to not use MSMQ. It seems like I really got no reason to go down this road. I need this to be non-transactional and as I understand it none of the journaling or dead letter techniques will help me with my redundancy requirement.
All my components will be online most of the time (maybe a couple of hours per year when they got access problems).
The MSQM will only add complexity to the exciting solution, another technique and maybe another server to keep track of.
To get full redundance to prevent data loss in MSMQ I will need a windows cluster or implement send/recieve to multiple identical queues. I don't want to do either of those.
All this lead me to front my recieving application with a WCF facade accepting http calls writing to a database queue. This database is already protected from data loss. The queue will be polled by muliple active instances of a Windows Servce containing all the heavy business logic. With low process priority these services could be hosted on the already existing nodes used by the load balaced web application. If I got time to use MSMQ or if I needed it for another reason in my application I might change my decision.
I have a self hosted WCF 4.0 service with an HTTPS endpoint. I have method that writes some trace info after the message comes in. However, some messages are 400k in size, so there is a long wait conceivably between when WCF has it and my console app has it. How can I get a hook or interception layer in there so I can at least know when a message is first coming in?
I think there is a WCF Performance Counter related to this, so there must be some way to know...
Thanks for all ideas!
This is not the same as Detect WCF client open channel operation , this is about knowing when the HTTP traffic first comes in. Maybe its not that I need to monitor things on my WCF service, maybe I need to monitor some other WCF layer that is intercepting HTTP. Can anyone say?
What about making a custom MessageEncoder that simply wraps the default implementation, but overrides ReadMessage() and logs some information before calling the wrapped implementation (which creates a Message instance)? At this stage the full message isn't even fully streamed over the wire, hence it's a very early point of the processing pipeline. Obviously, however, you don't know anything about the message yet. But if you want to get a timestamp, that might be a convenient place to get it.
One option is implement the IDispatchMessageInspector interface for your service with your message size checking code in the AfterReceiveRequest method override. Your code should look something like the code in this blog post.
It's a really common pattern and I'm finding it a nightmare to implement!
--
The WcfIntegration sample is almost what I'm looking for in that it receives messages via a WCF endpoint. However, it receives messages back on itself. I want a separate subscriber.
So what I'm trying to do is merge the WcfIntegration and pub/sub samples.
The real need is for a website to call a class library, which then calls the WCF endpoint of the publisher.
A subscriber then picks receives a message that the publisher publishes, and does whatever with it.
--
Rob
You shouldn't need the interface IEventMessageService; NSB handles that for you.
In my local example, I mapped the messages to myself. For you this would be:
<UnicastBusConfig><MessageEndpointMappings>
<add Messages="MyMessages" Endpoint="MyPublisherInputQueue"/>
</MessageEndpointMappings></UnicastBusConfig>
You also need to move your Publish to the actual handler. Right now, it is only happening once (at startup):
public void Handle(EventMessage message)
{
bus.Publish(message);
bus.Return((int)ErrorCodes.None);
}
Make sure your infrastructure is primed, i.e. the queue is transactional, and MSDTC is running.
I'm willing to bet that since there is no mapping, once the service is called, it doesn't know where to put the messages (it calls Bus.Send() internally). I didn't look at the subscribers since that didn't seem to be the issue.
I've finally got it to work here:-
http://code.google.com/p/nservicebus-wcf-pubsub/downloads/list
Anyone is welcome to improve the code.