Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ group: edge

matrix:
include:
- jdk: oraclejdk8
scala: 2.10.6
env: COMMAND=ci PUBLISH=
- jdk: oraclejdk8
scala: 2.11.11
env: COMMAND=ci PUBLISH=
- jdk: oraclejdk8
scala: 2.12.3
env: COMMAND=ci PUBLISH=true
- jdk: oraclejdk8
scala: 2.13.5
env: COMMAND=ci PUBLISH=true

env:
global:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ architecture, choices that made sense in the context of Java, but
don't make so much sense in the context of Scala (TODO: add details).

The client is production quality.
Supported for Scala versions: 2.10, 2.11 and 2.12.
Supported for Scala versions: 2.11, 2.12 and 2.13.

## Release Notes

Expand Down
39 changes: 24 additions & 15 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ organization := "io.monix"
addCommandAlias("ci", ";clean ;compile ;test ;package")
addCommandAlias("release", ";+publishSigned ;sonatypeReleaseAll")

scalaVersion := "2.11.11"
crossScalaVersions := Seq("2.10.6", "2.11.11", "2.12.3")
scalaVersion := "2.12.3"
crossScalaVersions := Seq("2.11.11", "2.12.3", "2.13.5")
compileOrder in ThisBuild := CompileOrder.JavaThenScala

scalacOptions ++= {
Expand All @@ -16,8 +16,7 @@ scalacOptions ++= {
"-deprecation", // emit warning for usages of deprecated APIs
"-feature", // emit warning usages of features that should be imported explicitly
// possibly deprecated options
"-Ywarn-dead-code",
"-Ywarn-inaccessible"
"-Ywarn-dead-code"
)
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, majorVersion)) if majorVersion >= 12 => baseOptions
Expand All @@ -33,7 +32,6 @@ scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
"-Xlint:adapted-args", // warn if an argument list is modified to match the receiver
"-Xlint:nullary-unit", // warn when nullary methods return Unit
"-Xlint:inaccessible", // warn about inaccessible types in method signatures
"-Xlint:nullary-override", // warn when non-nullary `def f()' overrides nullary `def f'
"-Xlint:infer-any", // warn when a type argument is inferred to be `Any`
"-Xlint:missing-interpolator", // a string literal appears to be missing an interpolator id
"-Xlint:doc-detached", // a ScalaDoc comment appears to be detached from its element
Expand All @@ -42,28 +40,39 @@ scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
"-Xlint:poly-implicit-overload", // parameterized overloaded implicit methods are not visible as view bounds
"-Xlint:option-implicit", // Option.apply used implicit view
"-Xlint:delayedinit-select", // Selecting member of DelayedInit
"-Xlint:by-name-right-associative", // By-name parameter of right associative operator
"-Xlint:package-object-classes", // Class or object defined in package object
"-Xlint:unsound-match" // Pattern match may not be typesafe
)
case _ =>
Seq.empty
})

scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, majorVersion)) if majorVersion <= 12 =>
Seq(
"-Ywarn-inaccessible",
"-Xlint:nullary-override", // warn when non-nullary `def f()' overrides nullary `def f'
"-Xlint:by-name-right-associative", // By-name parameter of right associative operator
"-Xlint:unsound-match" // Pattern match may not be typesafe
)
case _ => Seq.empty
})

// Turning off fatal warnings for ScalaDoc, otherwise we can't release.
scalacOptions in (Compile, doc) ~= (_ filterNot (_ == "-Xfatal-warnings"))

resolvers ++= Seq(
"Spy" at "http://files.couchbase.com/maven2/"
("Spy" at "http://files.couchbase.com/maven2/").withAllowInsecureProtocol(true)
)

libraryDependencies ++= Seq(
"net.spy" % "spymemcached" % "2.12.3",
"org.slf4j" % "slf4j-api" % "1.7.23",
"io.monix" %% "monix-eval" % "2.3.0",
"ch.qos.logback" % "logback-classic" % "1.1.7" % Test,
"org.scalatest" %% "scalatest" % "3.0.1" % Test,
"org.scalacheck" %% "scalacheck" % "1.13.4" % Test
"net.spy" % "spymemcached" % "2.12.3",
"org.slf4j" % "slf4j-api" % "1.7.30",
"io.monix" %% "monix-eval" % "3.3.0",
"ch.qos.logback" % "logback-classic" % "1.2.3" % Test,
"org.scalatest" %% "scalatest" % "3.2.6" % Test,
"org.scalatest" %% "scalatest-funsuite" % "3.2.6" % Test,
"org.scalacheck" %% "scalacheck" % "1.15.2" % Test,
"org.scalatestplus" %% "scalacheck-1-14" % "3.2.2.0" % Test
)

libraryDependencies += ("org.scala-lang" % "scala-reflect" % scalaVersion.value % "compile")
Expand Down Expand Up @@ -120,7 +129,7 @@ publishTo := Some(
publishArtifact in Test := false
pomIncludeRepository := { _ => false } // removes optional dependencies

scalariformSettings
scalariformSettings(true)

licenses := Seq("MIT" -> url("https://opensource.org/licenses/MIT"))
homepage := Some(url("https://github.com/monix/shade"))
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# https://github.com/monix/shade/blob/master/LICENSE.txt
#

sbt.version=0.13.15
sbt.version=1.4.6
10 changes: 5 additions & 5 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resolvers += Classpaths.sbtPluginReleases

addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.1")
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.18")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.1.1")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.3")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.5")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.7")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0")
18 changes: 9 additions & 9 deletions src/main/scala/shade/inmemory/InMemoryCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e
private[this] val scheduler = Scheduler(ec)

