All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xitrum.Cache.scala Maven / Gradle / Ivy

The newest version!
package xitrum

import scala.util.control.NonFatal

/**
 * This is the interface for cache implementations of Xitrum. All methods do not
 * take callbacks, because cache should be fast. The point of using cache is
 * to become faster. There's no point in using a slow cache.
 */
abstract class Cache {
  /**
   * Cache engine like Hazelcast may take serveral seconds to start, this method
   * is called at Xitrum server start to force the cache to start, instead of
   * letting it start lazily at first cache access.
   */
  def start(): Unit

  def stop(): Unit

  def isDefinedAt(key: Any): Boolean

  def get(key: Any): Option[Any]

  def put(key: Any, value: Any): Unit

  def putIfAbsent(key: Any, value: Any): Unit

  def putSecond(key: Any, value: Any, seconds: Int): Unit

  def putSecondIfAbsent(key: Any, value: Any, seconds: Int): Unit

  def remove(key: Any): Unit

  def clear(): Unit

  //----------------------------------------------------------------------------

  def getAs[T](key: Any): Option[T] = get(key).asInstanceOf[Option[T]]

  def putMinute(key: Any, value: Any, minutes: Int): Unit = { putSecond(key, value, minutes * 60) }
  def putHour  (key: Any, value: Any, hours:   Int): Unit = { putSecond(key, value, hours   * 60 * 60) }
  def putDay   (key: Any, value: Any, days:    Int): Unit = { putSecond(key, value, days    * 60 * 60 * 24) }

  def putMinuteIfAbsent(key: Any, value: Any, minutes: Int): Unit = { putSecondIfAbsent(key, value, minutes * 60) }
  def putHourIfAbsent  (key: Any, value: Any, hours:   Int): Unit = { putSecondIfAbsent(key, value, hours   * 60 * 60) }
  def putDayIfAbsent   (key: Any, value: Any, days:    Int): Unit = { putSecondIfAbsent(key, value, days    * 60 * 60 * 24) }
}

object Cache {
  /**
   * Cache config in xitrum.conf can be in 2 forms:
   *
   * {{{
   * cache = my.Cache
   * }}}
   *
   * Or if the cache needs additional options:
   *
   * {{{
   * cache {
   *   "my.Cache" {
   *     option1 = value1
   *     option2 = value2
   *   }
   *
   *   # - Commented out:   Cache is automatically disabled in development mode,
   *   #                    and enabled in production mode.
   *   # - enabled = true:  Force cache to be enabled even in development mode.
   *   # - enabled = false: Force cache to be disabled even in production mode.
   *   enabled = true
   * }
   * }}}
   */
  def loadFromConfig(): Cache = {
    try {
      val enabled =
        if (Config.xitrum.config.hasPath("cache.enabled"))
          Config.xitrum.config.getBoolean("cache.enabled")
        else
          Config.productionMode

      val cache =
        if (enabled) {
          // DualConfig works with config with only one entry
          val withoutEnabled = Config.xitrum.config.withoutPath("cache.enabled")
          DualConfig.getClassInstance[Cache](withoutEnabled, "cache")
        } else {
          dummy()
        }

      cache.start()
      cache
    } catch {
      case NonFatal(e) =>
        Config.exitOnStartupError("Could not load cache engine, please check config/xitrum.conf", e)
        throw e
    }
  }

  private def dummy(): Cache = new Cache {
    def start(): Unit = {}

    def stop(): Unit = {}

    def isDefinedAt(key: Any) = false

    def get(key: Any): Option[Any] = None

    def put(key: Any, value: Any): Unit = {}

    def putIfAbsent(key: Any, value: Any): Unit = {}

    def putSecond(key: Any, value: Any, seconds: Int): Unit = {}

    def putSecondIfAbsent(key: Any, value: Any, seconds: Int): Unit = {}

    def remove(key: Any): Unit = {}

    def clear(): Unit = {}
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy