We've built Workflow Service that operates as State Machine.
One of the possible WCF calls into Workflow Service, causes Workflow to return to the same State it was before (starting State and ending State is the same as no condition has been met to move to new state).
What we've noticed is that during state transition, any other request sent to Workflow Service ends up with communication error - no endpoint listening on that port. Once the Workflow ends state transition, same request to Workflow Service can be done again.
What it seems to us is that during state transition, all listening endpoints on Workflow Service are severed.
How to deal with this? Clearly, we can capture the exception on client side, and do a retry, but is there a better, built in option?
We've looked into Buffered Receive option, but it seems that one is making a queue, meaning that it would even accept messages for the State that is not even reached yet.
Related
What is the proper way to push out WCF service updates? Right now we just use the file system publish method that deletes all existing files prior to publish. This has to be done at say 2am so we don't interrupt end users. However, what if we HAD to push an update out middle of the day?
Is this where wrapping ClientBase with timed retries comes in handy? Thus the client's call while we're deploying initially fails, but it will re-try and succeed a second or so later (in theory)? Thanks in advance.
so you can inspect the Client.open method, or any business-method the client calls from the Service. Here you can for example, build a request channel (implements IRequestChannel) and a channelFactory to create a simple channel to the service, and then try to establish a Connection. If the service is not reachable an exeption is thrown. You can repeat this Kind of "probing" the service in a while Loop or something else. At the end, the clinets Open() Method or the busines method will wait until the service is reachable, and then it will continue. If the service is reachable you will jump out of the behavior and continue in business-code.
So the key is to implement a ClientBehavior for the Client, then in the validate-method build a ChannelFactory with a RequestChannel and try to connect to the service. This connection is somehow tried in a while Loop. If the connection will be accepted at the e.g. 4th time, the loop will be ended, the behavior closed and the busines-code will continue.
If you have any further question, feel free to ask me.
I've got an iOS application which uses a STOMP Client to talk to RabbitMQ. The application loads a lot of state during startup, and then keeps that state in sync by receiving updates published on STOMP. Of course, if it loses its connection, it can no longer be sure it's in sync, and therefore has to re-load that large initial blob. Any kind of network interruption triggers this behavior and makes my customers sad.
There are a lot of big-picture ways to fix this (and I'm working on them) but in the meantime, I'm trying to use persistent queues to solve this problem. The idea is that the server will create a queue, bind it to the appropriate topics, and then start building the large startup bundle. When finished, it will hand everything off to the client. The client will set itself up with the startup bundle, open a subscription to the queue, and then process any updates which happened while the server was getting things ready. Similarly, if the client should become disconnected, it can simply reconnect and resume reading the messages it finds in the queue.
My problem is that while the client successfully receives messages sent after it connects, if there were any messages in the queue before it connected, they are not read. Likewise, if the client becomes disconnected, when it reconnects, it won't see any messages which arrived while it was away.
Can anyone suggest how I might get the client to be able to read those missing messages?
It turns out what was happening was that the STOMP adapter was consuming the messages but failing to deliver them. Thus, when the client reconnected, it wouldn't have any messages waiting for it.
To fix the problem, I changed the "ack" setting on the subscribe request to "client", meaning that STOMP shouldn't consider the message delivered until the client sends back an ACK frame. By changing my client appropriately, messages now get delivered even after the client has been away.
As I asked here, I have an orchestration that is started by a public port published as a web service. Everytime this service is called the orchestration starts
I need to start the orchestration every 30 minutes too.
I ended up using the Scheduled Task Adapter to call my own port. I created a scheduled receive port that creates messages every given time, and a send port that with a filter, receives messages from the port and send them to the web service port
Orchestation starts correctly, but there is an error:
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
After researching, I found out that Biztalk doesn't like one-way web services (even if this web-service was generated by "Biztalk Web Service Publishing Wizard")
I found solutions like a WCF-proxy, but I was wondering if I could just configure the orchestration webservice to be two-way (in the wizard you can force it) and then call it the way i'm doing now. I'm trying but still receiving similar errors
Anyone had a similar issue?
Thanks
Add a Listen shape to the start of your Orchestration, you can then have 2 (or more) parallel Activating Receive shapes.
Connect the secondary Receive shape to a new one-way logical port (Specify-later)
Once deployed, hook your Scheduled Task Adapter up to the one-way port, so it receives the regularly scheduled message.
As always with BizTalk, there is more than one way to de-fur a feline, but this was the first to come to mind.
I have a duplex WCF service with sessions enabled, and I'm trying avoid fault state exceptions on the client.
I found several discussions arround this topic, but all I have found suggest to recreate the client proxy or channel. Non is focus in duplex services with session enabled.
My problem with that approach is that there is one session per client in the server, and each client has only one instance of the service proxy (singleton service proxy). Because it is duplex, in the client side several objects are listening to events on that service instance (messages sent from the server to the client).
If the service is in faulted state, it can not be used any more. If I discard that instance and create a new one, I'm finding it hard to hook up all the event handlers again to this new instance.
Should I wrap the service and every time an object hooks up for an event, store the handler in a list (so that I can re hook it when service is recreated)? Seems to be lost of code, easy to leak memory...
Is there a way to just restart the client proxy / channel, without discarding all the proxy instance? (I'm using the VS generated proxy)
Any ideas?
Thanks,
MAB
You cannot restart the proxy. The only recovery from faulted state is aborting current instance and recreating the new one. On the client side you must correctly unregister everything dependent on your proxy instance, create new instance and register everything again. This whole operation must happen once you get the exception about channel in faulted state (= when you try to call the service). After recreation you must call the service again.
On the service side the instance is either already dead (that caused the faulted state of the channel) or it will die after session timeout. You must also handle faulted exception when you try to callback on the faulted channel by removing the channel from your known clients and unregistering anything dependent on that channel.
Imagine the following setup: a Silverlight client tunnels a serialized command over the network using a WCF service which in turn deserializes the command and sends it using NServiceBus to a generic host which is responsible for processing the command. The WCF service has - upon sending the command - registered a callback to be invoked. The generic host validates the command and 'returns' an error code (either 0 == success or >0 == failure).
Note: The WCF service is modelled after the built-in WCF service. The difference is that this WCF service receives a 'universal command' (not an IMessage), deserializes it into a real command (which does implement IMessage), and consequently sends the deserialized command off to the bus.
When unexpected exceptions occur, the command gets (after a certain amount of retries) queued in an error queue. At this point, the initiating WCF service sits there idle, unaware of what just happened. At some later point, the Silverlight client will time out according to the WCF client proxy configuration.
Things which are fuzzy in my head:
Does NServiceBus handle this scenario in any way? When does the timeout exception get thrown (if at all)? Or is this something exclusive to sagas?
Presuming I use [OperationContract(AsyncPattern=true)], are there any WCF related timeout settings that will kill the service operation? Or will the EndXXX method be somehow called? Or will it sit there forever, leaking, waiting for something that will never come?
Ways to proceed:
reuse existing timeout mechanisms, provided things don't leak.
build my own timeout mechanism between the wcf service and nservicebus.
notify the wcf service somehow when the command lands in the error queue.
build my own async notifcation mechanism using full blown callback message handler in the WCF service layer.
Things I've done:
run the example provided with NServiceBus.
spiked the happy case.
Any guidance on how to proceed is welcome, be it blog post, mailing list entries, ...
Some motivations for picking my current approach
I'm trying to leverage some of the scalability advantages (using distributor in a later phase) of NServiceBus.
I don't want to host a gazillion WCF services (one for each command), that's why I cooked up a bus-like WCF service.
Even though this is somewhat request/response style, I'm mostly concerned with gracefully handling a command reply not coming through.
You can develop any sort of message type you desire, IMessage is simply a marker interface. If you inspect the WSDL file that the service mex endpoint provides, there is no reference to IMessage, therefore you can define any command you like in you service. That being the case you should be able to use the provided WCF host.
I was able to reproduce the issue you describe using the built-in WCF hosting option. When an exception is thrown, the entire transaction is rolled back and this includes the Bus.Return, and therefore the service never gets a response.
I found a hack around this that I could provide, but I recommend reconsidering how you are using the service. If you are truly looking to do some expensive operations in a separate process then I would recommend in your WCF endpoint that you do a Bus.Send to a different process altogether. This would ensure to your client that the command was successfully received and that work is in progress. From there it would be up to the server to complete the command(some up front validation would help ensure its success). If the command was not completed successfully this should be made known on another channel(some background polling from the client would do).