Skip to content

Commit b484990

Browse files
committed
Add a TaskService to create & manage running tasks
1 parent 598af21 commit b484990

File tree

8 files changed

+546
-1
lines changed

8 files changed

+546
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111

1212
<artifactId>scijava-common</artifactId>
13-
<version>2.64.1-SNAPSHOT</version>
13+
<version>2.65.0-SNAPSHOT</version>
1414

1515
<name>SciJava Common</name>
1616
<description>SciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by downstream projects in the SciJava ecosystem, such as ImageJ and SCIFIO.</description>
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2017 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
7+
* Institute of Molecular Cell Biology and Genetics, University of
8+
* Konstanz, and KNIME GmbH.
9+
* %%
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions are met:
12+
*
13+
* 1. Redistributions of source code must retain the above copyright notice,
14+
* this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright notice,
16+
* this list of conditions and the following disclaimer in the documentation
17+
* and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
23+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
* #L%
31+
*/
32+
package org.scijava.task;
33+
34+
import java.util.concurrent.ExecutionException;
35+
import java.util.concurrent.Future;
36+
37+
import org.scijava.event.EventService;
38+
import org.scijava.task.event.TaskEvent;
39+
import org.scijava.thread.ThreadService;
40+
41+
/**
42+
* Default implementation of {@link Task}. It launches code via the linked
43+
* {@link ThreadService}, and reports status updates via the linked
44+
* {@link EventService}.
45+
*
46+
* @author Curtis Rueden
47+
*/
48+
public class DefaultTask implements Task {
49+
50+
private final ThreadService threadService;
51+
private final EventService eventService;
52+
53+
private Future<?> future;
54+
55+
private boolean canceled;
56+
private String cancelReason;
57+
58+
private String status;
59+
private long step;
60+
private long max;
61+
62+
private String name;
63+
64+
/**
65+
* Creates a new task.
66+
*
67+
* @param threadService Service to use for launching the task in its own
68+
* thread. Required.
69+
* @param eventService Service to use for reporting status updates as
70+
* {@link TaskEvent}s. May be null, in which case no events are
71+
* reported.
72+
*/
73+
public DefaultTask(final ThreadService threadService,
74+
final EventService eventService)
75+
{
76+
this.threadService = threadService;
77+
this.eventService = eventService;
78+
}
79+
80+
// -- Task methods --
81+
82+
@Override
83+
public void run(final Runnable r) {
84+
if (r == null) throw new NullPointerException();
85+
future(r);
86+
}
87+
88+
@Override
89+
public void waitFor() throws InterruptedException, ExecutionException {
90+
future().get();
91+
}
92+
93+
@Override
94+
public boolean isDone() {
95+
return future != null && future.isDone();
96+
}
97+
98+
@Override
99+
public String getStatusMessage() {
100+
return status;
101+
}
102+
103+
@Override
104+
public long getProgressValue() {
105+
return step;
106+
}
107+
108+
@Override
109+
public long getProgressMaximum() {
110+
return max;
111+
}
112+
113+
@Override
114+
public void setStatusMessage(final String status) {
115+
this.status = status;
116+
fireTaskEvent();
117+
}
118+
119+
@Override
120+
public void setProgressValue(final long step) {
121+
this.step = step;
122+
fireTaskEvent();
123+
}
124+
125+
@Override
126+
public void setProgressMaximum(final long max) {
127+
this.max = max;
128+
fireTaskEvent();
129+
}
130+
131+
// -- Cancelable methods --
132+
133+
@Override
134+
public boolean isCanceled() {
135+
return canceled;
136+
}
137+
138+
@Override
139+
public void cancel(final String reason) {
140+
canceled = true;
141+
cancelReason = reason;
142+
}
143+
144+
@Override
145+
public String getCancelReason() {
146+
return cancelReason;
147+
}
148+
149+
// -- Named methods --
150+
151+
@Override
152+
public String getName() {
153+
return name;
154+
}
155+
156+
@Override
157+
public void setName(final String name) {
158+
this.name = name;
159+
}
160+
161+
// -- Helper methods --
162+
163+
private Future<?> future() {
164+
return future(null);
165+
}
166+
167+
private Future<?> future(final Runnable r) {
168+
if (future == null) initFuture(r);
169+
return future;
170+
}
171+
172+
private synchronized void initFuture(final Runnable r) {
173+
if (future != null) return;
174+
if (r == null) throw new IllegalArgumentException("Must call run first");
175+
future = threadService.run(r);
176+
}
177+
178+
private void fireTaskEvent() {
179+
if (eventService != null) eventService.publish(new TaskEvent(this));
180+
}
181+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2017 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
7+
* Institute of Molecular Cell Biology and Genetics, University of
8+
* Konstanz, and KNIME GmbH.
9+
* %%
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions are met:
12+
*
13+
* 1. Redistributions of source code must retain the above copyright notice,
14+
* this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright notice,
16+
* this list of conditions and the following disclaimer in the documentation
17+
* and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
23+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
* #L%
31+
*/
32+
33+
package org.scijava.task;
34+
35+
import org.scijava.event.EventService;
36+
import org.scijava.plugin.Parameter;
37+
import org.scijava.plugin.Plugin;
38+
import org.scijava.service.AbstractService;
39+
import org.scijava.service.Service;
40+
import org.scijava.thread.ThreadService;
41+
42+
/**
43+
* Default implementation of {@link TaskService}.
44+
*
45+
* @author Curtis Rueden
46+
*/
47+
@Plugin(type = Service.class)
48+
public class DefaultTaskService extends AbstractService implements
49+
TaskService
50+
{
51+
52+
@Parameter
53+
private ThreadService threadService;
54+
55+
@Parameter(required = false)
56+
private EventService eventService;
57+
58+
@Override
59+
public Task createTask(String name) {
60+
final DefaultTask task = new DefaultTask(threadService, eventService);
61+
task.setName(name);
62+
return task;
63+
}
64+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2017 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
7+
* Institute of Molecular Cell Biology and Genetics, University of
8+
* Konstanz, and KNIME GmbH.
9+
* %%
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions are met:
12+
*
13+
* 1. Redistributions of source code must retain the above copyright notice,
14+
* this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright notice,
16+
* this list of conditions and the following disclaimer in the documentation
17+
* and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
23+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
* #L%
31+
*/
32+
33+
package org.scijava.task;
34+
35+
import java.util.concurrent.ExecutionException;
36+
37+
import org.scijava.Cancelable;
38+
import org.scijava.Named;
39+
40+
/**
41+
* A self-aware job which reports its status and progress as it runs.
42+
*
43+
* @author Curtis Rueden
44+
*/
45+
public interface Task extends Cancelable, Named {
46+
47+
/**
48+
* Starts running the task.
49+
*
50+
* @throws IllegalStateException if the task was already started.
51+
*/
52+
void run(Runnable r);
53+
54+
/**
55+
* Waits for the task to complete.
56+
*
57+
* @throws IllegalStateException if {@link #run} has not been called yet.
58+
* @throws InterruptedException if the task is interrupted.
59+
* @throws ExecutionException if the task throws an exception while running.
60+
*/
61+
void waitFor() throws InterruptedException, ExecutionException;
62+
63+
/** Checks whether the task has completed. */
64+
boolean isDone();
65+
66+
/** Gets a status message describing what the task is currently doing. */
67+
String getStatusMessage();
68+
69+
/**
70+
* Gets the step the task is currently performing.
71+
*
72+
* @return A value between 0 and {@link #getProgressMaximum()} inclusive.
73+
* @see #getProgressMaximum()
74+
*/
75+
long getProgressValue();
76+
77+
/**
78+
* Gets the number of steps the task performs in total.
79+
*
80+
* @return Total number of steps the task will perform, or 0 if unknown.
81+
* @see #getProgressValue()
82+
*/
83+
long getProgressMaximum();
84+
85+
/**
86+
* Sets the status message. Called by task implementors.
87+
*
88+
* @param status The message to set.
89+
* @see #getStatusMessage()
90+
*/
91+
void setStatusMessage(String status);
92+
93+
/**
94+
* Sets the current step. Called by task implementors.
95+
*
96+
* @param step The step vaule to set.
97+
* @see #getProgressValue()
98+
*/
99+
void setProgressValue(long step);
100+
101+
/**
102+
* Sets the total number of steps. Called by task implementors.
103+
*
104+
* @param max The step count to set.
105+
* @see #getProgressMaximum()
106+
*/
107+
void setProgressMaximum(long max);
108+
}

0 commit comments

Comments
 (0)