001
014
015 package com.liferay.portal.kernel.resiliency.spi.provider;
016
017 import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
018 import com.liferay.portal.kernel.nio.intraband.welder.Welder;
019 import com.liferay.portal.kernel.process.ProcessExecutor;
020 import com.liferay.portal.kernel.resiliency.PortalResiliencyException;
021 import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil;
022 import com.liferay.portal.kernel.resiliency.spi.SPI;
023 import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration;
024 import com.liferay.portal.kernel.resiliency.spi.remote.RemoteSPI;
025 import com.liferay.portal.kernel.resiliency.spi.remote.RemoteSPIProxy;
026 import com.liferay.portal.kernel.util.StringBundler;
027
028 import java.util.concurrent.Callable;
029 import java.util.concurrent.Future;
030 import java.util.concurrent.FutureTask;
031 import java.util.concurrent.SynchronousQueue;
032 import java.util.concurrent.TimeUnit;
033
034
037 public abstract class BaseSPIProvider implements SPIProvider {
038
039 public abstract RemoteSPI createRemoteSPI(SPIConfiguration spiConfiguration)
040 throws PortalResiliencyException;
041
042 @Override
043 public SPI createSPI(SPIConfiguration spiConfiguration)
044 throws PortalResiliencyException {
045
046 String classPath = getClassPath();
047
048 RemoteSPI remoteSPI = createRemoteSPI(spiConfiguration);
049
050 String spiUUID = remoteSPI.getUUID();
051
052 SynchronousQueue<SPI> synchronousQueue =
053 SPISynchronousQueueUtil.createSynchronousQueue(spiUUID);
054
055 FutureTask<RegistrationReference> weldServerFutureTask =
056 new FutureTask<RegistrationReference>(
057 new WeldServerCallable(remoteSPI.getWelder()));
058
059 Thread weldServerThread = new Thread(
060 weldServerFutureTask,
061 "Weld Server Thread for " + spiConfiguration.getSPIId());
062
063 weldServerThread.setDaemon(true);
064
065 weldServerThread.start();
066
067 try {
068 Future<SPI> cancelHandlerFuture = ProcessExecutor.execute(
069 spiConfiguration.getJavaExecutable(), classPath,
070 spiConfiguration.getJVMArguments(), remoteSPI);
071
072 SPI spi = synchronousQueue.poll(
073 spiConfiguration.getRegisterTimeout(), TimeUnit.MILLISECONDS);
074
075 if (spi != null) {
076 RegistrationReference registrationReference =
077 weldServerFutureTask.get(
078 spiConfiguration.getRegisterTimeout(),
079 TimeUnit.MILLISECONDS);
080
081 RemoteSPIProxy remoteSPIProxy = new RemoteSPIProxy(
082 spi, spiConfiguration, getName(), cancelHandlerFuture,
083 registrationReference);
084
085 if (!MPIHelperUtil.registerSPI(remoteSPIProxy)) {
086 cancelHandlerFuture.cancel(true);
087
088 throw new PortalResiliencyException(
089 "Unable to register SPI " + remoteSPIProxy +
090 ". Forcibly cancelled SPI process launch.");
091 }
092
093 return remoteSPIProxy;
094 }
095
096 cancelHandlerFuture.cancel(true);
097
098 throw new PortalResiliencyException(
099 "SPI synchronous queue waiting timeout. Forcibly " +
100 "cancelled SPI process launch.");
101 }
102 catch (InterruptedException ie) {
103 throw new PortalResiliencyException(
104 "Interrupted on waiting SPI process, registering back RMI stub",
105 ie);
106 }
107 catch (PortalResiliencyException pre) {
108 throw pre;
109 }
110 catch (Exception e) {
111 throw new PortalResiliencyException(
112 "Unable to launch SPI process", e);
113 }
114 finally {
115 weldServerFutureTask.cancel(true);
116
117 SPISynchronousQueueUtil.destroySynchronousQueue(spiUUID);
118 }
119 }
120
121 public abstract String getClassPath();
122
123 @Override
124 public String toString() {
125 StringBundler sb = new StringBundler(5);
126
127 sb.append("{name=");
128 sb.append(getName());
129 sb.append(", classPath=");
130 sb.append(getClassPath());
131 sb.append("}");
132
133 return sb.toString();
134 }
135
136 protected static class WeldServerCallable
137 implements Callable<RegistrationReference> {
138
139 public WeldServerCallable(Welder welder) {
140 _welder = welder;
141 }
142
143 @Override
144 public RegistrationReference call() throws Exception {
145 return _welder.weld(MPIHelperUtil.getIntraband());
146 }
147
148 private final Welder _welder;
149
150 }
151
152 }