Skip to content

Commit

Permalink
feat(deployment): Add shutdown-on-startup and skip-upgrade properties…
Browse files Browse the repository at this point in the history
… to support k8s init container use (#31003) (#31047)

### Proposed Changes
* Add a FinalStartupServlet servlet that initializes after all other
servlets that are set to run on startup. This will check for the
shutdown-on-startup config property (DOT_SHUTDOWN_ON_STARTUP as an env
var) default false, and if true the server will shut down with exit code
0 just before accepting connections. All startup initialization and
upgrade tasks should have been completed. This can be used to run as an
Init Container in K8s
* Add a skip-upgrade config ( DOT_SKIP_UPGRADE ) default false. If set
to true the DB startup tasks will not be attempted to be run. This can
be used in a k8s pod replica when it is known that the upgrade tasks
have been handled by the init container. There may not be much of a
downside of leaving this off as it should detect the work has already
been done, but this may help to reduce some unecessary work and also
distinguish if there are some tasks that need to be run per instance vs
per cluster/db.
* Add and fix some logging helping to distinguish the location of
startup steps between Servlets and ServletListeners.

### Testing
At this stage a basic test that the server does shut down with exit 0
after all startup tasks when DOT_SHUTDOWN_ON_STARTUP=true is passed, and
the fact that with the defaults, it does not impact any existing
behavior is required. This will be further tested when implementing the
init container that will make use of this flag.
  • Loading branch information
spbolton authored Jan 8, 2025
1 parent 1956937 commit 7bdf6b5
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dotcms.api.web;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -13,9 +14,12 @@ public class RequestThreadLocalListener implements ServletRequestListener {


public RequestThreadLocalListener() {
Logger.info(this.getClass(), "Starting RequestThreadLocalListener");
}

public void contextInitialized(ServletContextEvent sce) {
Logger.info(this.getClass(), "Starting RequestThreadLocalListener");
}

public void requestDestroyed(ServletRequestEvent requestEvent) {
HttpServletRequestThreadLocal.INSTANCE.setRequest(null);
DotVelocitySecretAppConfigThreadLocal.INSTANCE.clearConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ public void contextDestroyed(ServletContextEvent arg0) {
}

public void contextInitialized(ServletContextEvent arg0) {

Logger.info(this,"ContextLifecycleListener contextInitialized called");
ByteBuddyFactory.init();

Config.setMyApp(arg0.getServletContext());

installWebSocket(arg0.getServletContext());
Logger.info(this,"ContextLifecycleListener contextInitialized completed");
}

private void installWebSocket(final ServletContext serverContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.dotmarketing.servlets;

import com.dotmarketing.util.Config;
import com.dotmarketing.util.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
//import javax.servlet.annotation.WebServlet;

/**
* This servlet is used to check if the server should be shutdown on startup.
* If the property shutdown-on-startup is set to true, the server will be shutdown
* The loadOnStartup is set to the highest value to ensure it is run after all other servlets that are not
* lazy loaded
*/
public class FinalStartupServlet extends HttpServlet {

// init method
@Override
public void init(ServletConfig cfg) throws ServletException {
super.init(cfg);
Logger.info(this, "Starting FinalStartupServlet");
if (Config.getBooleanProperty("shutdown-on-startup", false)) {
Logger.info(this, "shutdown-on-startup is true, shutting down the server");
System.exit(0);
}
}

@Override
public void destroy() {
Logger.info(this, "FinalStartupServlet destroyed");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void destroy() {
* @throws DotDataException
*/
public void init(ServletConfig config) throws ServletException {
Logger.info(this,"InitServlet init Started");

startupDate = new java.util.Date();
new StartupLogger().log();
Expand Down Expand Up @@ -259,6 +260,8 @@ public void init(ServletConfig config) throws ServletException {
Logger.warn(this.getClass(), "Unable to record startup time :" + e);
}

Logger.info(this,"InitServlet init Completed");

}

protected void deleteFiles(java.io.File directory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class InitServlet extends HttpServlet {

public void init() throws ServletException {
synchronized (InitServlet.class) {
Logger.info(this, "Portal InitServlet init method called");

// Initialize

Expand Down Expand Up @@ -75,6 +76,7 @@ public void init() throws ServletException {
Logger.error(this,e.getMessage(),e);
}
}
Logger.info(this, "Portal InitServlet init method completed");
}

@Override
Expand Down
25 changes: 16 additions & 9 deletions dotCMS/src/main/java/com/liferay/portal/servlet/MainServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@
*/
public class MainServlet extends ActionServlet {

public static final String SKIP_UPGRADE = "skip-upgrade";

@CloseDBIfOpened // Note if ByteBuddyFactory not initialized before this class this may not be wrapped
public void init(ServletConfig config) throws ServletException {
synchronized (MainServlet.class) {
Logger.info(this, "MainServlet init started");
ByteBuddyFactory.init();
super.init(config);
Config.initializeConfig();
Expand All @@ -115,10 +118,11 @@ public void init(ServletConfig config) throws ServletException {

try {
// Checking for execute upgrades
StartupTasksExecutor.getInstance().executeStartUpTasks();
StartupTasksExecutor.getInstance().executeSchemaUpgrades();
StartupTasksExecutor.getInstance().executeBackportedTasks();

if (!Config.getBooleanProperty(SKIP_UPGRADE, false)) {
StartupTasksExecutor.getInstance().executeStartUpTasks();
StartupTasksExecutor.getInstance().executeSchemaUpgrades();
StartupTasksExecutor.getInstance().executeBackportedTasks();
}
final Task00030ClusterInitialize clusterInitializeTask = new Task00030ClusterInitialize();
if(clusterInitializeTask.forceRun()){
clusterInitializeTask.executeUpgrade();
Expand Down Expand Up @@ -207,13 +211,16 @@ public void init(ServletConfig config) throws ServletException {
// Init other dotCMS services.
DotInitializationService.getInstance().initialize();

try {
// Now that everything is up we can check if we need to execute data upgrade tasks
StartupTasksExecutor.getInstance().executeDataUpgrades();
} catch (Exception e) {
throw new DotRuntimeException("Error executing data upgrade tasks", e);
if (!Config.getBooleanProperty(SKIP_UPGRADE, false)) {
try {
// Now that everything is up we can check if we need to execute data upgrade tasks
StartupTasksExecutor.getInstance().executeDataUpgrades();
} catch (Exception e) {
throw new DotRuntimeException("Error executing data upgrade tasks", e);
}
}
}
Logger.info(this, "MainServlet init completed");
}

public void callParentService(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
Expand Down
6 changes: 6 additions & 0 deletions dotCMS/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@
<servlet-class>com.dotmarketing.servlets.InitServlet</servlet-class>
<load-on-startup>8</load-on-startup>
</servlet>

<servlet>
<servlet-name>FinalStartupServlet</servlet-name>
<servlet-class>com.dotmarketing.servlets.FinalStartupServlet</servlet-class>
<load-on-startup>99999</load-on-startup>
</servlet>

<servlet>
<servlet-name>VelocityServlet</servlet-name>
Expand Down

0 comments on commit 7bdf6b5

Please sign in to comment.