How to get pass a process ID between threads in Java? - java

I'm building a paired client/server application for a research project. The server-side application is a java binary that has a main loop and a ServerSocket object. When a user with the client-side application rings up the server, I instantiate a new object of type ClientSession, and give it the socket over which communications will occur. Then I run it as a new thread so that the central thread of the server application can go back to waiting for calls.
Each ClientSession thread then does some processing based on requests from the client program. It might accept a string and throw back a small SQLite .db file in response, or accept a different string and send back a Java serialized object containing a list of files and file sizes. In all cases the ClientSession thread is shortlived, and closes when then socket is closed.
And so far this is working fine, but today I have a new challenge to run, of all things, a perl script as per a client's request. The script basically wraps some low-level Unix OS functions that are useful to my problem domain. If a client makes a request to start up a copy of this script, I can't just launch it in the ClientSession thread. The perl script needs to persist after the lifetime of a call (perhaps for days or weeks running in a loop with a sleep timer).
What I'd like to do is set up a separate thread on my server application and have it wrap this perl script.
Runtime.getRuntime.exec('perl script.pl');
This will start it up, but right now it'll die with the ClientSession thread.
My thought would be something like declare a PerlThread object, require it to know the UserID of who's requesting the new thread as part of its constructor, have it implement the Runnable interface, then just do a thread.start() on a new instance of it. But before I can get there, I have to do some message passing between a child thread and the main thread of my server application. So that setup brings me to my question:
How do I pass a message back to my main server program from a child thread and tell it that a Client requested a perl wrapper thread to start?

You should look at ExecutorService for a better technique for running jobs on separate threads. It's much more powerful and convenient than Thread.start() or Runnable.run().
You can look at the Callable construct to see how to get results back from jobs which run on other threads.
You could pass the information you want to get back from the task when it completes into the constructor for your domain specific callable, and when it completes, you can get it back.

How do I pass a message back to my main server program from a child thread and tell it that a Client requested a perl wrapper thread to start?
I would store an object somewhere that wraps the UserId as well as the associated Process object. You could store it in a static volatile field if there is just one of them. Something like:
public class ClientHandler {
...
private static volatile UserProcess userProcess;
...
// client handler
if (userProcess != null) {
// return error that the perl process is already started
} else {
// start the process
Process process = Runtime.getRuntime.exec('perl script.pl');
userProcess = new UserProcess(userId, process);
}
Then the main program can find out if any clients have the perl script running by looking at ClientHandler.userProcess.
If you can have multiple processes running on the client then I'd wrap some sort of ProcessManager class around a collect of these UserProcess objects. Something like startProcess(...), listProcesses(), ... Then the main class would ask the ProcessManager what processes are running or what users started what processes, etc..
The UserProcess class is just a wrapper around the UserId and Process fields.

Related

Apache Thrift reusing connection in different thread

I'm creating a program in Java in which a client can send read/write operations to a node which sends a read/write request to a supernode. The supernode is using a Thrift HaHs server.
There are multiple nodes and thus should be able to handle concurrent operations. Writing is no proble, but I'm having a problem with reading.
Each time a node connects to the server, a thread will take its read/write request and put it in a queue (LinkedBlockingQueue since this is a critical section that needs to be locked).
The server has a separate pool of worker threads that will process each request in the queue concurrently.
My problem is that after I get a specific file, I need to pass it back to the connecting node (using the same Thrift connection). However, I'm not sure how to do that since the requests are handled by separate worker threads. Here's the order of steps.
// node calls this supernode method (via Thrift RPC)
Request connect(Request req) {
queue.put(req)
return req;
}
// Inside Worker Thread class (which is inside supernode)
public void run() {
try {
while ( true ) {
Request req = queue.take();
processRequest(req);
}
}
catch ( InterruptedException ie ) {
// just terminate
}
}
Basically, I'm trying to figure out how I can send something back to the same Thrift socket inside processRequest
Any help would be much appreciated!
My solution currently is to use a separate 'Completion Queue' which will add completed requests and the incoming call will have to poll that queue--of course this is not efficient due to polling. I assume there is some way to wait the main thread while the worker thread is processing then signal the main thread to continue, but then I'm not sure how to pass back the computed request (i.e contents of file retrieved)
I would first ask myself why I need two threads where one seems enough?
Aside from that, my approach would be sth. like this (rough sketch):
The request data, response data and a waitable event object all are wrapped togehter in a "work package". By waitable event object I mean whatever the Java equivalent of that is exactly, technically.
That work package object is shared between threads. It is put into the queue to be processed by the worker, and also the calling thread keeps holding a reference to it.
The worker grabs the request data from the work package object, processes it and attaches the resulting data to that work package object.
Once the worker is done, he signals the event object mentioned above.
The calling thread waits for that event to happen. Since we use an event object, this is completely w/o polling. Once the event becomes signaled, the thread pulls the result data from the completed work package and returns to the client.
Of course additional code may be added to cover all edge cases, such as necessary timeouts etc.

running two threads simultaneously inside a stateless agent and guaranting communication between them

I am developing a stateless Agent in Java that takes informations from one Server and transfer it to another client. It means that the agent is located between a client and a server. So I am thinking to run two threads simultaneously on the agent: one thread (thread1) runs a serverSocket and get request from client while another threads (thread2)is runnning and makes communication with the server. The problem consists in synchronizing between the two threads. I am thinking in making thread 1 asking whole the time thread 2 about a new Information. If thread 2 has nothing new, he will not answer it. What is the best way to synchronize between them. Should I use a global variable (a flag) to synchronize between them? Can I save Information when I have a stateless agent?
I think you should modify your app into async model.
Your app needs:
- an entry point to accept incoming connections -> a good example is an async servlet (or one dedicated thread).
- a ThreadPoolExecutor that provides fixed numbers of workers and a blocking queue (use this constructor).
The workflow:
Accept incomming request.
Wrapp incoming request into (Runnable) task.
Put task into blocking queue.
If ThreadPoolExecutor has a free worker starts processing the task
An advantage of such a model is that you are able to handle one request using one thread. So there is no need to manually synchronize anything.

Java: Communicating data from one thread to another

I am working on creating a chat client based on UDP. The main structure is that there is a server where clients register and where clients can also request to form a connection with another client that is registered with the server. The clients are structures as follows using pseudo code:
public UDPClient() {
// Create datagram socket
// Execute RECEIVE thread using datagram socket above
// Execute SEND thread using datagram socket above
}
The idea is to have the send and receive executing on separate threads so I don't get blocked I/O on the receive. Both of these threads have loops within their run methods that allow you to continually send and receive messages. The problem I have is this. If a message comes in on the RECEIVE thread that changes how my SEND should be executing, how do I communicate this to the SEND thread? Do I have to shoot a datagram off to myself or can I communicate this in the code somehow?
Assuming boths threads have no reference to each other, create a third singleton class, which both read/send threads (classes) reference, that has a volatile member field to store the state data you want shared and which has synchronized access.
The volatile keyword, combined with synchronized access, guarantees that a change made to the field by one thread will be seen by another thread. Without this, changes may not be visible due to the java memory model specification.
Edited:
Following "separation of concerns" design guideline, it would be better to not have the read/send threads know about each other and to use a third class to orchestrate their activities/behaviour. Add methods to your read/send classes to stop(), start() etc and call these from the other class.
Using a separate class would also allow:
Behaviour control by other means, for example a "stop sending" button on an admin web page
Allowing multiple threads of each type, yet still having proper control through a central point, perhaps using a pool of such threads (without a separate class, you would have a many-to-many nightmare and lots of code that has nothing to do with the job at hand: ie ending and receiving)
Easier testing of your worker classes, because they do less and are more focused
porting/embedding them stand-alone for other uses
your SEND thread should have public (accesible) method (synchronized if possible) that you should be able to access from your RECEIVE thread. You could use this method to create a boolean flag, string message, etc. that you should always read before you .send(yourPacket); from your SEND thread.
Have a member variable in your READ method that your code can read from and change the SEND method based on that variable.

Is dataInputStream of a Socket know how to deal with multiple writings to it?

I am developing a Net game, in general:
I have a server which launch a serverThread for each client that has connected to it.
Its purpose is to listen to messages from the specific client and to process it on the server.
Also for each client that is opened it launch a clientThread which is a listening thread to messages from the server.
The two threads are quite simple and similar threads which implements the Runnable Interface and therefore override the run method.
Each Run method is some kind of infinite loop that has on its start the command (blocking command):
int command = m_In.readInt();
and then do a process by switch cases structure over the received command.
after process was done, the loop cause the code to return to the blocking m_In.readInt()
To wait for another command to come.
My question is: My Net game has enough options which are using the communication over this m_In, so what happens if there are two messages or more coming almost together to the clientThread, how would the dataInputStream will act?
Will it begin to process first message and after its done will grab the second which is on some kind of a queue? or it could drop the second message and it will be lost?
Maybe that stream has buffer so it stores the second message in a queue or something?
Thanks
Streams by their nature expect data to come in a specified order. If you have two threads writing to the same stream at the same time, bad things will happen.
Now you can certainly synchronize access to the stream and have the two thread interleave their writing (so long as you build some sort of formatting on the stream that tells the receiver how to read data), but you don't get this by default.
Typically though, each client thread would have their own connection and thus their own stream to write into. A server can obviously read from multiple streams at the 'same time', and that is the normal server pattern.

TCP Client Accepting Objects

I am writing a java program that needs to continuously accept serialized objects throughout the run of the application. The objects are sent by a server as requested by the user.
My main application initializes the tcp client (extends thread) in its run method, but I am trying to read objects from the line from a function.
Pseudocode follows:
*tcp client extends thread
*global vars: ip, port, socket, oi stream, oo stream, object reference
*run()
make connection
*getObject()
object reference = (object).readobject()
return object
My main application calls client.getObject() in an update loop. there may or not be an object waiting.
Am I going about this the wrong way?
Are you trying to do "classic" server behavior or non-blocking IO?
If it's the former, I'd recommend a blocking queue on the server to accept incoming requests and a pool of threads to process them. Have the server assign a thread to process the request when it comes in until the thread pool is exhausted; queue up requests until threads are freed up and returned to the pool.
Non-blocking IO is another matter entirely. Look at how Netty and node.js are designed and implemented for that.
I would never have a class extend Thread - it's unlikely that you'll add significant new behavior. Implement Runnable instead and give it to a Thread instance to run.
I would suggest your run() method reads all the objects and adds them to a queue.
getOject() takes the next object from the queue.
You can also have a int queueLength() to check how any are waiting.

Categories