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

com.github.mumoshu.play2.memcached.MemcachedCacheApi.scala Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
package com.github.mumoshu.play2.memcached

import java.util.concurrent.TimeUnit

import net.spy.memcached.transcoders.Transcoder
import play.api.cache.CacheApi
import play.api.{Logger, Configuration, Environment}
import play.api.inject.{ BindingKey, Injector, ApplicationLifecycle, Module }

import javax.inject.{Inject, Singleton}

import scala.concurrent.duration.Duration

import net.spy.memcached.MemcachedClient

import scala.reflect.ClassTag

@Singleton
class MemcachedCacheApi @Inject() (val namespace: String, client: MemcachedClient, configuration: Configuration) extends CacheApi {
  lazy val logger = Logger("memcached.plugin")
  lazy val tc = new CustomSerializing().asInstanceOf[Transcoder[Any]]
  lazy val timeout: Int = configuration.getInt("memcached.timeout").getOrElse(1)

  lazy val timeunit: TimeUnit = {
    configuration.getString("memcached.timeunit").getOrElse("seconds") match {
      case "seconds" => TimeUnit.SECONDS
      case "milliseconds" => TimeUnit.MILLISECONDS
      case "microseconds" => TimeUnit.MICROSECONDS
      case "nanoseconds" => TimeUnit.NANOSECONDS
      case _ => TimeUnit.SECONDS
    }
  }
  def get[T: ClassTag](key: String): Option[T] =
    if (key.isEmpty) {
      None
    } else {
      val ct = implicitly[ClassTag[T]]

      logger.debug("Getting the cached for key " + namespace + key)
      val future = client.asyncGet(namespace + key, tc)
      try {
        val any = future.get(timeout, timeunit)
        if (any != null) {
          logger.debug("any is " + any.getClass)
        }

        Option(
          any match {
            case x if ct.runtimeClass.isInstance(x) => x.asInstanceOf[T]
            case x if ct == ClassTag.Nothing => x.asInstanceOf[T]
            case x => x.asInstanceOf[T]
          }
        )
      } catch {
        case e: Throwable =>
          logger.error("An error has occured while getting the value from memcached. ct=" + ct , e)
          future.cancel(false)
          None
      }
    }

  def getOrElse[A: ClassTag](key: String, expiration: Duration = Duration.Inf)(orElse: => A): A = {
    get[A](key).getOrElse {
      val value = orElse
      set(key, value, expiration)
      value
    }
  }

  def set(key: String, value: Any, expiration: Duration = Duration.Inf) {
    if (!key.isEmpty) {
      val exp = if (expiration.isFinite()) expiration.toSeconds.toInt else 0
      client.set(namespace + key, exp, value, tc)
    }
  }

  def remove(key: String) {
    if (!key.isEmpty) {
      client.delete(namespace + key)
    }
  }
}

object MemcachedCacheApi {
  object ValFromJavaObject {
    def unapply(x: AnyRef): Option[AnyVal] = x match {
      case x: java.lang.Byte => Some(x.byteValue())
      case x: java.lang.Short => Some(x.shortValue())
      case x: java.lang.Integer => Some(x.intValue())
      case x: java.lang.Long => Some(x.longValue())
      case x: java.lang.Float => Some(x.floatValue())
      case x: java.lang.Double => Some(x.doubleValue())
      case x: java.lang.Character => Some(x.charValue())
      case x: java.lang.Boolean => Some(x.booleanValue())
      case _ => None
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy