{"id":13481400,"url":"https://github.com/Atry/memcontinuationed","last_synced_at":"2025-03-27T12:30:47.770Z","repository":{"id":6727245,"uuid":"7973129","full_name":"Atry/memcontinuationed","owner":"Atry","description":"Memcached client for Scala","archived":false,"fork":false,"pushed_at":"2017-06-17T04:11:52.000Z","size":52,"stargazers_count":50,"open_issues_count":4,"forks_count":3,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-18T04:15:31.759Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Atry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-02T07:30:38.000Z","updated_at":"2020-10-22T07:42:21.000Z","dependencies_parsed_at":"2022-09-26T21:40:32.543Z","dependency_job_id":null,"html_url":"https://github.com/Atry/memcontinuationed","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atry%2Fmemcontinuationed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atry%2Fmemcontinuationed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atry%2Fmemcontinuationed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atry%2Fmemcontinuationed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Atry","download_url":"https://codeload.github.com/Atry/memcontinuationed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245844811,"owners_count":20681783,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:00:51.498Z","updated_at":"2025-03-27T12:30:47.339Z","avatar_url":"https://github.com/Atry.png","language":"Scala","funding_links":[],"categories":["Database"],"sub_categories":[],"readme":"Memcontinuationed\n=================\n\n\u003cdiv align=\"right\"\u003e\u003ca href=\"https://travis-ci.org/Atry/memcontinuationed\"\u003e\u003cimg alt=\"Build Status\" src=\"https://travis-ci.org/Atry/memcontinuationed.png?branch=master\"/\u003e\u003c/a\u003e\u003c/div\u003e\n\n**Memcontinuationed** is an asynchronous memcached client for [Scala](http://www.scala-lang.org/).\nMemcontinuationed is the fastest memcached client on JVM,\nmuch faster than [spymemcached](https://code.google.com/p/spymemcached/) or\n[Whalin's client](https://github.com/gwhalin/Memcached-Java-Client/wiki).\n\n## Why is Memcontinuationed so fast?\n\n### Reason 1. Better threading model\n\nMemcontinuationed never blocks any threads. On the other hand, spymemcached does not block the IO thread but it does\nblock the user's thread. All Memcontinuationed API are\n[`@suspendable`](http://www.scala-lang.org/api/current/scala/util/continuations/package.html#suspendable=scala.util.continuations.package.cps%5BUnit%5D),\nwhich mean these methods can be invoked by a thread, and return to another thread.\n\n### Reason 2. Optimization for huge number of IOPS\n\nMemcontinuationed can merge multiply `get` or `gets` requests into one request.\nOn the other hand, spymemcached sends all requests immediately, never waiting for previous response.\nThe spymemcached way consumes more CPU and more TCP overheads than Memcontinuationed.\nEven worse, the spymemcached way is not compatible with [some memcached server](http://wiki.open.qq.com/wiki/%E8%AE%BF%E9%97%AECMEM).\n\nNote: Because Memcontinuationed queues requests until all the previous response have been received,\nyou may need to create a connection pool of `com.dongxiguo.memcontinuationed.Memcontinuationed` to maximize the IOPS.\n\n## A sample to use Memcontinuationed\n\n```scala\nimport com.dongxiguo.memcontinuationed.Memcontinuationed\nimport com.dongxiguo.memcontinuationed.StorageAccessor\nimport java.io._\nimport java.net._\nimport java.nio.channels.AsynchronousChannelGroup\nimport java.util.concurrent.Executors\nimport scala.util.continuations.reset\nimport scala.util.control.Exception.Catcher\n\nobject Sample {\n\n  def main(args: Array[String]) {\n    val threadPool = Executors.newCachedThreadPool()\n    val channelGroup = AsynchronousChannelGroup.withThreadPool(threadPool)\n\n    // The locator determines where the memcached server is.\n    // You may want to implement ketama hashing here.\n    def locator(accessor: StorageAccessor[_]) = {\n      new InetSocketAddress(\"localhost\", 1978)\n    }\n\n    val memcontinuationed = new Memcontinuationed(channelGroup, locator)\n\n    // The error handler\n    implicit def catcher:Catcher[Unit] = {\n      case e: Exception =\u003e\n        scala.Console.err.print(e)\n        sys.exit(-1)\n    }\n\n    reset {\n      memcontinuationed.set(MyKey(\"hello\"), \"Hello, World!\")\n      val result = memcontinuationed.require(MyKey(\"hello\"))\n      assert(result == \"Hello, World!\")\n      println(result)\n      sys.exit()\n    }\n  }\n}\n\n/**\n * `MyKey` specifies how to serialize the data of a key/value pair.\n */\ncase class MyKey(override val key: String) extends StorageAccessor[String] {\n\n  override def encode(output: OutputStream, data: String, flags: Int) {\n    output.write(data.getBytes(\"UTF-8\"))\n  }\n\n  override def decode(input: InputStream, flags: Int): String = {\n    val result = new Array[Byte](input.available)\n    input.read(result)\n    new String(result, \"UTF-8\")\n  }\n}\n```\n\nThere is something you need to know:\n\n* `get`, `set`, and most of other methods in `Memcontinuationed` are `@suspendable`. You must invoke them in `reset` or in another `@suspendable` function you defined.\n* `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`.\n* `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](http://code.google.com/p/protobuf/), you can use `com.dongxiguo.memcontinuationed.ProtobufAccessor` as your custom key's super class.\n\n## Build configuration\n\nAdd these lines to your `build.sbt` if you use [Sbt](http://www.scala-sbt.org/):\n\n```scala\nlibraryDependencies += \"com.dongxiguo\" %% \"memcontinuationed\" % \"0.3.2\"\n    \nlibraryDependencies \u003c++= scalaBinaryVersion { bv =\u003e\n  bv match {\n    case \"2.10\" =\u003e {\n      Seq()\n    }\n    case _ =\u003e {\n      Seq(\"org.scala-lang.plugins\" % s\"scala-continuations-library_$bv\" % \"1.0.1\")\n    }\n  }\n}\n\nlibraryDependencies \u003c+= scalaVersion { sv =\u003e\n  if (sv.startsWith(\"2.10.\")) {\n    compilerPlugin(\"org.scala-lang.plugins\" % \"continuations\" % sv)\n  } else {\n    compilerPlugin(\"org.scala-lang.plugins\" % s\"scala-continuations-plugin_$sv\" % \"1.0.1\")\n  }\n}\n\nscalacOptions += \"-P:continuations:enable\"\n```\n\n### Requirement\n\nMemcontinuationed requires Scala 2.10.x or 2.11.x, and JRE 7.\n\n## Links\n\n* [The API documentation](http://central.maven.org/maven2/com/dongxiguo/memcontinuationed_2.11/0.3.2/memcontinuationed_2.11-0.3.2-javadoc.jar)\n* [Coding examples](https://github.com/Atry/memcontinuationed/tree/master/src/test/scala/com/dongxiguo/memcontinuationed)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAtry%2Fmemcontinuationed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAtry%2Fmemcontinuationed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAtry%2Fmemcontinuationed/lists"}