You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/12/16 11:46:00 UTC

[GitHub] takumiCX opened a new issue #353: CompositeOmegaCallback的compensate(TxEvent event)方法有并发问题

takumiCX opened a new issue #353: CompositeOmegaCallback的compensate(TxEvent event)方法有并发问题
URL: https://github.com/apache/servicecomb-pack/issues/353
 
 
   CompositeOmegaCallback类的public void compensate(TxEvent event)方法可能会有并发异常
   
   > public void compensate(TxEvent event) {
   >     Map<String, OmegaCallback> serviceCallbacks = callbacks.getOrDefault(event.serviceName(), emptyMap());
   > 
   >     if (serviceCallbacks.isEmpty()) {
   >       throw new AlphaException("No such omega callback found for service " + event.serviceName());
   >     }
   > 
   >     OmegaCallback omegaCallback = serviceCallbacks.get(event.instanceId());
   >     if (omegaCallback == null) {
   >       LOG.info("Cannot find the service with the instanceId {}, call the other instance.", event.instanceId());
   >       omegaCallback = serviceCallbacks.values().iterator().next();
   >     }
   > 
   >     try {
   >       omegaCallback.compensate(event);
   >     } catch (Exception e) {
   >       serviceCallbacks.values().remove(omegaCallback);
   >       throw e;
   >     }
   >   }
   > 
   
   考虑serviceCallbacks这个map不为空,恰好只有一个元素<instance-1,omegaCallback>的情形,当该线程刚好通过下面这部分代码的if条件时让出cpu执行权
   
   >  if (omegaCallback == null) {
   >       LOG.info("Cannot find the service with the instanceId {}, call the other instance.",    event.instanceId());
   >       omegaCallback = serviceCallbacks.values().iterator().next();
   >     }
   
   此时刚好收到来自omega端的一个onDisconnected请求,instanceId恰好就是上面map里的instance-1
   
   
   > public void onDisconnected(GrpcServiceConfig request, StreamObserver<GrpcAck> responseObserver) {
   >     OmegaCallback callback = omegaCallbacks.getOrDefault(request.getServiceName(), emptyMap())
   >         .remove(request.getInstanceId());
   > 
   >     if (callback != null) {
   >       callback.disconnect();
   >     }
   > 
   >     responseObserver.onNext(ALLOW);
   >     responseObserver.onCompleted();
   >   }
   
   导致serviceCallbacks这么map中instance-1对应的Entry被移除, 导致map为空,当执行compensate的线程继续执行
   
   > serviceCallbacks.values().iterator().next();
   
   将抛出下面的异常
   
   > Exception in thread "Thread-1" java.util.NoSuchElementException
   > 	at java.util.concurrent.ConcurrentHashMap$ValueIterator.next(ConcurrentHashMap.java:3436)
   > 	at org.apache.servicecomb.saga.alpha.core.CompositeOmegaCallback.compensate(CompositeOmegaCallback.java:64)
   > 	at org.apache.servicecomb.saga.alpha.core.CompositeOmegaCallbackTest$1.run(CompositeOmegaCallbackTest.java:171)
   > 	at java.lang.Thread.run(Thread.java:748)
   
   
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services