001
014
015 package com.liferay.portal.cluster;
016
017 import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
018 import com.liferay.portal.kernel.cluster.ClusterInvokeThreadLocal;
019 import com.liferay.portal.kernel.cluster.ClusterMasterExecutorUtil;
020 import com.liferay.portal.kernel.cluster.ClusterRequest;
021 import com.liferay.portal.kernel.cluster.Clusterable;
022 import com.liferay.portal.kernel.util.MethodHandler;
023 import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
024 import com.liferay.portal.util.PropsValues;
025
026 import java.lang.reflect.Method;
027
028 import java.util.concurrent.Future;
029 import java.util.concurrent.TimeUnit;
030
031 import org.aopalliance.intercept.MethodInvocation;
032
033
036 public class ClusterableAdvice
037 extends AnnotationChainableMethodAdvice<Clusterable> {
038
039 @Override
040 public void afterReturning(MethodInvocation methodInvocation, Object result)
041 throws Throwable {
042
043 if (!ClusterInvokeThreadLocal.isEnabled()) {
044 return;
045 }
046
047 Clusterable clusterable = findAnnotation(methodInvocation);
048
049 if (clusterable == NullClusterable.NULL_CLUSTERABLE) {
050 return;
051 }
052
053 MethodHandler methodHandler =
054 ClusterableInvokerUtil.createMethodHandler(
055 clusterable.acceptor(), methodInvocation);
056
057 ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
058 methodHandler, true);
059
060 ClusterExecutorUtil.execute(clusterRequest);
061 }
062
063 @Override
064 public Object before(MethodInvocation methodInvocation) throws Throwable {
065 if (!ClusterInvokeThreadLocal.isEnabled()) {
066 return null;
067 }
068
069 Clusterable clusterable = findAnnotation(methodInvocation);
070
071 if (clusterable == NullClusterable.NULL_CLUSTERABLE) {
072 return null;
073 }
074
075 if (!clusterable.onMaster()) {
076 return null;
077 }
078
079 Method method = methodInvocation.getMethod();
080
081 Class<?> returnType = method.getReturnType();
082
083 if (ClusterMasterExecutorUtil.isMaster()) {
084 Object result = methodInvocation.proceed();
085
086 if (returnType == void.class) {
087 result = nullResult;
088 }
089
090 return result;
091 }
092
093 MethodHandler methodHandler =
094 ClusterableInvokerUtil.createMethodHandler(
095 clusterable.acceptor(), methodInvocation);
096
097 Future<Object> futureResult = ClusterMasterExecutorUtil.executeOnMaster(
098 methodHandler);
099
100 Object result = futureResult.get(
101 PropsValues.CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT,
102 TimeUnit.SECONDS);
103
104 if (returnType == void.class) {
105 result = nullResult;
106 }
107
108 return result;
109 }
110
111 @Override
112 public Clusterable getNullAnnotation() {
113 return NullClusterable.NULL_CLUSTERABLE;
114 }
115
116 }