Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finagle-redis: Add support for Redis Geo commands #628

Closed
wants to merge 2 commits into from

Conversation

Mura-Mi
Copy link

@Mura-Mi Mura-Mi commented Jul 11, 2017

Problem

finagle-redis does not support geo index operation

Solution

Implement GEOADD, GEOPOS, GEOHASH, GEODIST, GEORADIUS and
GEORADIUSBYMEMBER operation in finagle-redis.

@CLAassistant
Copy link

CLAassistant commented Jul 11, 2017

CLA assistant check
All committers have signed the CLA.

@kevinoliver
Copy link
Contributor

@Mura-Mi thanks for the patch/feature! gonna try to find someone who knows finagle-redis better than i to take a look at this.

Copy link
Contributor

@nepthar nepthar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Mura-Mi thanks so much! This is awesome!

In addition to the inline comments, I have a few notes.

  1. Could you please refactor things like fn defs to follow our style guidelines? https://github.com/twitter/finagle/blob/master/CONTRIBUTING.md#style
  2. There's no need for lazy vals on singletons and long lived objects. Can you leave them only on things like command responses?
  3. I think it would be helpful to link to some geohash-related documentation somewhere since not everyone is familiar with them. I suggest the redis page: https://redis.io/commands/geohash. Also, maybe a note about which versions of redis support these commands, so folks have that info at hand.

import com.twitter.io.Buf
import com.twitter.io.Buf.Utf8

case class GeoAdd(key: Buf, values: (Double, Double, Buf)*)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a case class for (Double, Double, Buf) instead of a tuple for clarity

withCoord: JBoolean = false,
withDist: JBoolean = false,
withHash: JBoolean = false,
count: JInt = null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we avoid nulls here and just use Option directly?

Copy link
Contributor

@vkostyukov vkostyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Mura-Mi! This looks pretty decent already! I have just a few nits around using Java numeric types (what's the reason for that?).

Also, please, don't forget to sign the CLA as our CLAsistant bot suggest.

*
* @return Future of the number of elements added to the sorted set
*/
def geoAdd(key: Buf, values: (Double, Double, Buf)*): Future[JLong] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this has to be Java Long?

* @return Future of an array where each element is a tuple representing
* longitude and latitude (x,y) of each member, or `None` if member is missing.
*/
def geoPos(key: Buf, members: Buf*): Future[Seq[Option[(JDouble, JDouble)]]] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why using Java Doubles?

case EmptyMBulkReply => Future.Nil
case MBulkReply(positions) => Future.value(positions.map {
case MBulkReply(Seq(longitude, latitude)) => (longitude, latitude) match {
case (BulkReply(lon), BulkReply(lat)) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can inline Buf.Utf8(lon) in this pattern matching to get the string out of BulkReply(lon). This way, you won't need to call BufToString later.

}
}

private lazy val geoDistResultHandler: PartialFunction[Reply, Future[Option[JDouble]]] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar question about JDouble.


private lazy val geoDistResultHandler: PartialFunction[Reply, Future[Option[JDouble]]] = {
case EmptyBulkReply => Future.None
case BulkReply(buf) => Future.value(Utf8.unapply(buf).map(_.toDouble))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please inline Buf.Utf8() extractor here.

* @return Future of the distance in the specified unit,
* or `None` if one or both the elements are missing.
*/
def geoDist(key: Buf, member1: Buf, member2: Buf, unit: GeoUnit = null): Future[Option[JDouble]] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer this w/o nulls. Also why JDouble?

case BulkReply(dist) => (r: GeoRadiusResult) => r.copy(dist = Some(BufToString(dist).toDouble))
case MBulkReply(BulkReply(lon) :: BulkReply(lat) :: Nil) =>
(r: GeoRadiusResult) =>
r.copy(coord = Some((BufToString(lon).toDouble, BufToString(lat).toDouble)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, inline Buf.Utf8() extractor instead.

object GeoUnit {

/** Meter */
case object m extends GeoUnit("m")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about GeoUnit.Meter, GeoUnit.Mile, etc?

Copy link
Author

@Mura-Mi Mura-Mi Jul 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good. I've named like these as described in Redis document, but I'll modify.

@nepthar
Copy link
Contributor

nepthar commented Jul 24, 2017

@Mura-Mi this looks good to me once @vkostyukov's comments about nulls/java types are addressed. Thanks!

@vkostyukov
Copy link
Contributor

@Mura-Mi Thanks for working on this! I still think we don't need to use Java types directly. Also, please, don't use BufToString. Try Buf.Utf8() extractor instead. Other than that, this looks good to me.

@bryce-anderson
Copy link
Contributor

@Mura-Mi, are you still interested in getting this merged? This looks pretty close, but there appears to be a few outstanding comments.

@Mura-Mi
Copy link
Author

Mura-Mi commented Sep 21, 2017

Thank you for reviewing my pull request. I'm removing the usage of Java primitive numbers and BufToString converter.

In TravisCI, latest redis-server is not available so the Geo API Redis integration test fails. I'm trying to install redis-server via apt-package. Is this acceptable?

Problem

finagle-redis does not support geo index operation

Solution

Implement GEOADD, GEOPOS,  GEOHASH, GEODIST, GEORADIUS and
GEORADIUSBYMEMBER operation in finagle-redis.
Latest version of `redis-server` is not available in default TravisCI
setting. To avoid Redis Geo API integration test's failing, make
latest redis-server available via apt-package.
@mkhq
Copy link
Contributor

mkhq commented Sep 21, 2017

@Mura-Mi would it be possible to move the integration tests into finagle-redis/src/it? All redis integration tests were moved there recently. Run in sbt with it:test.

@yannick-polius
Copy link
Contributor

@mkhq @Mura-Mi I had an internal reason to implement a similar PR. My version took a bit from this PR and is on the internal code review. I moved the integration test into finagle-redis/src/it.

Do we want to decide if we want to use this one or the other code review?

@mkhq
Copy link
Contributor

mkhq commented Jan 12, 2018

@yannick-polius Is this PR replaced by d32d123 ?

@yannick-polius
Copy link
Contributor

@mkhq yeah we were able to land it with that change.

@yannick-polius
Copy link
Contributor

@mkhq please see 269e181 for attribution

@Mura-Mi Mura-Mi closed this Jan 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

8 participants