Background Task Executor in Liferay

We may face some scenario to execute a process which might consume JVM memory and keeps the web page loading when dealing with large tasks like file uploads. Liferay has BackgroundTaskExecutor which internally acts like multi-threading which we require to send metadata to the background so the BackgroundTask Framework will take care of executing the task in background.

Below code for reference:

Step 1: Create a class (CustomBackgroundExecutor in my case) in any of your existing module which has to extend BaseBackgroundTaskExecutor class.

@Component(property = 

//GIVE YOUR FULLY QUALIFIED CLASS NAME WHERE YOUR BACKGROUND EXECUTOR IS PRESENT

"background.task.executor.class.name=com.file.zipper.web.portlet.CustomBackgroundExecutor",

service = BackgroundTaskExecutor.class)

public class CustomBackgroundExecutor extends BaseBackgroundTaskExecutor {

@Override

public BackgroundTaskResult execute(BackgroundTask backgroundTask) throws Exception {

logger.info("EXECUTING BACKGROUND TASK::: ");

Map<String, Serializable> taskContextMap = backgroundTask.getTaskContextMap();

logger.info("UPLOADED FILE NAME:::"+taskContextMap.get("currFileName"));

File file = new File((String) taskContextMap.get("filePath"));

// YOUR FILE UPLOAD LOGIC GOES HERE

return BackgroundTaskResult.SUCCESS;

}

@Override

public boolean isSerial() {

// RETURN TRUE IF YOU WANT TO EXECUTE IN SERIAL MANNER

return false;

}

@Override

public BackgroundTaskDisplay getBackgroundTaskDisplay(BackgroundTask backgroundTask) {

return null;

}

@Override

public BackgroundTaskExecutor clone() {

return this;

}

private static final Log logger = LogFactoryUtil.getLog(CustomBackgroundExecutor.class);

}

 

Imports for your reference:

import java.io.File;

import java.io.Serializable;

import java.util.Map;

import org.osgi.service.component.annotations.Component;

import com.liferay.portal.kernel.backgroundtask.BackgroundTask;

import com.liferay.portal.kernel.backgroundtask.BackgroundTaskExecutor;

import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;

import com.liferay.portal.kernel.backgroundtask.BaseBackgroundTaskExecutor;

import com.liferay.portal.kernel.backgroundtask.display.BackgroundTaskDisplay;

import com.liferay.portal.kernel.log.Log;

import com.liferay.portal.kernel.log.LogFactoryUtil;

 

Step 2: Use below code for reference in any of your methods to send contextual information to the background executor.

ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

ServiceContext serviceContext = new ServiceContext();

UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(actionRequest);

File file = uploadPortletRequest.getFile("file");

try {

Map<String, Serializable> taskContextMap = new HashMap<>();

taskContextMap.put("currFileName", uploadPortletRequest.getFileName("file"));

taskContextMap.put("filePath", file.getAbsolutePath());

BackgroundTask backgroundTask = BackgroundTaskManagerUtil.addBackgroundTask(

themeDisplay.getUserId(),

themeDisplay.getScopeGroupId(),

// YOUR CURRENT CLASS

YOUR_CURRENT.class.getName(),

// YOUR BACKGROUND EXECUTOR QUALIFIED NAME

CustomBackgroundExecutor.class.getName(),

taskContextMap,

serviceContext

);

logger.info("ADDED TO BACKGROUND::: "+backgroundTask);

} catch (PortalException e) {

logger.error(e);

}

 

Imports for your reference:

import java.io.File;

import java.io.Serializable;

import java.util.HashMap;

import java.util.Map;

import com.liferay.portal.kernel.backgroundtask.BackgroundTask;

import com.liferay.portal.kernel.backgroundtask.BackgroundTaskManagerUtil;

 

Step 3: Now, Try uploading a file to check the Background Task Framework in action.