leoismyname
leoismyname

Reputation: 407

BlockingQueue to block and return object till the object with specified id becomes available on the queue

I have got some legacy code in some middle application where request response methods are sync. Now the new interface to the back end is async, but i have to simulate the sync request in middle application. I need to make request call and will wait for the async response to come. It is multi threaded application where there will be multiple simultaneous requests and response.

I am wondering if there is a some kind of blocking queue in java where i can put the request object and wait till the response object with specified id(by equals method) is put back on queue. So there will be two method that will put the object on queue, lets say they are requestSender and responseReceiver. Request sender will put a request and wait and than responseReceiver put all the responses on the queue and when response object matches than only the associated requestSender will get the object and that that will return it to the frontend.

in short is there something like take(object) method in queue and it will only return when specific object get available on the queue.

If that is not possible with the blocking queue than what other approach should i use to simulate sync request-response in the middle application for front end when back end to middle application is async.

Thank you so much in advance.

Upvotes: 1

Views: 1089

Answers (2)

leoismyname
leoismyname

Reputation: 407

This is how i implemented the solution for now, please let me know if there is a better way, thanks

public class OrderFixResponseBlockingQueue {

    private Map<OrderFixKey, ArrayBlockingQueue<FxOrder>> responseQueueMap = new HashMap<OrderFixKey, ArrayBlockingQueue<FxOrder>>();


    public FxOrder get(FxOrder order, int timeoutInSecs) {
        try {

            OrderFixKey key = new OrderFixKey(order);
            ArrayBlockingQueue<FxOrder> orderQueue = new ArrayBlockingQueue<FxOrder>(1);
            responseQueueMap.put(key, orderQueue);

            FxOrder responseOrder = orderQueue.poll(timeoutInSecs, TimeUnit.SECONDS);
            responseQueueMap.remove(orderQueue);

            return responseOrder;

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }


    public void put(FxOrder order) {
        OrderFixKey key = new OrderFixKey(order);
        ArrayBlockingQueue<FxOrder> queue = responseQueueMap.get(key);

        if (queue != null) {
            queue.add(order);
        } else {
            System.out.println("Put queue not available, should be a request timeout");
        }
    }

    private class OrderFixKey {
        private final String orderId;

        OrderFixKey(FxOrder order) {
            this.orderId = order.getOrderId();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof FxOrder) {
                FxOrder that = (FxOrder) obj;
                return this.orderId.equals(that.getOrderId());
            }
            return false;
        }

        @Override
        public int hashCode() {
            return this.orderId.hashCode();
        }
    }
}

Upvotes: 1

SMA
SMA

Reputation: 37023

Look at ArrayBlockingQueue or LinkedBlockingQueue

So you will have producer producing the elements who can just offer to one of these queue, while your consumer thread will block on take method of Queue until you have an element from the producer and then you can consume that element in your consumer thread.

There is no such queue which will block until the same id is pushed onto Queue. I would suggest, tou could create your customized queue if that's the case.

Upvotes: 0

Related Questions