Skip to content

Commit

Permalink
Safer threaded compilation and caching of generated classes
Browse files Browse the repository at this point in the history
  • Loading branch information
noboomu committed Aug 13, 2022
1 parent f6a8f19 commit d5eb3e7
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 106 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Proteus Changelog.
## Unreleased
### No issue

**Reduce logging.**


[f6a8f1986b6d0da](https://github.com/noboomu/proteus/commit/f6a8f1986b6d0da) Joshua Bauer *2022-07-19 20:15:26*

**Tweak parameters.**


Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
<nexus-staging-maven-plugin.version>1.6.8</nexus-staging-maven-plugin.version>
<openapi.version>2.2.1</openapi.version>
<openhft-compiler.version>2.21ea82</openhft-compiler.version>
<openhft-compiler.version>2.23ea0</openhft-compiler.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<proteus.version>${project.version}</proteus.version>
<reflections.version>0.10.2</reflections.version>
Expand Down
2 changes: 2 additions & 0 deletions proteus-core/conf/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

<logger name="com.sun.jersey" level="ERROR" />


<logger name="net.openhft.compiler" level="ERROR" />
<logger name="org.xnio" level="ERROR" />
<logger name="io.undertow" level="DEBUG" />
<logger name="org.reflections" level="OFF" />
Expand Down
1 change: 1 addition & 0 deletions proteus-core/conf/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

<logger name="com.sun.jersey" level="ERROR" />

<logger name="net.openhft.compiler" level="ERROR" />
<logger name="org.xnio" level="ERROR" />
<logger name="io.undertow" level="ERROR" />
<logger name="org.reflections" level="OFF" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
import io.undertow.server.session.SessionAttachmentHandler;
import io.undertow.util.Headers;
import io.undertow.util.Methods;
import net.openhft.compiler.CachedCompiler;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnio.Options;
import org.xnio.Xnio;
import org.xnio.XnioWorker;

Expand Down Expand Up @@ -61,6 +61,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -71,11 +72,13 @@
* @author jbauer
*/

@SuppressWarnings("UnusedReturnValue")
@SuppressWarnings({"UnusedReturnValue", "unchecked"})
public class ProteusApplication {

private static Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ProteusApplication.class.getCanonicalName());

private static final String TMP_DIRECTORY_NAME = "proteus_generated_classes";

@Inject
@Named("registeredControllers")
public Set<Class<?>> registeredControllers;
Expand Down Expand Up @@ -118,6 +121,7 @@ public class ProteusApplication {

public ProteusApplication()
{

injector = Guice.createInjector(new ConfigModule());
injector.injectMembers(this);
}
Expand All @@ -138,15 +142,14 @@ public ProteusApplication(URL configURL)

}

public ProteusApplication(Module ... modules)
public ProteusApplication(Module... modules)
{

injector = Guice.createInjector(modules);
injector.injectMembers(this);

}


public void start()
{

Expand All @@ -158,7 +161,6 @@ public void start()

final Thread mainThread = Thread.currentThread();


log.info("Installing modules: {}", registeredModules.stream().map(Class::getSimpleName).collect(Collectors.joining(",")));

Set<Module> modules = registeredModules.stream().map(mc -> injector.getInstance(mc)).collect(Collectors.toSet());
Expand All @@ -182,6 +184,7 @@ public void start()
serviceManager.addListener(new Listener() {
public void stopped()
{

log.info("Services are stopped");

}
Expand All @@ -191,7 +194,7 @@ public void healthy()

log.info("Services are healthy");

startupDuration = Duration.between(startTime,Instant.now());
startupDuration = Duration.between(startTime, Instant.now());

for (ListenerInfo info : undertow.getListenerInfo())
{
Expand All @@ -213,7 +216,7 @@ public void failure(Service service)

log.error("Service failure: " + service);

startupDuration = Duration.between(startTime,Instant.now());
startupDuration = Duration.between(startTime, Instant.now());

for (ListenerInfo info : undertow.getListenerInfo())
{
Expand Down Expand Up @@ -256,24 +259,21 @@ public void failure(Service service)

buildServer();


undertow.start();

Duration timeout = config.getDuration("application.services.timeout");

try
{
serviceManager.startAsync().awaitHealthy(timeout);
} catch( TimeoutException e )
} catch (TimeoutException e)
{
log.error("Failed start to services within {} minutes",timeout,e);
log.error("Failed start to services within {} minutes", timeout, e);
} catch (Exception e)
{
log.error("Failed to start services",e);
log.error("Failed to start services", e);
}



this.running.set(true);

// serviceManager.startAsync();
Expand Down Expand Up @@ -317,6 +317,8 @@ public void buildServer()

CopyOnWriteArrayList<Class<? extends Supplier<RoutingHandler>>> routerClasses = new CopyOnWriteArrayList<>();

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

log.info("Compiling route handlers...");

for (Class<?> controllerClass : registeredControllers)
Expand All @@ -327,19 +329,27 @@ public void buildServer()
try
{

// log.debug("Generating {}...", controllerClass);
// log.debug("Generating {}...", controllerClass);

HandlerGenerator generator = new HandlerGenerator("io.sinistral.proteus.controllers.handlers", controllerClass);

injector.injectMembers(generator);

// log.debug("Compiling {}...", controllerClass);
// log.debug("Compiling {}...", controllerClass);

try (CachedCompiler cachedCompiler = new CachedCompiler(null, getTemporaryDirectoryPath().toFile()))
{
final String source = generator.generateClassSource();
var routerClass = cachedCompiler.loadFromJava(generator.getCanonicalName(), source);

Class<? extends Supplier<RoutingHandler>> routerClass = generator.compileClass();
lock.writeLock().lock();

routerClasses.add(routerClass);

lock.writeLock().unlock();
}

routerClasses.add(routerClass);

// log.debug("Compiled {}", controllerClass);

} catch (Exception e)
{
Expand All @@ -359,7 +369,7 @@ public void buildServer()
log.error("Failed waiting for handlers to generate", e);
}

log.debug("Compilation completed in {}", DurationFormatUtils.formatDurationHMS(Duration.between(compilationStartTime,Instant.now()).toMillis()));
log.debug("Compilation completed in {}", DurationFormatUtils.formatDurationHMS(Duration.between(compilationStartTime, Instant.now()).toMillis()));

for (Class<? extends Supplier<RoutingHandler>> clazz : routerClasses)
{
Expand Down Expand Up @@ -400,8 +410,7 @@ public void buildServer()
handler = sessionAttachmentHandler;
}


if(config.hasPath("undertow.gracefulShutdown") && config.getBoolean("undertow.gracefulShutdown"))
if (config.hasPath("undertow.gracefulShutdown") && config.getBoolean("undertow.gracefulShutdown"))
{
handler = new GracefulShutdownHandler(handler);
}
Expand Down Expand Up @@ -433,7 +442,6 @@ public void buildServer()
.setServerOption(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, config.getInt("undertow.server.maxBufferedRequestSize"))
.setHandler(handler);


if (config.getBoolean("undertow.ssl.enabled"))
{
try
Expand Down Expand Up @@ -522,7 +530,7 @@ public ProteusApplication addDefaultRoutes(RoutingHandler router)
{
exchange.getResponseHeaders().add(Headers.CONTENT_TYPE, MediaType.TEXT_PLAIN);

if(this.serviceManager.servicesByState().values().stream().allMatch(Service::isRunning))
if (this.serviceManager.servicesByState().values().stream().allMatch(Service::isRunning))
{
exchange.setStatusCode(200).getResponseSender().send("OK");
}
Expand Down Expand Up @@ -734,7 +742,7 @@ public void printStatus()
tableHeaders = Arrays.asList("Method", "Path", "Consumes", "Produces", "Controller");

tableRows = this.registeredEndpoints.stream().sorted().map(e ->
Arrays.asList(e.getMethod().toString(), e.getPathTemplate(), String.format("[%s]", e.getConsumes()), String.format("[%s]", e.getProduces()), String.format("(%s.%s)", e.getControllerName(), e.getControllerMethod())))
Arrays.asList(e.getMethod().toString(), e.getPathTemplate(), String.format("[%s]", e.getConsumes()), String.format("[%s]", e.getProduces()), String.format("(%s.%s)", e.getControllerName(), e.getControllerMethod())))
.collect(Collectors.toList());

printer = new TablePrinter(tableHeaders, tableRows);
Expand All @@ -748,17 +756,33 @@ public void printStatus()
tableHeaders = Arrays.asList("Service", "State", "Startup Time");

tableRows = serviceStateMap.asMap().entrySet().stream().flatMap(e ->
e.getValue().stream().map(s ->
Arrays.asList(s.getClass().getSimpleName(), e.getKey().toString(), DurationFormatUtils.formatDurationHMS(serviceStartupTimeMap.get(s)))))
e.getValue().stream().map(s ->
Arrays.asList(s.getClass().getSimpleName(), e.getKey().toString(), DurationFormatUtils.formatDurationHMS(serviceStartupTimeMap.get(s)))))
.collect(Collectors.toList());

printer = new TablePrinter(tableHeaders, tableRows);

sb.append(printer.toString()).append("\nListening On: " + this.ports).append("\nApplication Startup Time: ").append(DurationFormatUtils.formatDurationHMS(this.startupDuration.toMillis())).append( "\n");
sb.append(printer.toString()).append("\nListening On: " + this.ports).append("\nApplication Startup Time: ").append(DurationFormatUtils.formatDurationHMS(this.startupDuration.toMillis())).append("\n");

log.info(sb.toString());
}

protected java.nio.file.Path getTemporaryDirectoryPath() throws Exception
{

String tmpDirLocation = System.getProperty("java.io.tmpdir");

java.nio.file.Path tmpPath = Paths.get(tmpDirLocation);

try
{
return Files.createDirectory(tmpPath.resolve(TMP_DIRECTORY_NAME));

} catch (Exception e)
{
return tmpPath;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

@Singleton
public class JacksonModule extends AbstractModule
{
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;

@Singleton
public class XmlModule extends AbstractModule {

@Override
Expand Down
Loading

0 comments on commit d5eb3e7

Please sign in to comment.