<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -33,6 +33,12 @@ max_memory_size = 134217728
 # then if the journal grows larger than 160MB, it will be forcably re-created.
 max_journal_overflow = 10
 
+# if you would like a timer to periodically sweep through queues and clean
+# up expired items (when they are at the head of a queue), set the timer's
+# frequency here. 0 (the default) turns it off. this is only useful for queues
+# that are rarely (or never) polled, but may contain short-lived items.
+#expiration_timer_frequency_seconds = 1
+
 # per-queue config
 queues {
   weather_updates {
@@ -40,7 +46,7 @@ queues {
     # seconds (1,800,000 milliseconds, or 30 mins). if a client uses a
     # shorter expiry, that's honored instead.
     max_age = 1800000
-    
+
     # refuse SET operations when the queue would exceed this many items.
     max_items = 1500000
   }</diff>
      <filename>config/production.conf</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
   &lt;info
     organisation=&quot;net.lag&quot;
     module=&quot;kestrel&quot;
-    revision=&quot;1.2&quot;
+    revision=&quot;1.2.1&quot;
     e:testclass=&quot;net.lag.TestRunner&quot;
     e:jarclassname=&quot;net.lag.kestrel.Kestrel&quot;
     e:buildpackage=&quot;net.lag.kestrel&quot;</diff>
      <filename>ivy/ivy.xml</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,7 @@ package net.lag.kestrel
 
 import java.net.InetSocketAddress
 import java.util.concurrent.{CountDownLatch, Executors, ExecutorService, TimeUnit}
+import java.util.{Timer, TimerTask}
 import scala.actors.{Actor, Scheduler}
 import scala.actors.Actor._
 import scala.collection.mutable
@@ -108,6 +109,21 @@ object Kestrel {
     // expose config thru JMX.
     config.registerWithJmx(&quot;net.lag.kestrel&quot;)
 
+    // optionally, start a periodic timer to clean out expired items.
+    val expirationTimerFrequency = config.getInt(&quot;expiration_timer_frequency_seconds&quot;, 0)
+    if (expirationTimerFrequency &gt; 0) {
+      val timer = new Timer(&quot;Expiration timer&quot;, true)
+      val expirationTask = new TimerTask {
+        def run() {
+          val expired = Kestrel.queues.flushAllExpired()
+          if (expired &gt; 0) {
+            log.info(&quot;Expired %d item(s) from queues automatically.&quot;, expired)
+          }
+        }
+      }
+      timer.schedule(expirationTask, expirationTimerFrequency * 1000, expirationTimerFrequency * 1000)
+    }
+
     log.info(&quot;Kestrel started.&quot;)
 
     // make sure there's always one actor running so scala 2.7.2 doesn't kill off the actors library.</diff>
      <filename>src/main/scala/net/lag/kestrel/Kestrel.scala</filename>
    </modified>
    <modified>
      <diff>@@ -137,7 +137,7 @@ class KestrelHandler(val session: IoSession, val config: Config) extends Actor {
       case &quot;FLUSH_EXPIRED&quot; =&gt;
         flushExpired(request.line(1))
       case &quot;FLUSH_ALL_EXPIRED&quot; =&gt;
-        val flushed = Kestrel.queues.queueNames.foldLeft(0) { (sum, qName) =&gt; sum + Kestrel.queues.flushExpired(qName) }
+        val flushed = Kestrel.queues.flushAllExpired()
         writeResponse(&quot;%d\r\n&quot;.format(flushed))
       case &quot;VERSION&quot; =&gt;
         version()</diff>
      <filename>src/main/scala/net/lag/kestrel/KestrelHandler.scala</filename>
    </modified>
    <modified>
      <diff>@@ -200,6 +200,10 @@ class QueueCollection(queueFolder: String, private var queueConfigs: ConfigMap)
     }
   }
 
+  def flushAllExpired(): Int = synchronized {
+    queueNames.foldLeft(0) { (sum, qName) =&gt; sum + flushExpired(qName) }
+  }
+
   def stats(key: String): Array[(String, String)] = queue(key) match {
     case None =&gt; Array[(String, String)]()
     case Some(q) =&gt;</diff>
      <filename>src/main/scala/net/lag/kestrel/QueueCollection.scala</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0d187c741bbbf60d3cc84fba2f5b497ae8733350</id>
    </parent>
  </parents>
  <author>
    <name>Robey Pointer</name>
    <email>robey@twitter.com</email>
  </author>
  <url>http://github.com/robey/kestrel/commit/310d5fb7b0f92ea6c24798978a1182fdbdd674c1</url>
  <id>310d5fb7b0f92ea6c24798978a1182fdbdd674c1</id>
  <committed-date>2009-10-09T18:45:12-07:00</committed-date>
  <authored-date>2009-10-09T18:45:12-07:00</authored-date>
  <message>add a config option to periodically sweep through queues and clear out expired items.</message>
  <tree>2d89c42b5f58a7ba7178ab4763e74c4a64e05aa1</tree>
  <committer>
    <name>Robey Pointer</name>
    <email>robey@twitter.com</email>
  </committer>
</commit>
