mirror of https://github.com/apache/cloudstack.git
use event instead of poll for xapi async call in XS 6.2 and above to reduce the pressure on XAPI
This commit is contained in:
parent
0ae35ddbfd
commit
9f44909e63
|
|
@ -214,6 +214,7 @@ import org.w3c.dom.Node;
|
|||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
|
@ -664,16 +665,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
+ " with args " + getArgsString(args)
|
||||
+ " due to HandleInvalid clazz:" + e.clazz + ", handle:"
|
||||
+ e.handle);
|
||||
} catch (XenAPIException e) {
|
||||
} catch (Exception e) {
|
||||
s_logger.warn(
|
||||
"callHostPlugin failed for cmd: " + cmd + " with args "
|
||||
+ getArgsString(args) + " due to " + e.toString(),
|
||||
e);
|
||||
} catch (XmlRpcException e) {
|
||||
s_logger.warn(
|
||||
"callHostPlugin failed for cmd: " + cmd + " with args "
|
||||
+ getArgsString(args) + " due to " + e.getMessage(),
|
||||
e);
|
||||
} finally {
|
||||
if (task != null) {
|
||||
try {
|
||||
|
|
@ -3310,7 +3306,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void waitForTask(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException {
|
||||
protected void waitForTask(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
|
||||
|
|
@ -3328,7 +3324,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
|
||||
s_logger.warn(msg);
|
||||
task.cancel(c);
|
||||
throw new Types.BadAsyncResult(msg);
|
||||
throw new TimeoutException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3347,7 +3343,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
void rebootVM(Connection conn, VM vm, String vmName) throws XmlRpcException {
|
||||
void rebootVM(Connection conn, VM vm, String vmName) throws Exception {
|
||||
Task task = null;
|
||||
try {
|
||||
task = vm.cleanRebootAsync(conn);
|
||||
|
|
@ -3403,7 +3399,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
//poll every 1 seconds , timeout after 10 minutes
|
||||
waitForTask(conn, task, 1000, 10 * 60 * 1000);
|
||||
checkForSuccess(conn, task);
|
||||
} catch (Types.HandleInvalid e) {
|
||||
} catch (TimeoutException e) {
|
||||
if (vm.getPowerState(conn) == Types.VmPowerState.HALTED) {
|
||||
task = null;
|
||||
return;
|
||||
|
|
@ -3448,7 +3444,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
void startVM(Connection conn, Host host, VM vm, String vmName) throws XmlRpcException {
|
||||
void startVM(Connection conn, Host host, VM vm, String vmName) throws Exception {
|
||||
Task task = null;
|
||||
try {
|
||||
task = vm.startOnAsync(conn, host, false, true);
|
||||
|
|
@ -3463,7 +3459,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return;
|
||||
}
|
||||
throw new CloudRuntimeException("Start VM " + vmName + " catch HandleInvalid and VM is not in RUNNING state");
|
||||
} catch (Types.BadAsyncResult e) {
|
||||
} catch (TimeoutException e) {
|
||||
if (vm.getPowerState(conn) == Types.VmPowerState.RUNNING) {
|
||||
s_logger.debug("VM " + vmName + " is in Running status");
|
||||
task = null;
|
||||
|
|
@ -3486,7 +3482,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
private void migrateVM(Connection conn, Host destHost, VM vm, String vmName) throws XmlRpcException {
|
||||
private void migrateVM(Connection conn, Host destHost, VM vm, String vmName) throws Exception {
|
||||
Task task = null;
|
||||
try {
|
||||
Map<String, String> other = new HashMap<String, String>();
|
||||
|
|
@ -3519,7 +3515,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
protected VDI cloudVDIcopy(Connection conn, VDI vdi, SR sr, int wait) throws XenAPIException, XmlRpcException {
|
||||
protected VDI cloudVDIcopy(Connection conn, VDI vdi, SR sr, int wait) throws Exception {
|
||||
Task task = null;
|
||||
if (wait == 0) {
|
||||
wait = 2 * 60 * 60;
|
||||
|
|
@ -3568,7 +3564,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
e.handle);
|
||||
} catch (XenAPIException e) {
|
||||
s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
|
||||
} catch (XmlRpcException e) {
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (task != null) {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,18 @@ import com.xensource.xenapi.Connection;
|
|||
import com.xensource.xenapi.Host;
|
||||
import com.xensource.xenapi.HostPatch;
|
||||
import com.xensource.xenapi.PoolPatch;
|
||||
import com.xensource.xenapi.Event;
|
||||
import com.xensource.xenapi.Task;
|
||||
import com.xensource.xenapi.Types;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.HashSet;
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.resource.ServerResource;
|
||||
|
||||
|
|
@ -105,4 +109,56 @@ public class XenServer620Resource extends XenServer610Resource {
|
|||
}
|
||||
cmd.setHostDetails(details);
|
||||
}
|
||||
|
||||
|
||||
protected void waitForTask(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
|
||||
"ms timeout");
|
||||
}
|
||||
Set<String> classes = new HashSet<String>();
|
||||
classes.add("Task/" + task.toWireString());
|
||||
String token = "";
|
||||
Double t = new Double(timeout / 1000);
|
||||
while (true) {
|
||||
Map<?, ?> map = Event.properFrom(c, classes, token, t);
|
||||
token = (String)map.get("token");
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Event.Record> events = (Set<Event.Record>)map.get("events");
|
||||
if (events.size() == 0) {
|
||||
String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
|
||||
s_logger.warn(msg);
|
||||
task.cancel(c);
|
||||
throw new TimeoutException(msg);
|
||||
}
|
||||
for (Event.Record rec : events) {
|
||||
if (!(rec.snapshot instanceof Task.Record)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Skipping over " + rec);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Task.Record taskRecord = (Task.Record)rec.snapshot;
|
||||
|
||||
if (taskRecord.status != Types.TaskStatusType.PENDING) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Task is done " + taskRecord.status);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
s_logger.debug("Task is not done " + taskRecord);
|
||||
}
|
||||
}
|
||||
if (System.currentTimeMillis() - beginTime > timeout) {
|
||||
String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
|
||||
s_logger.warn(msg);
|
||||
task.cancel(c);
|
||||
throw new TimeoutException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,29 +21,26 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
|
||||
import com.xensource.xenapi.Connection;
|
||||
import com.xensource.xenapi.Event;
|
||||
import com.xensource.xenapi.Host;
|
||||
import com.xensource.xenapi.Pool;
|
||||
import com.xensource.xenapi.Task;
|
||||
import com.xensource.xenapi.Types;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import com.xensource.xenapi.VM;
|
||||
import com.xensource.xenapi.Event;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.ClusterSyncAnswer;
|
||||
import com.cloud.agent.api.ClusterSyncCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.hypervisor.xen.resource.XenServer620SP1Resource;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineName;
|
||||
import com.cloud.hypervisor.xen.resource.XenServer620SP1Resource;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -99,48 +96,6 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource {
|
|||
return cmds;
|
||||
}
|
||||
|
||||
protected void waitForTask2(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
|
||||
"ms timeout");
|
||||
}
|
||||
Set<String> classes = new HashSet<String>();
|
||||
classes.add("Task/" + task.toString());
|
||||
String token = "";
|
||||
Double t = new Double(timeout / 1000);
|
||||
while (true) {
|
||||
Map<?, ?> map = Event.properFrom(c, classes, token, t);
|
||||
token = (String)map.get("token");
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Event.Record> events = (Set<Event.Record>)map.get("events");
|
||||
if (events.size() == 0) {
|
||||
String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
|
||||
s_logger.warn(msg);
|
||||
task.cancel(c);
|
||||
throw new TimeoutException(msg);
|
||||
}
|
||||
for (Event.Record rec : events) {
|
||||
if (!(rec.snapshot instanceof Task.Record)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Skipping over " + rec);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Task.Record taskRecord = (Task.Record)rec.snapshot;
|
||||
|
||||
if (taskRecord.status != Types.TaskStatusType.PENDING) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Task is done " + taskRecord.status);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
s_logger.debug("Task is not done " + taskRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Answer execute(final ClusterSyncCommand cmd) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue