3
3
import java .io .File ;
4
4
import java .text .MessageFormat ;
5
5
import java .util .Arrays ;
6
+ import java .util .HashMap ;
7
+ import java .util .HashSet ;
6
8
import java .util .List ;
7
9
import java .util .Map ;
8
10
import java .util .Set ;
15
17
16
18
import net .greghaines .jesque .Job ;
17
19
import net .greghaines .jesque .client .Client ;
20
+ import net .greghaines .jesque .meta .QueueInfo ;
21
+ import net .greghaines .jesque .meta .dao .QueueInfoDAO ;
18
22
import net .greghaines .jesque .worker .Worker ;
19
23
import net .greghaines .jesque .worker .WorkerEvent ;
20
24
import net .greghaines .jesque .worker .WorkerListener ;
44
48
import edu .unc .lib .dl .util .DepositStatusFactory ;
45
49
import edu .unc .lib .dl .util .JobStatusFactory ;
46
50
import edu .unc .lib .dl .util .PackagingType ;
51
+ import edu .unc .lib .dl .util .RedisWorkerConstants ;
47
52
import edu .unc .lib .dl .util .RedisWorkerConstants .DepositAction ;
48
53
import edu .unc .lib .dl .util .RedisWorkerConstants .DepositField ;
49
54
import edu .unc .lib .dl .util .RedisWorkerConstants .DepositState ;
@@ -72,6 +77,9 @@ public class DepositSupervisor implements WorkerListener {
72
77
@ Autowired
73
78
private WorkerPool cdrMetsDepositWorkerPool ;
74
79
80
+ @ Autowired
81
+ private QueueInfoDAO queueDAO ;
82
+
75
83
@ Autowired
76
84
private DepositEmailHandler depositEmailHandler ;
77
85
@@ -137,6 +145,9 @@ public void init() {
137
145
}
138
146
139
147
public void start () {
148
+ // Repopulate the queue
149
+ requeueAll ();
150
+
140
151
LOG .info ("Starting deposit checks and worker pool" );
141
152
if (timer != null )
142
153
return ;
@@ -225,15 +236,37 @@ public void run() {
225
236
LOG .info ("Starting deposit workers" );
226
237
cdrMetsDepositWorkerPool .run ();
227
238
}
228
-
229
- // Repopulate the queue
230
- requeueAll ();
239
+ }
240
+
241
+ private Map <String , Set <String >> getQueuedDepositsWithJobs () {
242
+ Map <String , Set <String >> depositMap = new HashMap <>();
243
+ addQueuedDeposits (RedisWorkerConstants .DEPOSIT_PREPARE_QUEUE , depositMap );
244
+ addQueuedDeposits (RedisWorkerConstants .DEPOSIT_DELAYED_QUEUE , depositMap );
245
+ addQueuedDeposits (RedisWorkerConstants .DEPOSIT_CDRMETS_QUEUE , depositMap );
246
+ return depositMap ;
247
+ }
248
+
249
+ private void addQueuedDeposits (String queueName , Map <String , Set <String >> depositMap ) {
250
+ QueueInfo info = queueDAO .getQueueInfo (queueName , 0 , 0 );
251
+
252
+ for (Job job : info .getJobs ()) {
253
+ String depositId = (String ) job .getArgs ()[1 ];
254
+
255
+ Set <String > jobs = depositMap .get (depositId );
256
+ if (jobs == null ) {
257
+ jobs = new HashSet <>();
258
+ depositMap .put (depositId , jobs );
259
+ }
260
+ jobs .add (job .getClassName ());
261
+ }
231
262
}
232
263
233
264
/**
234
265
* Add jobs previously running or queued back to the queue
235
266
*/
236
267
private void requeueAll () {
268
+
269
+ Map <String , Set <String >> depositSet = getQueuedDepositsWithJobs ();
237
270
Set <Map <String , String >> depositStatuses = depositStatusFactory .getAll ();
238
271
239
272
LOG .info ("Repopulating the deposit queue, {} items in backlog" , depositStatuses .size ());
@@ -246,7 +279,16 @@ private void requeueAll() {
246
279
// Job may have been locked to a particular supervisor depend on when it was interrupted
247
280
depositStatusFactory .removeSupervisorLock (uuid );
248
281
// Inform supervisor to resume this deposit from where it left off
249
- depositStatusFactory .setActionRequest (uuid , DepositAction .resume );
282
+ if (depositSet .containsKey (uuid )) {
283
+ // If the job is queued but the job it is waiting on is a cleanup, then it is finished
284
+ if (depositSet .get (uuid ).contains (CleanupDepositJob .class .getName ())) {
285
+ depositStatusFactory .setState (uuid , DepositState .finished );
286
+ } else {
287
+ LOG .debug ("Skipping resumption of deposit {} because it already is in the queue" , uuid );
288
+ }
289
+ } else {
290
+ depositStatusFactory .setActionRequest (uuid , DepositAction .resume );
291
+ }
250
292
}
251
293
}
252
294
@@ -257,7 +299,21 @@ private void requeueAll() {
257
299
258
300
depositStatusFactory .removeSupervisorLock (uuid );
259
301
// Re-register as a new deposit
260
- depositStatusFactory .setActionRequest (uuid , DepositAction .register );
302
+ if (depositSet .containsKey (uuid )) {
303
+ if (depositSet .get (uuid ).contains (CleanupDepositJob .class .getName ())) {
304
+ depositStatusFactory .setState (uuid , DepositState .finished );
305
+ } else {
306
+ LOG .debug ("Skipping resumption of queued deposit {} because it already is in the queue" , uuid );
307
+ }
308
+ } else {
309
+ List <String > successfulJobs = jobStatusFactory .getSuccessfulJobNames (uuid );
310
+ if (successfulJobs != null && successfulJobs .size () > 0 ) {
311
+ // Queued but had already performed some jobs, so this is a resumption rather than new deposit
312
+ depositStatusFactory .setActionRequest (uuid , DepositAction .resume );
313
+ } else {
314
+ depositStatusFactory .setActionRequest (uuid , DepositAction .register );
315
+ }
316
+ }
261
317
}
262
318
}
263
319
}
@@ -607,9 +663,20 @@ private void resumeDeposit(String uuid, Map<String, String> status, long delay)
607
663
// Clear out the previous failed job if there was one
608
664
jobStatusFactory .clearStale (uuid );
609
665
depositStatusFactory .deleteField (uuid , DepositField .errorMessage );
666
+
667
+ // since we already checked for queued jobs at startup, only check when resuming from a paused state
668
+ boolean enqueueNext = true ;
669
+ if (DepositState .paused .name ().equals (status .get (DepositField .state .name ()))) {
670
+ Map <String , Set <String >> depositSet = getQueuedDepositsWithJobs ();
671
+ enqueueNext = !depositSet .containsKey (uuid );
672
+ }
610
673
611
- List <String > successfulJobs = jobStatusFactory .getSuccessfulJobNames (uuid );
612
- queueNextJob (null , uuid , status , successfulJobs , delay );
674
+ if (enqueueNext ) {
675
+ List <String > successfulJobs = jobStatusFactory .getSuccessfulJobNames (uuid );
676
+ queueNextJob (null , uuid , status , successfulJobs , delay );
677
+ } else {
678
+ LOG .info ("Resuming {} from paused state. A job is already queued so no new jobs will be enqueued" , uuid );
679
+ }
613
680
614
681
depositStatusFactory .setState (uuid , DepositState .queued );
615
682
} catch (DepositFailedException e ) {
0 commit comments