2

I have to write a code which involves making a web service call to a backend asynchronously and returning a toll free number in round robin from a list of TFNs to the caller. Below is my code

@Stateless
public class TollFreeServiceBean {
    @EJB
    private AsyncBackendService asyncBean;
    public long getTollFreeNumber(Request request) {
        //Validate request 
        asyncBean.callBackend(request);
        return TFNUtil.getNext();
    }
}

@Stateless
public class AsyncBackendService {
    @Asynchronous
    public void callBackend(Request request) {
        // Call web service and inform a caller with `Request` is going to call
    }
}

public class TFNUtil {
    private static int index = 0;
    private TFNUtil(){}
    public static synchronized long getNext() {
        // Get TFN list from cache
        if(tfnList.size() >= index) {
             index = 0;
        }
        long tfn = tfnList.get(index);
        index++;
        return tfn;
    }
}

The idea is that the customers will get a different TFN each until the TFNs in the cache are completed. Once completed, the next customer should get the first TFN again. For example if there are 10 TFNs and 11 customers, 11th customer should receive 1st TFN. 12th customer should receive 2nd TFN and so on.

The backend system is complaining that two different simultaneous customers are landing on the same TFN. So I think my TFNUtil.getNext() logic is not right.

Can anyone please point out the bug here?

Krishna Chaitanya
  • 2,533
  • 4
  • 40
  • 74
  • i think issue with if(tfnList.size() >= index) { = 0;} clause. suppose every time index is higher than list size it return 0. so after no of cusomters are equal to list size return 0. can u explain more about tfnList – Chamly Idunil Nov 09 '16 at 09:22
  • Yes after the number of customers is equal to the list size we want to send the first tfn to the customer coming after the list size. That is why I mentioned round robin. – Krishna Chaitanya Nov 09 '16 at 09:38
  • yes. then what should be logic when no of customers greater than list size. system suppose to time out first logged user. also there is possible suppose no of customers 11 and only TFN 3 available. rather than going to TFN1 you can use TFN3 right ? cant u use dynamically growing list. – Chamly Idunil Nov 09 '16 at 09:47
  • When number is users greater than TFNs then we will serve the TFN in round robin – Krishna Chaitanya Nov 09 '16 at 09:50
  • Two customer always can get same TFN question arises that is Backend is getting this even though 2 customer calls happening when there is no load – Shashank Nov 09 '16 at 09:54
  • @shashank yea that is what the backend system is complaining. I want the code to get reviewed and be sure that this code has no bugs/faults in it. – Krishna Chaitanya Nov 09 '16 at 09:58
  • How are you ensuring order in which call to your service is same as the order in which people are calling your Backend – Shashank Nov 09 '16 at 10:00
  • We will inform the backend that a customer is going to come to them. The details of the customer is sent in the request sent to the backend. But we won't send on which TFN the customer might arrive. – Krishna Chaitanya Nov 09 '16 at 10:02
  • I mean let say you have 10 TFN, 1st and 11th will land on same number but rest 2-10 trying to call and couldnt get through due some network waiting or something else now it seems that TFN 1 is getting two simultaneous call and rest are free. – Shashank Nov 09 '16 at 10:05
  • Yea many be due to some network latency 1 and 11th customers are landing on 1st tfn while others still trying to connect. – Krishna Chaitanya Nov 09 '16 at 10:09
  • If you can redirect call to another TFN then it would be great, redirecting could be automatic if you have such api , or can be operators intervention. Other solution is suggested by @GhostCat by reserving time window – Shashank Nov 09 '16 at 10:21
  • Sure thank you. So I guess the code does not have any problem w.r.t the business requirement. – Krishna Chaitanya Nov 09 '16 at 10:33

1 Answers1

1

Your statements are contradicting themselves.

On the one hand, you are worried that no two customers should receive the same number.

On the other hand, you purposely put a system into place that will exactly do that.

You see, depending on how many elements your list tfnList has ... your method getNext() might "spill over" pretty quickly. And what do you think will happen then?

To me, it sounds like the real solution is more complex: you might have to re-design your system. Instead of just rotating that list of numbers, you might need a system that is able to block/reserve a number for some time. And while a number is reserved, it is not handed out again.

A simple version of that would be "time" based only; meaning that a reservation "vanishes" automatically after some X minutes/hours. If that doesn't work; you would have to go one step further: and find something/somebody in your workflow that to unreserve numbers to render them "available" again.

And beyond that, it seems that you didn't fully consider what should happen when your have N numbers available, but N+x customers coming in at the same time! No round-robin'ing/rotating ... whatever can help you there! If that situation is possible, then you have to deal with it and define what should happen then!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Your update doesnt help. It does not clarify why you are surprised that a method that can return the **same** number to two people ... does exactly that. If your 10 numbers are in use, and you give out number 1 to an 11th customer, what do expect to happen?! Also have a look at my latest updates! – GhostCat Nov 09 '16 at 09:45
  • I meant that two simultaneous customers are getting the same TFN. This is what the backend system is complaining about. I just want to get the code checked/reviewed and be sure that the code is working as expected. – Krishna Chaitanya Nov 09 '16 at 09:46
  • write test case using thread pool executor and test your TFNutils class once – Shashank Nov 09 '16 at 09:56
  • @shashank can you point me to some example how to use thread pool executor or can you brief me what exactly to do? That would be helpful. – Krishna Chaitanya Nov 09 '16 at 10:04
  • There is **no** point in making such experiments. The code is thread-safe, the problem comes out of the broken design. Besides: defining a **helpful** multi-threaded testcase would be really really hard. And you know: a passing testcase ... would mean nothing. Because there might be other threading scenarios that would let to a fail. But as said: the problem is **not** about the code having a multi-threading issue! The **overall** system is at fault! – GhostCat Nov 09 '16 at 10:12