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 Method method = methodInvocation.getMethod();
061
062 Class<?> returnType = method.getReturnType();
063
064 if (returnType == void.class) {
065 clusterRequest.setFireAndForget(true);
066 }
067
068 ClusterExecutorUtil.execute(clusterRequest);
069 }
070
071 @Override
072 public Object before(MethodInvocation methodInvocation) throws Throwable {
073 if (!ClusterInvokeThreadLocal.isEnabled()) {
074 return null;
075 }
076
077 Clusterable clusterable = findAnnotation(methodInvocation);
078
079 if (clusterable == NullClusterable.NULL_CLUSTERABLE) {
080 return null;
081 }
082
083 if (!clusterable.onMaster()) {
084 return null;
085 }
086
087 Method method = methodInvocation.getMethod();
088
089 Class<?> returnType = method.getReturnType();
090
091 if (ClusterMasterExecutorUtil.isMaster()) {
092 Object result = methodInvocation.proceed();
093
094 if (returnType == void.class) {
095 result = nullResult;
096 }
097
098 return result;
099 }
100
101 MethodHandler methodHandler =
102 ClusterableInvokerUtil.createMethodHandler(
103 clusterable.acceptor(), methodInvocation);
104
105 Future<Object> futureResult = ClusterMasterExecutorUtil.executeOnMaster(
106 methodHandler);
107
108 Object result = futureResult.get(
109 PropsValues.CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT,
110 TimeUnit.SECONDS);
111
112 if (returnType == void.class) {
113 result = nullResult;
114 }
115
116 return result;
117 }
118
119 @Override
120 public Clusterable getNullAnnotation() {
121 return NullClusterable.NULL_CLUSTERABLE;
122 }
123
124 }