chrisdinn / brando

A Redis client written with Akka's IO package
Other
107 stars 24 forks source link

Authentication doesn't work #67

Open KarelCemus opened 8 years ago

KarelCemus commented 8 years ago

I traced issues reported as Brando #64 and play-redis #44 and #29

Backstory

We noticed the first occurrence of the issue on Heroku because it secures its redis instance. It caused excessive logging without any reasonable error message.

However, I successfully reproduced in on localhost when I secured my redis instance.

How to reproduce

Enable redis authentication in redis.conf, e.g., uncomment

requirepass foobared

Code reproducing the issue

Example of Play framework controller:

package controllers

import javax.inject.Inject

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

import play.api.mvc._

import akka.actor.ActorSystem
import akka.pattern._
import brando.Redis

class Application @Inject( )( system: ActorSystem ) extends Controller {

  implicit val timeout = akka.util.Timeout( 1.second )

  val actor = system actorOf Redis( "localhost", 6379, database = 1, auth = Some( "foobared" ) )

  def ping( ) = actor ? brando.Request( "PING" )

  def index = Action.async {

    ping( ).map { case message =>
      Ok( views.html.index( "done", message ) )
    }.recover { case ex =>
      Ok( views.html.index( "error", ex.toString ) )
    }
  }

}

Observation

When used Redis actor the response is the redis is disconnected. When the StashingRedis is used, requests timeout. Both no further reason provided.

Tracing the issue

To trace the issue, I inserted several logging statements into Brando. I figured out two things:

  1. Authentication method is never called even when proper auth is provided. The reason is it stucks in Connecting state but the authentication is executed on Connected.
  2. The following logging statements suggest that Brando always creates new connection with every attempt but probably somehow does not closes the previous. First, actor id changes, second, when deployed on Heroku, it dies after 30 attempts due to 'ERR max number of clients reached'.
2016-04-21T13:07:53.071807+00:00 app[web.1]: Queue(Actor[akka://application/temp/$v])
2016-04-21T13:07:54.081759+00:00 app[web.1]: connecting
2016-04-21T13:07:54.093458+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:54.093624+00:00 app[web.1]: Queue(Actor[akka://application/temp/$w])
2016-04-21T13:07:55.112304+00:00 app[web.1]: connecting
2016-04-21T13:07:55.119680+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:55.119837+00:00 app[web.1]: Queue(Actor[akka://application/temp/$x])
2016-04-21T13:07:56.135040+00:00 app[web.1]: connecting
2016-04-21T13:07:56.140825+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:56.141029+00:00 app[web.1]: Queue(Actor[akka://application/temp/$y])
2016-04-21T13:07:57.152416+00:00 app[web.1]: connecting
2016-04-21T13:07:57.161871+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:57.162046+00:00 app[web.1]: Queue(Actor[akka://application/temp/$z])
2016-04-21T13:07:58.184895+00:00 app[web.1]: connecting
2016-04-21T13:07:58.200840+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:58.210118+00:00 app[web.1]: Queue(Actor[akka://application/temp/$A])
2016-04-21T13:07:59.221666+00:00 app[web.1]: connecting
2016-04-21T13:07:59.226342+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:07:59.226689+00:00 app[web.1]: Queue(Actor[akka://application/temp/$B])
2016-04-21T13:08:00.243840+00:00 app[web.1]: connecting
2016-04-21T13:08:00.250774+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:08:00.251051+00:00 app[web.1]: Queue(Actor[akka://application/temp/$C])
2016-04-21T13:08:01.264740+00:00 app[web.1]: connecting
2016-04-21T13:08:01.273008+00:00 app[web.1]: Some(Failure(brando.RedisException: NOAUTH Authentication required))
2016-04-21T13:08:01.273249+00:00 app[web.1]: Queue(Actor[akka://application/temp/$D])
2016-04-21T13:08:02.293235+00:00 app[web.1]: connecting
2016-04-21T13:08:02.297606+00:00 app[web.1]: Some(Failure(brando.RedisException: ERR max number of clients reached))
2016-04-21T13:08:02.297748+00:00 app[web.1]: Queue(Actor[akka://application/temp/$E])

Subsequent issues

When max number of clients is reached, it crashes at this line.

Finally, it goes out of memory after while. However, I am not sure what exactly causes the memory leaking, just guessing.

KarelCemus commented 8 years ago

@neilchaudhuri might confirm the issue rised since Brando 3.0.x. Based on play-redis#29 I guess it worked with Brando 2.x.x

KarelCemus commented 8 years ago

OK, I confirm myself, with Brando 2.1.2 it works as expected.

chandanpasunoori commented 8 years ago

is this is fixed ?? I'm still not able to connect

val redis = system.actorOf(Redis("localhost", 6379)) 
[INFO] [08/07/2016 10:32:28.971] [redis-test-akka.actor.default-dispatcher-3] [akka://redis-test/deadLetters] Message [akka.actor.PoisonPill$] from Actor[akka://redis-test/user/$c#-932188988] to Actor[akka://redis-test/deadLetters] was not delivered. [4] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
redis: ActorRef = Actor[akka://redis-test/user/$c#-932188988]
jasongoodwin commented 8 years ago

I think it's only on Damien's branch at the moment. You could use local publishes of the branch until it's published.

check it out

git clone https://github.com/damienlevin/brando
cd brando/
git checkout issue67

then publish it with sbt or activator

sbt +publish-local
activator +publish-local

Then you'll have v 3.0.4 available in your local sbt repository which you can use from your project for now. I'll have a look at the pull request later to see if I can help out.

chandanpasunoori commented 8 years ago

thanks for info.. I'm done it already for my project. in plan to switch to another library for play-redis because of repo is inactive