NetTcpBinding with Streaming and Session - session

I’m trying to set up a WcfService with the use of NetTcpBinding. I use Transfer mode Streamed since I will transfer large files. I need to use Session, and I have read that NetTcpBinding supports this, but when I turn it on like:
SessionMode=SessionMode.Required
I get the error:
System.InvalidOperationException: Contract requires Session, but Binding 'NetTcpBinding' doesn't support it or isn't configured properly to support it.
Does anyone know what I have to do to make NetTcpBinding work with sessions?
Thanks for any help :)

You've no doubt solved this - but for others that come across it (as I did)...
According to "Programming WCF Services" by Juval Lowy - you can't use streaming with a contract that is configured SessionMode.Required. See page 243
Neither can you use NetTcpBinding with reliable messaging with streaming.
It doesn't elaborate as to why.
One workaround might be to split the operations that require session mode into a separate contract and the streaming operations into another.
Then implement a unique ID for each client (unique GUID for the lifetime of the client app) which is passed in the non-streaming interface as a RegisterSession(Guid mySessionId) operation.
When sessions are created on the server - they can register with a session manager object which stores the GUID, SessionContractImplemenation pair in a Dictionary.
Then add a param to the streaming contract operation (same GUID) so that the streaming contract implementation can access the live non-streaming object (via the session manager you created - using the GUID provided).
You'll have to manage session lifetimes appropriately of course.
From Microsoft...
Sessions and Streaming
When you have a large amount of data to transfer, the streaming transfer mode in WCF is a feasible alternative to the default behavior of buffering and processing messages in memory in their entirety. You may get unexpected behavior when streaming calls with a session-based binding. All streaming calls are made through a single channel (the datagram channel) that does not support sessions even if the binding being used is configured to use sessions. If multiple clients make streaming calls to the same service object over a session-based binding, and the service object's concurrency mode is set to single and its instance context mode is set to PerSession, all calls must go through the datagram channel and so only one call is processed at a time. One or more clients may then time out. You can work around this issue by either setting the service object's InstanceContextMode to PerCall or Concurrency to multiple.
Note:
MaxConcurrentSessions have no effect in this case because there is only one "session" available.
See http://msdn.microsoft.com/en-us/library/ms733040.aspx

Related

Preventing data loss in client authoritative database writes

A project I'm working on requires users to insert themselves into a list on a server. We expect a few hundred users over a weekend and while very unlikely, a collision could happen in which two users submit the list concurrently and one of them is lost. The server has no validation, it simply allows you to get and put data.
I was pointed in the direction of "optimistic locking" but I'm having trouble grasping when exactly the data should be validated and how it prevents this from happening. If one of the clients reads the data, adds itself and then checks again to ensure that the data is the same with the use of an index or timestamp, how does this prevent the other client from doing the same and then one overwriting the other?
I'm trying to understand the flow in the context of two clients getting data and putting data.
The point of optimistic locking is that the decision to accept or reject a write is taken on the server, and is protected against concurrency by a pessimistic transaction or some sort of hardware protection, such as compare-and-swap. So a client requests a write together with some sort of timestamp or version identifier, and the server only accepts the write if the timestamp is still accurate. If it isn't the client gets some sort of rejection code and will have to try again. If it is, the client gets told that its write succeeded.
This is not the only way to handle receiving data from multiple clients. One popular alternative is to use a reliable messaging system - for example the Java Messaging Service specifies an interface for such systems for which you can find open source implementations. Clients write into the messaging system and can go away as soon as their message is accepted. The server reads requests from the messaging system and acts on them. If the server or the network goes down it's no big deal: the messages will still be there to be read when they come back (typically they are written to disk and have the same level of protection as database data although if you look at a reliable message queue implementation you may find that it is not, in fact, built on top of a standard database table).
One example of a writeup of the details of optimistic locking is the HTTP server Etag specification e.g. https://en.wikipedia.org/wiki/HTTP_ETag

Opentracing - Should I trace internal service work or just API calls?

