fixes:
save and recovery thread context
@@ -9,6 +9,8 @@ import org.zstack.core.cloudbus.MessageSafe;
import org.zstack.core.config.GlobalConfig;
import org.zstack.core.config.GlobalConfigUpdateExtensionPoint;
import org.zstack.core.db.*;
+import org.zstack.core.defer.Defer;
+import org.zstack.core.defer.Deferred;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.core.progress.ProgressCommands.ProgressReportCmd;
import org.zstack.core.thread.CancelablePeriodicTask;
@@ -27,22 +29,18 @@ import org.zstack.utils.Utils;
import org.zstack.utils.gson.JSONObjectUtil;
import org.zstack.utils.logging.CLogger;
+import javax.persistence.Query;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import static java.util.Collections.max;
-import static java.util.Collections.min;
import static org.codehaus.groovy.runtime.InvokerHelper.asList;
-
import static org.zstack.core.Platform.toI18nString;
import static org.zstack.header.Constants.THREAD_CONTEXT_API;
import static org.zstack.header.Constants.THREAD_CONTEXT_TASK_NAME;
-import javax.persistence.Query;
-
/**
* Created by mingjian.deng on 16/12/10.
@@ -60,6 +58,11 @@ public class ProgressReportService extends AbstractService implements Management
@Autowired
private CloudBus bus;
+ private class ThreadContextMapSaved {
+ public Map<String, String> contextMap = new HashMap<>();
+ public ThreadContext.ContextStack contextStack;
+ }
+
private int DELETE_DELAY = 300;
private Future<Void> cleanupThread;
@@ -112,6 +115,18 @@ public class ProgressReportService extends AbstractService implements Management
return DELETE_DELAY;
}
+ private Runnable saveThreadContext() {
+ ThreadContextMapSaved savedThread = new ThreadContextMapSaved();
+ savedThread.contextMap = ThreadContext.getContext();
+ savedThread.contextStack = ThreadContext.cloneStack();
+
+ return () -> {
+ ThreadContext.clearAll();
+ ThreadContext.putAll(savedThread.contextMap);
+ ThreadContext.setStack(savedThread.contextStack.asList());
+ };
+ }
+
private void setThreadContext(ProgressReportCmd cmd) {
ThreadContext.clearAll();
if (cmd.getThreadContextMap() != null) {
@@ -126,7 +141,10 @@ public class ProgressReportService extends AbstractService implements Management
public boolean start() {
restf.registerSyncHttpCallHandler(ProgressConstants.PROGRESS_REPORT_PATH, ProgressReportCmd.class, new SyncHttpCallHandler<ProgressReportCmd>() {
@Override
+ @Deferred
public String handleSyncHttpCall(ProgressReportCmd cmd) {
+ Runnable cleanup = saveThreadContext();
+ Defer.defer(cleanup);
setThreadContext(cmd);
logger.debug(String.format("report progress is : %s", cmd.getProgress()));
taskProgress(TaskType.Progress, cmd.getProgress());
