1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.workspace.impl;
23
24 import org.opencastproject.workspace.api.Workspace;
25
26 import org.quartz.Job;
27 import org.quartz.JobDetail;
28 import org.quartz.JobExecutionContext;
29 import org.quartz.JobExecutionException;
30 import org.quartz.Trigger;
31 import org.quartz.TriggerUtils;
32 import org.quartz.impl.StdSchedulerFactory;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.util.Date;
37
38
39 public class WorkspaceCleaner {
40
41
42 private static final Logger logger = LoggerFactory.getLogger(WorkspaceCleaner.class);
43
44 private static final String JOB_NAME = "mh-workspace-cleaner-job";
45 private static final String JOB_GROUP = "mh-workspace-cleaner-job-group";
46 private static final String TRIGGER_NAME = "mh-workspace-cleaner-trigger";
47 private static final String TRIGGER_GROUP = "mh-workspace-cleaner-trigger-group";
48 private static final String JOB_PARAM_PARENT = "parent";
49
50 private final org.quartz.Scheduler quartz;
51
52 private final Workspace workspace;
53 private final int maxAge;
54 private int schedulerPeriod;
55
56 protected WorkspaceCleaner(Workspace workspace, int schedulerPeriod, int maxAge) {
57 this.workspace = workspace;
58 this.maxAge = maxAge;
59 this.schedulerPeriod = schedulerPeriod;
60
61
62 if (schedulerPeriod <= 0) {
63 logger.debug("No scheduler initialized due to invalid scheduling period ({})", schedulerPeriod);
64 quartz = null;
65 return;
66 }
67
68 try {
69 quartz = new StdSchedulerFactory().getScheduler();
70 quartz.start();
71
72 final JobDetail job = new JobDetail(JOB_NAME, JOB_GROUP, Runner.class);
73 job.setDurability(false);
74 job.setVolatility(true);
75 job.getJobDataMap().put(JOB_PARAM_PARENT, this);
76 quartz.addJob(job, true);
77 } catch (org.quartz.SchedulerException e) {
78 throw new RuntimeException(e);
79 }
80 }
81
82 public Workspace getWorkspace() {
83 return workspace;
84 }
85
86 public int getMaxAge() {
87 return maxAge;
88 }
89
90
91
92
93 public void schedule() {
94 if (quartz == null || schedulerPeriod <= 0) {
95 logger.debug("Cancel scheduling of workspace cleaner due to invalid scheduling period");
96 return;
97 }
98 logger.debug("Scheduling workspace cleaner to run every {} seconds.", schedulerPeriod);
99 try {
100 final Trigger trigger = TriggerUtils.makeSecondlyTrigger(schedulerPeriod);
101 trigger.setStartTime(new Date());
102 trigger.setName(TRIGGER_NAME);
103 trigger.setGroup(TRIGGER_GROUP);
104 trigger.setJobName(JOB_NAME);
105 trigger.setJobGroup(JOB_GROUP);
106 if (quartz.getTriggersOfJob(JOB_NAME, JOB_GROUP).length == 0) {
107 quartz.scheduleJob(trigger);
108 } else {
109 quartz.rescheduleJob(TRIGGER_NAME, TRIGGER_GROUP, trigger);
110 }
111 } catch (Exception e) {
112 logger.error("Error scheduling Quartz job", e);
113 }
114 }
115
116
117 public void shutdown() {
118 try {
119 quartz.shutdown();
120 } catch (org.quartz.SchedulerException ignore) {
121 }
122 }
123
124
125 @Override
126 protected void finalize() throws Throwable {
127 super.finalize();
128 shutdown();
129 }
130
131
132
133
134 public static class Runner implements Job {
135
136 @Override
137 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
138 logger.debug("Start workspace cleaner");
139 try {
140 execute((WorkspaceCleaner) jobExecutionContext.getJobDetail().getJobDataMap().get(JOB_PARAM_PARENT));
141 } catch (Exception e) {
142 throw new JobExecutionException("An error occurred while cleaning workspace", e);
143 }
144 logger.debug("Finished workspace cleaner");
145 }
146
147 private void execute(WorkspaceCleaner workspaceCleaner) {
148 workspaceCleaner.getWorkspace().cleanup(workspaceCleaner.getMaxAge());
149 }
150
151 }
152
153 }