Blogs
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.