Skip to content

Commit 238f539

Browse files
committed
Improve job diagnostics
1 parent c7728a5 commit 238f539

2 files changed

Lines changed: 86 additions & 10 deletions

File tree

plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/ProjectUtils.java

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@
2121

2222
import com.google.cloud.tools.eclipse.test.util.reflection.ReflectionUtil;
2323
import com.google.common.base.Joiner;
24+
import com.google.common.base.Preconditions;
2425
import com.google.common.base.Stopwatch;
26+
import com.google.common.collect.ComparisonChain;
27+
import com.google.common.collect.Ordering;
2528
import java.io.File;
2629
import java.io.IOException;
2730
import java.net.URL;
2831
import java.util.ArrayList;
32+
import java.util.Arrays;
2933
import java.util.Collection;
3034
import java.util.Collections;
3135
import java.util.Enumeration;
@@ -38,6 +42,7 @@
3842
import java.util.concurrent.TimeUnit;
3943
import java.util.zip.ZipEntry;
4044
import java.util.zip.ZipFile;
45+
import org.eclipse.core.internal.jobs.InternalJob;
4146
import org.eclipse.core.resources.IMarker;
4247
import org.eclipse.core.resources.IProject;
4348
import org.eclipse.core.resources.IProjectDescription;
@@ -283,30 +288,94 @@ public static void waitForProjects(Runnable delayTactic, IProject... projects) {
283288
buildErrorsChanging = !previousBuildErrors.equals(currentBuildErrors);
284289
previousBuildErrors = currentBuildErrors;
285290

286-
if (DEBUG || timer.elapsed(TimeUnit.SECONDS) > 10) {
287-
if (!jobs.isEmpty()) {
291+
if (DEBUG || timer.elapsed(TimeUnit.SECONDS) > 5) {
292+
if (timer.elapsed(TimeUnit.SECONDS) > 10) {
293+
dumpJobsState(timer);
294+
} else if (!jobs.isEmpty()) {
288295
System.err.printf("ProjectUtils#waitForProjects[%s]: waiting for %d jobs: %s\n", timer,
289296
jobs.size(), jobs);
290297
}
291298
if (buildErrorsChanging) {
292299
System.err.printf("ProjectUtils#waitForProjects[%s]: waiting for %d build errors\n",
293300
timer, currentBuildErrors.size());
294301
}
295-
// Uncomment if tests are failing to identify any other build-related jobs.
296-
// Job[] otherJobs = Job.getJobManager().find(null);
297-
// if (otherJobs.length > 0) {
298-
// System.err.printf("Ignoring %d unrelated jobs:\n", otherJobs.length);
299-
// for (Job job : otherJobs) {
300-
// System.err.printf(" %s: %s\n", job.getClass().getName(), job);
301-
// }
302-
// }
303302
}
304303
} while (!jobs.isEmpty() || buildErrorsChanging);
305304
} catch (CoreException | InterruptedException ex) {
306305
throw new RuntimeException(ex);
307306
}
308307
}
309308

309+
private static void dumpJobsState(Stopwatch timer) {
310+
Job[] otherJobs = Job.getJobManager().find(null);
311+
if (otherJobs.length == 0) {
312+
System.err.printf("ProjectUtils#dumpJobsState[%s]: no jobs\n", timer);
313+
return;
314+
}
315+
316+
Arrays.sort(otherJobs, new Ordering<Job>() {
317+
@Override
318+
public int compare(Job j1, Job j2) {
319+
Preconditions.checkNotNull(j1);
320+
Preconditions.checkNotNull(j2);
321+
//@formatter:off
322+
return ComparisonChain.start()
323+
.compareTrueFirst(j1.isBlocking(), j2.isBlocking())
324+
.compare(j2.getState(), j1.getState()) // descending order so RUNNING is first
325+
.compare(j1.getPriority(), j2.getPriority())
326+
.compareTrueFirst(j1.isUser(), j2.isUser())
327+
.compareTrueFirst(j1.isSystem(), j2.isSystem())
328+
.compare(j1.getRule(), j2.getRule(), Ordering.usingToString().nullsLast())
329+
.result();
330+
//@formatter:on
331+
}
332+
});
333+
334+
System.err.printf("ProjectUtils#dumpJobsState[%s]: %d jobs:\n", timer, otherJobs.length);
335+
for (Job job : otherJobs) {
336+
String status;
337+
switch (job.getState()) {
338+
case Job.RUNNING:
339+
status = "RUNNING";
340+
break;
341+
case Job.WAITING:
342+
status = "WAITING";
343+
break;
344+
case Job.SLEEPING:
345+
status = "SLEEPING";
346+
break;
347+
case Job.NONE:
348+
status = "NONE";
349+
break;
350+
default:
351+
status = "UNKNOWN(" + job.getState() + ")";
352+
break;
353+
}
354+
Object blockingJob = null;
355+
try {
356+
blockingJob = ReflectionUtil.invoke(Job.getJobManager(), "findBlockingJob",
357+
new Class<?>[] {InternalJob.class}, InternalJob.class, job);
358+
} catch (Exception ex) {
359+
System.err.println("Unable to fetch blocking-job: " + ex);
360+
}
361+
//@formatter:off
362+
System.err.printf(" + %s%s{pri=%d%s%s%s%s} %s (%s)\n",
363+
status,
364+
(job.isBlocking() ? "<BLOCKING>" : ""),
365+
job.getPriority(),
366+
(job.getRule() != null ? ",rule=" + job.getRule() : ""),
367+
(job.isSystem() ? ",system" : ""),
368+
(job.isUser() ? ",user" : ""),
369+
(job.getThread() != null ? ",thr=" + job.getThread() : ""),
370+
job,
371+
job.getClass().getName());
372+
//@formatter:on
373+
if (blockingJob != null) {
374+
System.err.println(" - blocked by: " + blockingJob);
375+
}
376+
}
377+
}
378+
310379
/** Identify all jobs that we know of that are related to building. */
311380
private static Collection<Job> findPendingBuildJobs(IProject... projects) {
312381
Set<Job> jobs = new HashSet<>();

plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/reflection/ReflectionUtil.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ public static <T> T invoke(Object object, String methodName, Class<T> returnType
4242
for (int i = 0; i < parameters.length; i++) {
4343
parameterTypes[i] = parameters[i] == null ? Object.class : parameters[i].getClass();
4444
}
45+
return invoke(object, methodName, parameterTypes, returnType, parameters);
46+
}
47+
48+
/** Invoke a method. */
49+
public static <T> T invoke(Object object, String methodName, Class<?>[] parameterTypes,
50+
Class<T> returnType, Object... parameters) throws NoSuchMethodException, SecurityException,
51+
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
4552
Method method = object.getClass().getDeclaredMethod(methodName, parameterTypes);
4653
method.setAccessible(true);
4754
return returnType.cast(method.invoke(object, parameters));

0 commit comments

Comments
 (0)