View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.util.store;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.context.MuleContextAware;
11  import org.mule.api.lifecycle.Disposable;
12  import org.mule.api.lifecycle.Initialisable;
13  import org.mule.api.lifecycle.InitialisationException;
14  import org.mule.api.store.ObjectStore;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.util.UUID;
17  import org.mule.util.concurrent.DaemonThreadFactory;
18  
19  import java.io.Serializable;
20  
21  import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
22  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  /**
28   * TODO
29   */
30  public abstract class AbstractMonitoredObjectStore<T extends Serializable> 
31      implements ObjectStore<T>, Runnable, MuleContextAware, Initialisable, Disposable
32  {
33      protected final Log logger = LogFactory.getLog(this.getClass());
34  
35      protected MuleContext context;
36      protected ScheduledThreadPoolExecutor scheduler;
37  
38      /**
39       * the maximum number of entries that this store keeps around. Specify <em>-1</em> if the store 
40       * is supposed to be "unbounded".
41       */
42      protected int maxEntries = 4000;
43  
44      /**
45       * The time-to-live for each message ID, specified in milliseconds, or <em>-1</em> for entries 
46       * that should never expire. <b>DO NOT</b> combine this with an unbounded store!
47       */
48      protected int entryTTL = -1;
49  
50      /**
51       * The interval for periodic bounded size enforcement and entry expiration, specified in 
52       * milliseconds. Arbitrary positive values between 1 millisecond and several hours or days are 
53       * possible, but should be chosen carefully according to the expected message rate to prevent 
54       * out of memory conditions.
55       */
56      protected int expirationInterval = 1000;
57  
58      /**
59       * A name for this store, can be used for logging and identification purposes.
60       */
61      protected String name = null;
62  
63      public void initialise() throws InitialisationException
64      {
65          if (name == null)
66          {
67              name = UUID.getUUID();
68          }
69  
70          if (expirationInterval <= 0)
71          {
72              throw new IllegalArgumentException(CoreMessages.propertyHasInvalidValue("expirationInterval",
73                      new Integer(expirationInterval)).toString());
74          }
75  
76          if (scheduler == null)
77          {
78              this.scheduler = new ScheduledThreadPoolExecutor(1);
79              scheduler.setThreadFactory(new DaemonThreadFactory(name + "-Monitor", this.getClass().getClassLoader()));
80              scheduler.scheduleWithFixedDelay(this, 0, expirationInterval, TimeUnit.MILLISECONDS);
81          }
82      }
83  
84      public final void run()
85      {
86          expire();
87      }
88  
89      public void dispose()
90      {
91          if (scheduler != null)
92          {
93              scheduler.shutdown();
94          }
95      }
96  
97      public void setEntryTTL(int entryTTL)
98      {
99          this.entryTTL = entryTTL;
100     }
101 
102     public void setExpirationInterval(int expirationInterval)
103     {
104         this.expirationInterval = expirationInterval;
105     }
106 
107     public void setMaxEntries(int maxEntries)
108     {
109         this.maxEntries = maxEntries;
110     }
111 
112     public void setScheduler(ScheduledThreadPoolExecutor scheduler)
113     {
114         this.scheduler = scheduler;
115     }
116 
117     public void setName(String id)
118     {
119         this.name = id;
120     }
121 
122     public void setMuleContext(MuleContext context)
123     {
124         this.context = context;
125     }
126 
127     public int getEntryTTL()
128     {
129         return entryTTL;
130     }
131 
132     public int getExpirationInterval()
133     {
134         return expirationInterval;
135     }
136 
137     public int getMaxEntries()
138     {
139         return maxEntries;
140     }
141 
142     public String getName()
143     {
144         return name;
145     }
146 
147     public ScheduledThreadPoolExecutor getScheduler()
148     {
149         return scheduler;
150     }
151 
152     protected abstract void expire();
153 }