GithubHelp home page GithubHelp logo

memcontinuationed's Introduction

Memcontinuationed

Build Status

Memcontinuationed is an asynchronous memcached client for Scala. Memcontinuationed is the fastest memcached client on JVM, much faster than spymemcached or Whalin's client.

Why is Memcontinuationed so fast?

Reason 1. Better threading model

Memcontinuationed never blocks any threads. On the other hand, spymemcached does not block the IO thread but it does block the user's thread. All Memcontinuationed API are @suspendable, which mean these methods can be invoked by a thread, and return to another thread.

Reason 2. Optimization for huge number of IOPS

Memcontinuationed can merge multiply get or gets requests into one request. On the other hand, spymemcached sends all requests immediately, never waiting for previous response. The spymemcached way consumes more CPU and more TCP overheads than Memcontinuationed. Even worse, the spymemcached way is not compatible with some memcached server.

Note: Because Memcontinuationed queues requests until all the previous response have been received, you may need to create a connection pool of com.dongxiguo.memcontinuationed.Memcontinuationed to maximize the IOPS.

A sample to use Memcontinuationed

import com.dongxiguo.memcontinuationed.Memcontinuationed
import com.dongxiguo.memcontinuationed.StorageAccessor
import java.io._
import java.net._
import java.nio.channels.AsynchronousChannelGroup
import java.util.concurrent.Executors
import scala.util.continuations.reset
import scala.util.control.Exception.Catcher

object Sample {

  def main(args: Array[String]) {
    val threadPool = Executors.newCachedThreadPool()
    val channelGroup = AsynchronousChannelGroup.withThreadPool(threadPool)

    // The locator determines where the memcached server is.
    // You may want to implement ketama hashing here.
    def locator(accessor: StorageAccessor[_]) = {
      new InetSocketAddress("localhost", 1978)
    }

    val memcontinuationed = new Memcontinuationed(channelGroup, locator)

    // The error handler
    implicit def catcher:Catcher[Unit] = {
      case e: Exception =>
        scala.Console.err.print(e)
        sys.exit(-1)
    }

    reset {
      memcontinuationed.set(MyKey("hello"), "Hello, World!")
      val result = memcontinuationed.require(MyKey("hello"))
      assert(result == "Hello, World!")
      println(result)
      sys.exit()
    }
  }
}

/**
 * `MyKey` specifies how to serialize the data of a key/value pair.
 */
case class MyKey(override val key: String) extends StorageAccessor[String] {

  override def encode(output: OutputStream, data: String, flags: Int) {
    output.write(data.getBytes("UTF-8"))
  }

  override def decode(input: InputStream, flags: Int): String = {
    val result = new Array[Byte](input.available)
    input.read(result)
    new String(result, "UTF-8")
  }
}

There is something you need to know:

  • get, set, and most of other methods in Memcontinuationed are @suspendable. You must invoke them in reset or in another @suspendable function you defined.
  • get, set, and most of other methods in Memcontinuationed accept an implicit parameter Catcher. You must use Catcher to handle exceptions from @suspendable functions, instead of try/catch.
  • MyKey is the key you passed to server, which is a custom StorageAccessor. You should implement your own StorageAccessor for each type of data. If your value's format is Protocol Buffers, you can use com.dongxiguo.memcontinuationed.ProtobufAccessor as your custom key's super class.

Build configuration

Add these lines to your build.sbt if you use Sbt:

libraryDependencies += "com.dongxiguo" %% "memcontinuationed" % "0.3.2"
    
libraryDependencies <++= scalaBinaryVersion { bv =>
  bv match {
    case "2.10" => {
      Seq()
    }
    case _ => {
      Seq("org.scala-lang.plugins" % s"scala-continuations-library_$bv" % "1.0.1")
    }
  }
}

libraryDependencies <+= scalaVersion { sv =>
  if (sv.startsWith("2.10.")) {
    compilerPlugin("org.scala-lang.plugins" % "continuations" % sv)
  } else {
    compilerPlugin("org.scala-lang.plugins" % s"scala-continuations-plugin_$sv" % "1.0.1")
  }
}

scalacOptions += "-P:continuations:enable"

Requirement

Memcontinuationed requires Scala 2.10.x or 2.11.x, and JRE 7.

Links

memcontinuationed's People

Contributors

atry avatar zaneli avatar missingfaktor avatar

Stargazers

