KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > model > ViewJob


1 package hudson.model;
2
3 import org.kohsuke.stapler.StaplerRequest;
4 import org.kohsuke.stapler.StaplerResponse;
5
6 import javax.servlet.ServletException JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.util.LinkedHashSet JavaDoc;
9 import java.util.SortedMap JavaDoc;
10
11 /**
12  * {@link Job} that monitors activities that happen outside Hudson,
13  * which requires occasional batch reload activity to obtain the up-to-date information.
14  *
15  * <p>
16  * This can be used as a base class to derive custom {@link Job} type.
17  *
18  * @author Kohsuke Kawaguchi
19  */

20 public abstract class ViewJob<JobT extends ViewJob<JobT,RunT>, RunT extends Run<JobT,RunT>>
21     extends Job<JobT,RunT> {
22
23     /**
24      * We occasionally update the list of {@link Run}s from a file system.
25      * The next scheduled update time.
26      */

27     private transient long nextUpdate = 0;
28
29     /**
30      * All {@link Run}s. Copy-on-write semantics.
31      */

32     protected transient /*almost final*/ RunMap<RunT> runs = new RunMap<RunT>();
33
34     private transient boolean notLoaded = true;
35
36     /**
37      * If the reloading of runs are in progress (in another thread,
38      * set to true.)
39      */

40     private transient volatile boolean reloadingInProgress;
41
42     /**
43      * {@link ExternalJob}s that need to be reloaded.
44      *
45      * This is a set, so no {@link ExternalJob}s are scheduled twice, yet
46      * it's order is predictable, avoiding starvation.
47      */

48     private static final LinkedHashSet JavaDoc<ViewJob> reloadQueue = new LinkedHashSet JavaDoc<ViewJob>();
49     /*package*/ static final Thread JavaDoc reloadThread = new ReloadThread();
50     static {
51         reloadThread.start();
52     }
53
54     protected ViewJob(Hudson parent, String JavaDoc name) {
55         super(parent,name);
56     }
57
58     public boolean isBuildable() {
59         return false;
60     }
61
62
63     public void onLoad(ItemGroup<? extends Item> parent, String JavaDoc name) throws IOException JavaDoc {
64         super.onLoad(parent, name);
65         notLoaded = true;
66     }
67
68     protected SortedMap JavaDoc<Integer JavaDoc,RunT> _getRuns() {
69         if(notLoaded || runs==null) {
70             // if none is loaded yet, do so immediately.
71
synchronized(this) {
72                 if(runs==null)
73                     runs = new RunMap<RunT>();
74                 if(notLoaded) {
75                     notLoaded = false;
76                     _reload();
77                 }
78             }
79         }
80         if(nextUpdate<System.currentTimeMillis()) {
81             if(!reloadingInProgress) {
82                 // schedule a new reloading operation.
83
// we don't want to block the current thread,
84
// so reloading is done asynchronously.
85
reloadingInProgress = true;
86                 synchronized(reloadQueue) {
87                     reloadQueue.add(this);
88                     reloadQueue.notify();
89                 }
90             }
91         }
92         return runs;
93     }
94
95     public void removeRun(RunT run) {
96         // reload the info next time
97
nextUpdate = 0;
98     }
99
100     private void _reload() {
101         try {
102             reload();
103         } finally {
104             reloadingInProgress = false;
105             nextUpdate = System.currentTimeMillis()+1000*60;
106         }
107     }
108
109     /**
110      * Reloads the list of {@link Run}s. This operation can take a long time.
111      *
112      * <p>
113      * The loaded {@link Run}s should be set to {@link #runs}.
114      */

115     protected abstract void reload();
116
117     public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException JavaDoc, ServletException JavaDoc {
118         super.doConfigSubmit(req,rsp);
119         // make sure to reload to reflect this config change.
120
nextUpdate = 0;
121     }
122
123
124     /**
125      * Thread that reloads the {@link Run}s.
126      */

127     private static final class ReloadThread extends Thread JavaDoc {
128         private ViewJob getNext() throws InterruptedException JavaDoc {
129             synchronized(reloadQueue) {
130                 while(reloadQueue.isEmpty())
131                     reloadQueue.wait();
132                 ViewJob job = reloadQueue.iterator().next();
133                 reloadQueue.remove(job);
134                 return job;
135             }
136         }
137
138         public void run() {
139             while (true) {
140                 try {
141                     getNext()._reload();
142                 } catch (InterruptedException JavaDoc e) {
143                     // treat this as a death signal
144
return;
145                 } catch (Throwable JavaDoc t) {
146                     // otherwise ignore any error
147
t.printStackTrace();
148                 }
149             }
150         }
151     }
152
153     // private static final Logger logger = Logger.getLogger(ViewJob.class.getName());
154
}
155
Popular Tags