View Javadoc

1   package com.atlassian.scheduler.core.impl;
2   
3   import com.atlassian.scheduler.config.JobId;
4   import com.atlassian.scheduler.core.spi.RunDetailsDao;
5   import com.atlassian.scheduler.status.RunDetails;
6   import com.atlassian.scheduler.status.RunOutcome;
7   import com.google.common.cache.Cache;
8   import com.google.common.cache.CacheBuilder;
9   
10  import static java.util.concurrent.TimeUnit.DAYS;
11  
12  /**
13   * An implementation of the {@code RunDetailsDao} that keeps the scheduler history in memory.
14   * This implementation does not share information across nodes in the cluster or persist it
15   * across restarts, but provides an otherwise functional implementation.  By default, each
16   * job's history is expired 30 days after it is last updated.
17   *
18   * @since v1.0
19   */
20  public class MemoryRunDetailsDao implements RunDetailsDao {
21      private final Cache<JobId, JobRecord> store;
22  
23      public MemoryRunDetailsDao() {
24          this(30);
25      }
26  
27      public MemoryRunDetailsDao(int daysToKeepIdleHistory) {
28          this.store = CacheBuilder.newBuilder()
29                  .expireAfterWrite(daysToKeepIdleHistory, DAYS)
30                  .<JobId, JobRecord>build();
31      }
32  
33  
34      @Override
35      public RunDetails getLastRunForJob(JobId jobId) {
36          final JobRecord record = store.getIfPresent(jobId);
37          return (record != null) ? record.lastRun : null;
38      }
39  
40      @Override
41      public RunDetails getLastSuccessfulRunForJob(JobId jobId) {
42          final JobRecord record = store.getIfPresent(jobId);
43          return (record != null) ? record.lastRun : null;
44      }
45  
46      @Override
47      public void addRunDetails(JobId jobId, RunDetails runDetails) {
48          // Concurrency note: while we won't get concurrent modification exceptions or anything like
49          // that, little effort is made here to keep this information consistent if multiple instances
50          // of the same JobId attempt to record run details at once.  This is not supposed to happen,
51          // anyway, so it should not be important.
52          final JobRecord record;
53          if (runDetails.getRunOutcome() == RunOutcome.SUCCESS) {
54              record = new JobRecord(runDetails, runDetails);
55          } else {
56              record = new JobRecord(runDetails, getLastSuccessfulRunForJob(jobId));
57          }
58          store.put(jobId, record);
59      }
60  
61  
62      static class JobRecord {
63          final RunDetails lastRun;
64          final RunDetails lastSuccessfulRun;
65  
66          JobRecord(RunDetails lastRun, RunDetails lastSuccessfulRun) {
67              this.lastRun = lastRun;
68              this.lastSuccessfulRun = lastSuccessfulRun;
69          }
70      }
71  }