Second Datke avatar foresightyj avatar jackxiang avatar Salvador Guzman avatar Angel Ortega (he/they) avatar Chen Yinghua avatar Franck Rasolo avatar  avatar  avatar Angus H. avatar  avatar Chao Chu avatar Chris Wood avatar Sky Schulz avatar Yadid Ayzenberg avatar James Ward avatar Anton Ivanov avatar Rogério da Silva Yokomizo avatar Michał Kowol avatar He-Pin(kerr) avatar Ernesto Cambuston avatar Rodrigo Oliveira avatar Herbert Fischer avatar Matthew Tovbin avatar  avatar Paweł Cesar Sanjuan Szklarz avatar  avatar Mag A avatar almoehi avatar Jason Webb avatar gangge avatar Aaron S. Hawley avatar Piyush Purang avatar Arakaki avatar Tomato avatar  avatar  avatar Sean Gao avatar andrew salvadore avatar Raghava Nellaturu avatar Ludovic Claude avatar Yamashita, Yuu avatar kenji yoshida avatar  avatar Donnchadh Ó Donnabháin avatar Miles Sabin avatar Steve Sowerby avatar Fernando Racca avatar Adam Shannon avatar Doug Tangren avatar

Watchers

yasushi abe avatar Gulen Chongtham avatar kenji yoshida avatar Donnchadh Ó Donnabháin avatar  avatar James Cloos avatar  avatar  avatar

memcontinuationed's Issues

Build Instructions

I think the dependency part of the README can be simplified to:

libraryDependencies <++= scalaBinaryVersion {
  case "2.10" =>
    Seq()
  case _ =>
    Seq("org.scala-lang.plugins" %% "scala-continuations-library" % "1.0.1")
}

Auth Support

It seems like authenticated MemCache isn't currently supported. It would be great to have this. Thanks!

Problem with subtype

I wish get key in memcache and if not found then add data in memcache and return data.

def getOrData[T](key: String, duration: Int = 10)(data: => T): Future[T] = {
reset {
memcached.get(Key(key)).get(Key(key)) match {
case None => {
memcached.add[Array[Byte]](Key%28key%29, Serialize.serialize%28data%29, Exptime.fromNowOn%28duration%29)
Future(data)
}
case Some(result) => {
Future(Serialize.unserializeT)
}
case _ =>
}
}
}

I don't have any problem with serialize and un unserialize method, this method take an Array of Byte and return T object.

But I have errors with my implementation :
scala.util.continuations.cpsParam[Unit,Unit] is not a subtype of scala.util.continuations.cpsParam[?,scala.concurrent.Future[T]]
[error] case None => {

illegal answer type modification: scala.util.continuations.cpsParam[Unit,Unit] andThen scala.util.continuations.cpsParam[?,scala.concurrent.Future[T]]
[error] memcached.get(Key(key)).get(Key(key)) match {

Value size limited to 32768

Value sizes are limited in the AsciiProtocol are limited to 32768

private final val MaxValueSize = 32768

However, by default values can be up to 1MB and with tuning values can be even larger. When the user attempts to write a larger value it works fine, but when they read that larger value they simply get a mysterious error such as:

SEVERE: com.dongxiguo.memcontinuationed.ProtocolException: Bad line VALUE raw:6TSa2041BHDwSWYtJA0+dmZvRNg= 0 168508

Implement Binary protocol

The binary protocol is proported to be faster, but memcontinuationed currently only uses the ASCII protocol.

Unresolved dependencies

I'm trying to clone memcontinuationed and then run it in sbt. I get the following unresolved dependencies that prevent it from running:
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.dongxiguo.zero-log#context_2.9.2;0.3.3: not found
[warn] :: com.dongxiguo#zero-log_2.9.2;0.3.3: not found
[warn] :: com.dongxiguo#commons-continuations_2.9.2;0.2.1: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
error sbt.ResolveException: unresolved dependency: com.dongxiguo.zero-log#context_2.9.2;0.3.3: not found
[error] unresolved dependency: com.dongxiguo#zero-log_2.9.2;0.3.3: not found
[error] unresolved dependency: com.dongxiguo#commons-continuations_2.9.2;0.2.1: not found

Exception in continuation

Hi,
If i send much conccurent requests to my application, I have an exception :
2013-08-08 17-40-19 C:\Users\atry\Documents\lalala\game\race-for-the-woolen\commons-continuations\src\main\scala\com\dongxiguo\commons\continuations\io\AsynchronousInputStream.scala:45 completed
SEVERE: Exception is thrown in continuation when handling a completed asynchronous reading. java.nio.BufferUnderflowException
at java.nio.Buffer.nextGetIndex(Buffer.java:492)
at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:135)

I use linux system and not windows

NoClassDefFoundError

if I add addCompilerPlugin("org.scala-lang.plugins" % "continuations" % "2.10.2") in my build.scala, I have this error :
java.lang.NoClassDefFoundError: scala/reflect/internal/AnnotationCheckers$AnnotationChecker
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2404)
...
Caused by: java.lang.ClassNotFoundException: scala.reflect.internal.AnnotationCheckers$AnnotationChecker
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
...
error java.lang.reflect.InvocationTargetException

But if I change the version of this plugin to 2.9.2, I don't have this error but I have some errors in my code because not found method require, add get etc (probably because scala 2.9.2)

Application has build with sbt 1.12.4 and scala 2.10.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.