Suppose I have service which does the following:
Receives input notification
Processes input notification which means:
some computing
storing in DB
some computring
generating it's own notification
Sends its own notification to multiple clients
What is the best practice in this case, should I granularly trace each operation like computing, storing in db etc with separate span or leave that for metrics (i.e. prometheus) and create single span for the whole notification processing?
It's somewhat up to you as to the granularity that's appropriate for your application, and also the volume of tracing data you're expecting to generate. An application handling a few requests per minute is going to have different needs than one handling 1000s of requests per second.
That said, I recommend creating spans when control flow enters or leaves your application (such as when your application starts processing a request or message from an external system, and when your application calls out to an external dependency, such as HTTP requests, sending notifications, or writing/reading from the database), and using logs/tags for everything that's internal to your application.

How to handle global resources in Spring State Machine?

I am thinking of using Spring State Machine for a TCP client. The protocol itself is given and based on proprietary TCP messages with message id and length field. The client sets up a TCP connection to the server, sends a message and always waits for the response before sending the next message. In each state, only certain responses are allowed. Multiple clients must run in parallel.
Now I have the following questions related to Spring State machine.
1) During the initial transition from disconnected to connected the client sets up a connection via java.net.Socket. How can I make this socket (or the DataOutputStream and BufferedReader objects got from the socket) available to the actions of the other transitions?
In this sense, the socket would be some kind of global resource of the state machine. The only way I have seen so far would be to put it in the message headers. But this does not look very natural.
2) Which runtime environment do I need for Spring State Machine?
Is a JVM enough or do I need Tomcat?
Is it thread-safe?
Thanks, Wolfgang
There's nothing wrong using event headers but those are not really global resources as header exists only for duration of a event processing. I'd try to add needed objects into an machine's extended state which is then available for all actions.
You need just JVM. On default machine execution is synchronous so there should not be any threading issues. Docs have notes if you want to replace underlying executor asynchronous(this is usually done if multiple concurrent regions are used).

Vert.X Event Bus Scalability

One question on vert.x event bus scalability. I am planning to use vert.x in smart device (small form facor) application and a remote management application. Initial estimate is that there will be close to 100K smart devices and 3/4 servers hosting management application. In this case, can you please advise using event bus between the smart device and web application (in cluster mode). My primary requirement of using event bus is to send dynamic notifications originated from device to the management servers and take corrective steps in case of system failure.
I posted another query recently and one of the users pointed me that internally vert.x uses the netsockets for event bus backed by hazelcast for cluster mode discovery. If that is the case, my assumption is that the scalability will be limited by the number of sockets that can be handled by the management server. Is this right ?
Also appreciate if anyone can point me to any benchmark test done on the vert.x eventbus in terms of msg processing performance.
My primary requirement of using event bus is to send dynamic notifications originated from device to the management servers and take corrective steps in case of system failure.
No, use regular HTTP requests for this. EventBus, and indeed every concurrent two-way networking model, is fundamentally unsuitable for this use case. Absolutely do not use Hazelcast on the clients; using a SockJS EventBus bridge is possible but so error-prone that you will certainly waste more time doing that correctly than writing a simple HTTP endpoint for this heartbeat behaviour.
my assumption is that the scalability will be limited by the number of sockets that can be handled by the management server. Is this right ?
No. Your scalability will be limited by however you'll be persisting the data you receive from the device. Hazelcast's maps are fine for this (accessed via vertx.sharedData()), but it really depends if you 100% understand what you want.

Cache values in Java EE

I'm building a simple message delegation application. Messages are being send on both ends via JMS. I'm using a MDB to process incoming messages, transform them and send them to a target queue. Unfortunately the same messages can be send to the incoming queue more than once but it is not allowed to forward duplicates.
So what is the best way to accomplish that?
Since there can be multiple MDBs listening on the incoming queue a need a single cache where I can store the unique message uuids of the incoming messages for at least an hour. How should this cache be accessed? Via a singleton/ static class (I'm running Java EE 5 and thus don't have the singleton annotation)?
In addition I think all operations must be synchronized, right? Does that harm performance too much?
#Ingo: are you OK with database solution. You can full fledged DB server or simple apache derby solution for this..
If so, you can have a simple table where you can store message unique UId and can check against it for uniqueness....this solution will have following benefits:
Simple code
No need of time bound cache(1 hour). You can check for uniqueness of a message forever.
Persistent record of what messages came in.
No need of expensive synchronized, you can rely on DB isolation level to have consistency.
centralized solution for your possibly many deployments of application.

Resources