0

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!

JensG
  • 13,148
  • 4
  • 45
  • 55
Art
  • 147
  • 3
  • 13
  • Does the incoming call wait for completion of the queued task? – JensG Mar 31 '16 at 13:16
  • That's what I'd like it to do because the incoming call is synchronous (I could make it asynchronous, but I'd rather not change that much of the code now just for one function). 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) – Art Mar 31 '16 at 14:06

1 Answers1

1

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.

JensG
  • 13,148
  • 4
  • 45
  • 55
  • Thank, the wait and notify helped. And now I believe the threads wait for each other correctly which is great. However, the one field of the Object I want to update doesn't seem to update transfer to the main thread. I assume I'm not keeping a reference correctly. All i'm doing is – Art Mar 31 '16 at 19:54