Conversation
9c60cc1 to
dfa7d75
Compare
dfa7d75 to
7f0c7cf
Compare
7f0c7cf to
e1f0d29
Compare
| val lcount = left match { | ||
| case value: TransactionOutput[_, _, _] => value.count | ||
| case _ => 1 | ||
| } | ||
|
|
||
| val rcount = right match { | ||
| case value: TransactionOutput[_, _, _] => value.count | ||
| case _ => 1 | ||
| } |
There was a problem hiding this comment.
You can factor these two out, not much benefit from nesting them this way.
| val left: Output[A] | ||
| val right: Output[B] | ||
|
|
||
| def tryDecode(respValue: RespValue)(implicit codec: BinaryCodec): Out = |
| val left: Output[A] | ||
| val right: Output[B] |
| def tryDecode(respValue: RespValue)(implicit codec: BinaryCodec): Out = | ||
| respValue match { | ||
| case RespValue.Array(values) => | ||
| this match { |
There was a problem hiding this comment.
Let's introduce self (both for consistency and safety).
| this match { | ||
| case _: Zip[_, _] => | ||
| (left, right) match { | ||
| case (l: TransactionOutput[_, _, _], r: TransactionOutput[_, _, _]) => |
There was a problem hiding this comment.
Don't introduce names, shadow them instead - less concepts to deal with.
| final case class Zip[+A, +B]( | ||
| left: Output[A], | ||
| right: Output[B] | ||
| ) extends TransactionOutput[A, B, (A, B)] | ||
|
|
||
| final case class ZipLeft[+A, +B]( | ||
| left: Output[A], | ||
| right: Output[B] | ||
| ) extends TransactionOutput[A, B, A] | ||
|
|
||
| final case class ZipRight[+A, +B]( | ||
| left: Output[A], | ||
| right: Output[B] | ||
| ) extends TransactionOutput[A, B, B] |
There was a problem hiding this comment.
Nit: I think you can write them down in a line-per-class manner:
final case class Zip[+A, +B](left: Output[A], right: Output[B]) extends TransactionOutput[A, B, (A, B)]| def codec: BinaryCodec | ||
| def executor: RedisExecutor |
There was a problem hiding this comment.
Why do you need them to be public?
|
|
||
| def commit: ZIO[Redis, RedisError, Out] = | ||
| ZIO.serviceWithZIO[Redis] { redis => | ||
| this match { |
There was a problem hiding this comment.
self (for reasons mentioned above)
| import zio.schema.codec.BinaryCodec | ||
| import zio.{URLayer, ZLayer} | ||
|
|
||
| trait Redis extends api.Sets |
There was a problem hiding this comment.
This seems to duplicate the entire API, do we really need it? Can't we have transactional combinators on top of the existing API and use transactions as "scoping" mechanism?
| ( | ||
| l.tryDecode(RespValue.Array(values.take(l.count))), | ||
| r.tryDecode(RespValue.Array(values.drop(l.count).take(r.count))) | ||
| ).asInstanceOf[Out] |
There was a problem hiding this comment.
We have some "gray zone" safety here.
e1f0d29 to
f5ce881
Compare
f5ce881 to
7f5cbda
Compare
Add transactional package. Add transactional sets API. Add few transactional sets tests. Signed-off-by: Aleksandar Novakovic <anovakovic01@gmail.com>
Extract all of the commands to the commands package in order to share them between transactional and normal API. Signed-off-by: Aleksandar Novakovic <anovakovic01@gmail.com>
Signed-off-by: Aleksandar Novakovic <anovakovic01@gmail.com>
e0a8ed5 to
c0fd6d1
Compare
Signed-off-by: Aleksandar Novakovic <anovakovic01@gmail.com>
Signed-off-by: Aleksandar Novakovic <anovakovic01@gmail.com>
| } | ||
| ), | ||
| suite("Stralgo")( | ||
| suite("StrAlgo")( |
| def zipLeft[A](that: RedisTransaction[A]): RedisTransaction[Out] = | ||
| ZipLeft(this, that) | ||
|
|
||
| def zipRight[A](that: RedisTransaction[A]): RedisTransaction[A] = | ||
| ZipRight(this, that) |
| sealed trait RedisTransaction[+Out] { self => | ||
| import RedisTransaction._ | ||
|
|
||
| def commit: ZIO[Redis, RedisError, Out] = |
| private[redis] trait Cluster extends RedisEnvironment { | ||
| import Cluster._ | ||
|
|
||
| final val _asking: RedisCommand[Unit, Unit] = askingCommand(codec, executor) |
There was a problem hiding this comment.
Two things:
- let's not name things like this
- are these exist to "help" with
transactionalpackage?
Generally speaking, they may be useful, but we don't have a "proof" for that (i.e. benchmarks), and they don't improve anything on schema-dependent commands.
There was a problem hiding this comment.
These are used by both regular API and Transactional one. The idea was to define a command once and use it from both APIs. It was not introduced for optimization purposes. Also, I've done this because I don't know how to use the same API for both. The reason is the runtime behaviour. Regular API sends a command and receives a response, while the transactional one sends a command and has to remember what type of output it would have to parse later when EXEC is sent. That's why I had to introduce RedisTransaction which is basically transactional command.
| case Single(command, in) => | ||
| command.run(in) |
There was a problem hiding this comment.
Is it possible reuse the existing API here (e.g. pass by name), rather than having a dedicated package full of duplicates?
| import zio.redis.{Output, RedisCommand, RedisError} | ||
| import zio.{ZIO, Zippable} | ||
|
|
||
| sealed trait RedisTransaction[+Out] { self => |
There was a problem hiding this comment.
I'd still prefer it in zio.redis rather than in a separate package.
|
Offtopic: please sync with master or re-open as it's diverging quickly :) |
This PR resolves #156.
Summary:
MULTI-EXECtransactions,