def get[T](key: String): Option[T] = {
val currentState = stateRef.get
val currentState = stateRef.get()

currentState.values.get(key) match {
case Some(value) if value.expiresAt > System.currentTimeMillis() =>
Expand All @@ -74,7 +74,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e
def add[T](key: String, value: T, expiry: Duration = Duration.Inf): Boolean = {
val ts = getExpiryTS(expiry)
val currentTS = System.currentTimeMillis()
val currentState = stateRef.get
val currentState = stateRef.get()

val itemExists = currentState.values.get(key) match {
case Some(item) if item.expiresAt > currentTS =>
Expand Down Expand Up @@ -109,7 +109,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e

@tailrec
def delete(key: String): Boolean = {
val currentState = stateRef.get
val currentState = stateRef.get()

currentState.values.get(key) match {
case Some(value) =>
Expand All @@ -127,7 +127,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e

@tailrec
def cachedFuture[T](key: String, expiry: Duration = Duration.Inf)(cb: => Future[T]): Future[T] = {
val currentState = stateRef.get
val currentState = stateRef.get()

val currentValue = currentState.values.get(key) match {
case Some(value) if value.expiresAt > System.currentTimeMillis() =>
Expand Down Expand Up @@ -157,7 +157,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e
}

def compareAndSet[T](key: String, expected: Option[T], update: T, expiry: Duration): Boolean = {
val current = stateRef.get
val current = stateRef.get()
val ts = getExpiryTS(expiry)

val currentValue = current.values.get(key) match {
Expand Down Expand Up @@ -239,18 +239,18 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e

def size: Int = {
val ts = System.currentTimeMillis()
stateRef.get.values.count(_._2.expiresAt <= ts)
stateRef.get().values.count(_._2.expiresAt <= ts)
}

def realSize: Int = stateRef.get.values.size
def realSize: Int = stateRef.get().values.size

/**
* Future that completes when a maintenance window has run,
* giving the number of items that were removed.
* @return
*/
def maintenance: Future[Int] =
stateRef.get.maintenancePromise.future
stateRef.get().maintenancePromise.future

def close(): Unit = {
Try(task.cancel())
Expand All @@ -259,7 +259,7 @@ private[inmemory] final class InMemoryCacheImpl(implicit ec: ExecutionContext) e
}

protected def getExpiryTS(expiry: Duration): Long =
if (expiry.isFinite())
if (expiry.isFinite)
System.currentTimeMillis() + expiry.toMillis
else
System.currentTimeMillis() + 365.days.toMillis
Expand Down
20 changes: 8 additions & 12 deletions src/main/scala/shade/memcached/Codec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ trait BaseCodecs {
(value >>> 24).asInstanceOf[Byte],
(value >>> 16).asInstanceOf[Byte],
(value >>> 8).asInstanceOf[Byte],
value.asInstanceOf[Byte]
)
value.asInstanceOf[Byte])

def deserialize(data: Array[Byte]): Int =
(data(0).asInstanceOf[Int] & 255) << 24 |
Expand Down Expand Up @@ -83,8 +82,7 @@ trait BaseCodecs {
(value >>> 24).asInstanceOf[Byte],
(value >>> 16).asInstanceOf[Byte],
(value >>> 8).asInstanceOf[Byte],
value.asInstanceOf[Byte]
)
value.asInstanceOf[Byte])

def deserialize(data: Array[Byte]): Long =
(data(0).asInstanceOf[Long] & 255) << 56 |
Expand All @@ -108,8 +106,7 @@ trait BaseCodecs {
implicit object CharBinaryCodec extends Codec[Char] {
def serialize(value: Char): Array[Byte] = Array(
(value >>> 8).asInstanceOf[Byte],
value.asInstanceOf[Byte]
)
value.asInstanceOf[Byte])

def deserialize(data: Array[Byte]): Char =
((data(0).asInstanceOf[Int] & 255) << 8 |
Expand All @@ -120,8 +117,7 @@ trait BaseCodecs {
implicit object ShortBinaryCodec extends Codec[Short] {
def serialize(value: Short): Array[Byte] = Array(
(value >>> 8).asInstanceOf[Byte],
value.asInstanceOf[Byte]
)
value.asInstanceOf[Byte])

def deserialize(data: Array[Byte]): Short =
((data(0).asInstanceOf[Short] & 255) << 8 |
Expand Down Expand Up @@ -153,18 +149,18 @@ trait GenericCodec {
}

def serialize(value: S): Array[Byte] =
using (new ByteArrayOutputStream()) { buf =>
using (new ObjectOutputStream(buf)) { out =>
using(new ByteArrayOutputStream()) { buf =>
using(new ObjectOutputStream(buf)) { out =>
out.writeObject(value)
out.close()
buf.toByteArray
}
}

def deserialize(data: Array[Byte]): S =
using (new ByteArrayInputStream(data)) { buf =>
using(new ByteArrayInputStream(data)) { buf =>
val in = new GenericCodecObjectInputStream(classTag, buf)
using (in) { inp =>
using(in) { inp =>
inp.readObject().asInstanceOf[S]
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/shade/memcached/FakeMemcached.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,17 @@ class FakeMemcached(context: ExecutionContext) extends Memcached {
def increment(key: String, by: Long, default: Option[Long], exp: Duration): Future[Long] = {
def toBigInt(bytes: Seq[Byte]): BigInt = BigInt(new String(bytes.toArray))
Future.successful(cache.transformAndGet[Seq[Byte]](key, exp) {
case Some(current) => (toBigInt(current) + by).toString.getBytes
case None if default.isDefined => default.get.toString.getBytes
case Some(current) => (toBigInt(current) + by).toString.getBytes.toIndexedSeq
case None if default.isDefined => default.get.toString.getBytes.toIndexedSeq
case None => throw new UnhandledStatusException(s"For key $key - CASNotFoundStatus")
}).map(toBigInt).map(_.toLong)
}

def decrement(key: String, by: Long, default: Option[Long], exp: Duration): Future[Long] = {
def toBigInt(bytes: Seq[Byte]): BigInt = BigInt(new String(bytes.toArray))
Future.successful(cache.transformAndGet[Seq[Byte]](key, exp) {
case Some(current) => (toBigInt(current) - by).max(0).toString.getBytes
case None if default.isDefined => default.get.toString.getBytes
case Some(current) => (toBigInt(current) - by).max(0).toString.getBytes.toIndexedSeq
case None if default.isDefined => default.get.toString.getBytes.toIndexedSeq
case None => throw new UnhandledStatusException(s"For key $key - CASNotFoundStatus")
}).map(toBigInt).map(_.toLong)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import scala.util.control.NonFatal
* Play's test/run modes.
*/
class GenericCodecObjectInputStream(classTag: ClassTag[_], in: InputStream)
extends ObjectInputStream(in) {
extends ObjectInputStream(in) {

private def classTagClassLoader =
classTag.runtimeClass.getClassLoader
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/shade/memcached/Memcached.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ trait Memcached extends java.io.Closeable {
*/
def set[T](key: String, value: T, exp: Duration)(implicit codec: Codec[T]): CancelableFuture[Unit]

def awaitSet[T](key: String, value: T, exp: Duration)(implicit codec: Codec[T]) {
def awaitSet[T](key: String, value: T, exp: Duration)(implicit codec: Codec[T]): Unit = {
Await.result(set(key, value, exp), Duration.Inf)
}

Expand Down
17 changes: 6 additions & 11 deletions src/main/scala/shade/memcached/MemcachedImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,7 @@ class MemcachedImpl(config: Configuration, ec: ExecutionContext) extends Memcach
throw new CancelledException(withoutPrefix(k))
case FailedResult(k, unhandled) =>
throw new UnhandledStatusException(
s"For key ${withoutPrefix(k)} - ${unhandled.getClass.getName}"
)
s"For key ${withoutPrefix(k)} - ${unhandled.getClass.getName}")
}

@inline
Expand All @@ -324,8 +323,7 @@ class MemcachedImpl(config: Configuration, ec: ExecutionContext) extends Memcach
if (System.getProperty("net.spy.log.LoggerImpl") == null) {
System.setProperty(
"net.spy.log.LoggerImpl",
"shade.memcached.internals.Slf4jLogger"
)
"shade.memcached.internals.Slf4jLogger")
}

val conn = {
Expand All @@ -334,8 +332,7 @@ class MemcachedImpl(config: Configuration, ec: ExecutionContext) extends Memcach
if (config.protocol == Protocol.Binary)
SpyProtocol.BINARY
else
SpyProtocol.TEXT
)
SpyProtocol.TEXT)
.setDaemon(true)
.setFailureMode(config.failureMode match {
case FailureMode.Retry =>
Expand Down Expand Up @@ -369,19 +366,17 @@ class MemcachedImpl(config: Configuration, ec: ExecutionContext) extends Memcach
withTimeoutThreshold.setAuthDescriptor(
new AuthDescriptor(
Array("PLAIN"),
new PlainCallbackHandler(credentials.username, credentials.password)
)
)
new PlainCallbackHandler(credentials.username, credentials.password)))
case None =>
withTimeoutThreshold
}

withAuth
}

import scala.collection.JavaConverters._
import scala.jdk.CollectionConverters._
val addresses = AddrUtil.getAddresses(config.addresses).asScala
new SpyMemcachedIntegration(conn.build(), addresses, Scheduler(context))
new SpyMemcachedIntegration(conn.build(), addresses.toSeq, Scheduler(context))
}
}

4 changes: 2 additions & 2 deletions src/main/scala/shade/memcached/internals/PartialResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ final class MutablePartialResult[T] {
_result.compareAndSet(NoResultAvailable, FutureResult(result))

def completePromise(key: String, promise: Promise[Result[T]]): Unit = {
_result.get match {
_result.get() match {
case FinishedResult(result) =>
promise.tryComplete(result)
case FutureResult(result) =>
promise.tryCompleteWith(result)
promise.completeWith(result)
case NoResultAvailable =>
promise.tryComplete(Success(FailedResult(key, IllegalCompleteStatus)))
}
Expand Down
Loading