I'm writing a server using java NIO, and I have a few questions that I can't find answers to.
First, regarding SSLEngine, how to handle NEED_TASK properly in separated thread? When I invoke tasks in separate thread they complete, but I have no idea how to go back to perform another handshake operation. One option would be to call that operation from a thread that was performing delegated task, but I guess that's not the way to do it.
Another question is about calling interestOps() from different thread then selector thread. I need to change key interests after an attempt to write to channel hadn't written all data.
I thought about using some sort of Queue of changes like in ROX NIO tutorial, but I have read in another thread here that it is not the best way.
first regarding SSLEngine, how to handle NEED_TASK properly in separated thread. When I invoke tasks in separate thread they complete, but I have no idea how to go back to perform another handshake operations.
While the engine is in NEED_TASK state it can't do anything else. When the task completes you should then repeat the operation that originally returned NEED_TASK and let the engine tell you what to do next. You need to block or disable use of that engine by other threads until the task completes, i.e. don't select on that channel.
Another question is about calling interestOps() from different thread then selector thread. I need to change key interests after an attempt to write to channel hadn't written all data. I thought about using some sort of Queue of changes like in ROX NIO tutorial, but I have read in another thread here that it is not the best way.
That would have been me. I hate those queues. I just wakeup() the selector and change the interestOps, never seen a problem with that. The selector thread has to cope correctly with zero keys being ready, but it already needs to do that.
Related
Maybe there is some "integration-pattern" here I miss...
I have a proccess (a thread from an TaskExecutor) that is some cases need to stop and wait for an additional data to continue.
I was thinking about blocking in a receive method, but I don't find how to send, from a different thread a message to that channel (a temporal one, isn't it?) to unblock this thread, only this.
The component responsible about unblock should receive a message from some kind of messagin platform (redis,rabbit,...) and then "notify" the blocked execution.
An ugly implementation could be a wait/notify but of course I don't want to use that having a full "message-oriented" solution.
Is there any component/solution for this problem?
Maybe a subscriber with some topic I can use to be sure only that thead ir running again, but I cannot block in a publishsubscribe channel, can I?
thanks a lot,
that is some cases need to stop and wait for an additional data to continue.
Looks like this is indeed the use-case for the Thread Barrier component.
Another way to do something similar is an Aggregator for the releaseStrategy as 2 messages by size.
Anyway the correlationKey is a key entity in both use-cases.
Hi guys am getting following error am using Websocket and Tomcat8.
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1092)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1055)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:186)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.broadcastData(IRIMonitorSocketServlet.java:369)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.access$0(IRIMonitorSocketServlet.java:356)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet$5.run(IRIMonitorSocketServlet.java:279)
You are trying to write to a websocket that is not in a ready state. The websocket is currently in writing mode and you are trying to write another message to that websocket which raises an error. Using an async write or as not such good practice a sleep can prevent this from happening. This error is also normally raised when a websocket program is not thread safe.
Neither async or sleep can help.
The key problem is the send-method can not be called concurrently.
So it's just about concurrency, you can use locks or some other thing. Here is how I handle it.
In fact, I write a actor to wrap the socketSession. It will produce an event when the send-method is called. Each actor will be registered in an Looper which contains a work thread and an event queue. Meanwhile the work thread keeps sending message.
So, I will use the sync-send method inside, the actor model will make sure about the concurrency.
The key problem now is about the number of Looper. You know, you can't make neither too much or too few threads. But you can still estimate a number by your business cases, and keep adjusting it.
it is actually not a concurrency issue, you will have the same error in a single-threaded environment. It is about asynchronous calls that must not overlap.
You should use session.get**Basic**Remote().sendText instead of session.get**Async**Remote().sendText() to avoid this problem. Should not be an issue as long as the amount of data you are writing stays reasonable small.
I want to generate some text string that is going to be sent via TCP socket . I have accomplished it within few minutes.
However I want a producer consumer pattern.I dont care if it failed or not.
Should I create a Blocking Queque at application for this ? Should I create a service ?
Note that I want a single thread to manage this job.
In the case it's a short task (like you commented), I'd recommend putting it within an AsyncTask as a background thread. You can control anything about this separately, which will help you also debugging it. Services are more intended for long executing tasks, so I'd not recommend it at this scope (it's a bit harder even to communicate with other Activity's. Here you'll find the AsyncTask's documentation, and here a good example.
The Blocking structure depends on your needs - but I don't think you'll need that in your case. Anyway, if you would need that, there're lots of thread-safe data structures you may use, you might find this helpful.
Create a LinkedBlockingQueue where your producer adds data. Create a Timer that fires every second or so. The task of the Timer would be to send the messages over the wire.
For this, both the producer (the one generating the messages) and consumer (Timer) should have access to the LinkedBlockingQueue. The Timer will remove the first element of the LinkedBlockingQueue and then send it.
Sounds good ?
A little help please.
I am designing a stateless server that will have the following functionality:
Client submits a job to the server.
Client is blocked while the server tries to perform the job.
The server will spawn one or multiple threads to perform the job.
The job either finishes, times out or fails.
The appropriate response (based on the outcome) is created, the client is unblocked and the response is handed off to the client.
Here is what I have thought of so far.
Client submits a job to the server.
The server assigns an ID to the job, places the job on a Queue and then places the Client on an another queue (where it will be blocked).
Have a thread pool that will execute the job, fetch the result and appropriately create the response.
Based on ID, pick the client out of the queue (thereby unblocking it), give it the response and send it off.
Steps 1,3,4 seems quite straight forward however any ideas about how to put the client in a queue and then block it. Also, any pointers that would help me design this puppy would be appreciated.
Cheers
Why do you need to block the client? Seems like it would be easier to return (almost) immediately (after performing initial validation, if any) and give client a unique ID for a given job. Client would then be able to either poll using said ID or, perhaps, provide a callback.
Blocking means you're holding on to a socket which obviously limits the upper number of clients you can serve simultaneously. If that's not a concern for your scenario and you absolutely need to block (perhaps you have no control over client code and can't make them poll?), there's little sense in spawning threads to perform the job unless you can actually separate it into parallel tasks. The only "queue" in that case would be the one held by common thread pool. The workflow would basically be:
Create a thread pool (such as ThreadPoolExecutor)
For each client request:
If you have any parts of the job that you can execute in parallel, delegate them to the pool.
And / or do them in the current thread.
Wait until pooled job parts complete (if applicable).
Return results to client.
Shutdown the thread pool.
No IDs are needed per se; though you may need to use some sort of latch for 2.1 / 2.3 above.
Timeouts may be a tad tricky. If you need them to be more or less precise you'll have to keep your main thread (the one that received client request) free from work and have it signal submitted job parts (by flipping a flag) when timeout is reached and return immediately. You'll have to check said flag periodically and terminate your execution once it's flipped; pool will then reclaim the thread.
How are you communicating to the client?
I recommend you create an object to represent each job which holds job parameters and the socket (or other communication mechanism) to reach the client. The thread pool will then send the response to unblock the client at the end of job processing.
The timeouts will be somewhat tricky, and will have hidden gotcha's but the basic design would seem to be to straightforward, write a class that takes a Socket in the constructor. on socket.accept we just do a new socket processing instantiation, with great foresight and planning on scalability or if this is a bench-test-experiment, then the socket processing class just goes to the data processing stuff and when it returns you have some sort of boolean or numeric for the state or something, handy place for null btw, and ether writes the success to the Output Stream from the socket or informs client of a timeout or whatever your business needs are
If you have to have a scalable, effective design for long-running heavy-haulers, go directly to nio ... hand coded one-off solutions like I describe probably won't scale well but would provide fundamental conceptualizing basis for an nio design of code-correct work.
( sorry folks, I think directly in code - design patterns are then applied to the code after it is working. What does not hold up gets reworked then, not before )
I'm in the process of converting our java code to use NIO, but I'm not sure of the best way to design it.
My initial approach was to create a pool of selector threads. The threads are started/killed as needed, and channels are registered to a selector thread when they are connected/accepted in a round-robin fashion. From there, each thread blocks on select(), and when woken up will run the appropriate callback associated with each channel that has a selected key.
In addition to this "multiple selector thread" design, I've also seen people say to use a single selector thread, and a pool of dispatch threads. When an IO operation is ready to be performed, the selector notifies a dispatcher thread, which then processes the request. This model has the benefit of not blocking the IO thread, but now we're forcing all of the IO into a single thread and dealing with synchronization/an event queue in the dispatcher.
Additionally I wouldn't be able to use a single direct byte buffer for reading each channel, passing it directly into the callback. Instead I'd have to copy the data out each time a read occurs into an array and reset. (I think..)
What's the best way to implement this?
Take a look at the Reactor Pattern
http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf
How you want your selectors to work really depends on your usecase. (Number of connections, message size, etc)
What is the problem that you are trying to solve by converting from IO to NIO?
You really should look into Mina,
http://mina.apache.org/
It solves all the problems you mentioned.
Also have a look at netty which is really fast and feature rich and also is used in big systems and by big companies like Redhat (jboss), Twitter, Facebook... .