Skip to content

Instantly share code, notes, and snippets.

@machuz
Created August 1, 2018 12:11
Show Gist options
  • Save machuz/e1482867a2da0fd625c5c8c76106ec08 to your computer and use it in GitHub Desktop.
Save machuz/e1482867a2da0fd625c5c8c76106ec08 to your computer and use it in GitHub Desktop.
redis実装パターン(hash利用。これに決めた)
class RedisClientImpl @Inject()(
system: ActorSystem
)(
host: String,
port: Int,
password: Option[String],
dbNum: Option[Int]
) extends RedisClient {
protected lazy val c: RediscalaClient =
RediscalaClient(
host,
port,
password,
dbNum
)(_system = system)
final override def put[A: ByteStringFormatter](
key: CacheKey,
value: A,
expireSeconds: Option[Long] = None
): Task[\/[EsError, A]] = {
for {
r <- {
Task
.deferFuture(c.set(Tag.unwrap(key), value, expireSeconds))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) value.right[EsError]
else
NonFatalError(
new RuntimeException(
s"redis set command failure [key=$key,value=$value,expireSeconds=$expireSeconds]"
),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def putList[A: ByteStringFormatter](
key: CacheKey,
values: Seq[A],
expireSeconds: Option[Long] = None
): Task[\/[EsError, Seq[A]]] = {
for {
r1E <- {
Task
.deferFuture(c.lpush(Tag.unwrap(key), values: _*))
.materialize
.map {
case S(_) => values.right
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
r2E <- {
expireSeconds match {
case Some(expire) if r1E.isRight =>
Task
.deferFuture(c.expire(Tag.unwrap(key), expire))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) ().right[EsError]
else
NonFatalError(
new RuntimeException(s"redis expire command failure [key=$key,expireSeconds=$expireSeconds]"),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
case _ => Task.now(().right[EsError])
}
}
} yield
for {
r <- r1E
_ <- r2E
} yield r
}
final override def putHash[A: ByteStringFormatter](
key: CacheKey,
hashKey: CacheHashKey,
value: A,
expireSeconds: Option[Long] = None
): Task[\/[EsError, A]] = {
for {
r1E <- {
Task
.deferFuture(c.hset(Tag.unwrap(key), Tag.unwrap(hashKey), value))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) value.right[EsError]
else
NonFatalError(
new RuntimeException(
s"redis hset command failure [key=$key,value=$value,expireSeconds=$expireSeconds]"
),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
r2E <- {
expireSeconds match {
case Some(expire) if r1E.isRight =>
Task
.deferFuture(c.expire(Tag.unwrap(key), expire))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) ().right[EsError]
else
NonFatalError(
new RuntimeException(s"redis expire command failure [key=$key,expireSeconds=$expireSeconds]"),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
case _ => Task.now(().right[EsError])
}
}
} yield
for {
r <- r1E
_ <- r2E
} yield r
}
final override def putBulkHash[A: ByteStringFormatter](
key: CacheKey,
values: Map[CacheHashKey, A],
expireSeconds: Option[Long] = None
): Task[\/[EsError, Seq[A]]] = {
for {
r1E <- {
Task
.deferFuture(c.hmset(Tag.unwrap(key), values.map(v => Tag.unwrap(v._1) -> v._2)))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) values.values.toSeq.right[EsError]
else
NonFatalError(
new RuntimeException(
s"redis hset command failure [key=$key,value=$values,expireSeconds=$expireSeconds]"
),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
r2E <- {
expireSeconds match {
case Some(expire) if r1E.isRight =>
Task
.deferFuture(c.expire(Tag.unwrap(key), expire))
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) ().right[EsError]
else
NonFatalError(
new RuntimeException(s"redis expire command failure [key=$key,expireSeconds=$expireSeconds]"),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) =>
NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
case _ => Task.now(().right[EsError])
}
}
} yield
for {
r <- r1E
_ <- r2E
} yield r
}
final override def get[A: ByteStringFormatter](
key: CacheKey
): Task[\/[EsError, Option[A]]] = {
for {
r <- {
Task
.deferFuture(c.get(Tag.unwrap(key)))
.materialize
.map {
case S(Some(r)) => r.some.right
case S(None) => None.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def getList[A: ByteStringFormatter](
key: CacheKey,
start: Int = 0,
stop: Int = -1
): Task[\/[EsError, Seq[A]]] = {
for {
r <- {
Task
.deferFuture(c.lrange[A](Tag.unwrap(key), start, stop))
.materialize
.map {
case S(xs) => xs.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def scan[A: ByteStringFormatter](
matchGlob: CacheKeyGlob
): Task[\/[EsError, Seq[A]]] = {
for {
keySeqTask <- {
Task
.deferFuture(c.keys(Tag.unwrap(matchGlob)))
.materialize
.map {
case S(xs) => xs.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
rE <- {
keySeqTask match {
case \/-(keySeq) if keySeq.nonEmpty =>
Task
.deferFuture(c.mget(keySeq: _*))
.materialize
.map {
case S(scanResSeq) => scanResSeq.flatten.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
case \/-(keySeq) if keySeq.isEmpty =>
Task.now(Nil.right)
case -\/(e) => Task.now(e.left)
}
}
} yield
for {
_ <- keySeqTask
r <- rE
} yield r
}
final override def scanHash[A: ByteStringFormatter](
key: CacheKey,
hashKeyGlob: CacheHashKeyGlob,
cursor: Int = 0,
count: Option[Int] = None
): Task[\/[EsError, Seq[A]]] = {
for {
r <- {
Task
.deferFuture(c.hscan(Tag.unwrap(key), cursor, count, Tag.unwrap(hashKeyGlob).some))
.materialize
.map {
case S(xs) => xs.data.values.toList.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def delete(
key: CacheKey
): Task[\/[EsError, Unit]] = {
for {
r <- {
Task
.deferFuture(c.del(Tag.unwrap(key)))
.materialize
.map {
case S(_) => ().right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def deleteHash(
key: CacheKey,
hashKeys: Seq[CacheHashKey]
): Task[\/[EsError, Unit]] = {
for {
r <- {
Task
.deferFuture(c.hdel(Tag.unwrap(key), hashKeys.map(Tag.unwrap): _*))
.materialize
.map {
case S(_) => ().right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def exists(
key: CacheKey
): Task[\/[EsError, Boolean]] = {
for {
r <- {
Task
.deferFuture(c.exists(Tag.unwrap(key)))
.materialize
.map {
case S(r) => r.right
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
final override def clear: Task[\/[EsError, Unit]] = {
for {
r <- {
Task
.deferFuture(c.flushdb())
.materialize
.map {
case S(isSuccessful) =>
if (isSuccessful) ().right
else
NonFatalError(
new RuntimeException(s"redis clear command failure [res=$isSuccessful]"),
ErrorCode.REDIS_COMMAND_ERROR
).left
case F(throwable) => NonFatalError(throwable, ErrorCode.REDIS_REQUEST_ERROR).left
}
}
} yield r
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment