0 Replies Latest reply on Aug 27, 2008 1:35 AM by mnrz

    need help on interceptors and suspending specific threads

    mnrz

      Hi

      We are using EJB3 and we've created an interceptor to check whether the user has already sent a request or not.
      if we noticed that the user has already sent a request then in this interceptor we need to suspend that thread and wait till the former request being completed otherwise the thread will proceed. This suspension should be applied if the same user has already a request and for other users this is not the case.

      in order to find whether or not a user has sent a request, each time a request comes, we store its user id in a Map structure.

      here is the body of our interceptor

      
      public class ConcurrectBankingTransaction {
      
       private static Map<Long,Condition> users = new HashMap<Long,Condition>();
       private static final Lock lock = new ReentrantLock();
      
       @AroundInvoke
       public Object check(InvocationContext context) throws Throwable {
       Object result = null;
       if(context.getParameters() == null) {
       //TODO what....
       }
       Object obj = context.getParameters()[0];
       String cmSessionId = null;
       cmSessionId = ((BaseDto)obj).getCmSessionId();
       Long userId = null;
       if (cmSessionId == null) {
       if(obj instanceof LoginDto) {
       UserInfoDto entity = findUser((LoginDto) obj);
       if (entity != null) {
       userId = entity.getId();
       }else {
       //TODO what to do...
       }
       }else {
       //TODO what to do...
       }
       }else {
       try {
       userId = (CurrentSessionData.getUserId(cmSessionId));
       } catch (ChannelManagerException e) {
       //TODO handle the exception here...
       e.printStackTrace();
       }
       }
      
       //acquires the lock
       lock.lock();
       try {
       if(contains(userId)) {
       final Condition inProcessTransaction = getLockForUserId(userId);
       while (contains(userId)) {
       try {
       //this releases the lock and causes the current thread to be waiting...
       inProcessTransaction.await(2000, TimeUnit.MILLISECONDS);
       } catch (InterruptedException e) {
       // It's OK
       }
       }
       addUserId(userId,inProcessTransaction);
       }else {
       addUserId(userId,lock.newCondition());
       }
       }finally {
       lock.unlock();
       }
      
       try {
       result = context.proceed();
       }catch (Throwable e) {
       //any throwable supposed to be caught to release the previous lock condition
       getLockForUserId(userId).signal();
       removeUserId(userId);
       throw e;
       }
      
       //notifying the condition to proceed the awaiting thread
       getLockForUserId(userId).signal();
       removeUserId(userId);
       return result;
       }
      
      


      now, I am skeptical on the way this works. I just created this interceptor based on information gathering through the internet and not sure that works fine. Unfortunately, I can't create a situation in which we can test the system.

      I have seen a CountDownLatch but I fear to use that because no knowledge I have about that.

      I appreciate if you can help me on this or if you have any other idea on how to suspend other threads

      thank you very much