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

Problem in running Redis #9

Closed
samira-t opened this issue Sep 8, 2011 · 9 comments
Closed

Problem in running Redis #9

samira-t opened this issue Sep 8, 2011 · 9 comments

Comments

@samira-t
Copy link

samira-t commented Sep 8, 2011

Hi,

I am trying to run Redis. But when I use "val r = new RedisClient("localhost", 6379)" I am always getting the message"Connection refused" and "timeout". I followed all the instruction you mentioned in the web page. How can I solve the problem?

Thanks,
Samira

@derekjw
Copy link
Owner

derekjw commented Sep 8, 2011

Just to make sure, you are already running a server on localhost?

@samira-t
Copy link
Author

samira-t commented Sep 8, 2011

Thanks for the reply.

My problem is solved. I didn't run redis server.
I have some more questions from you:

  1. By implementing the client by actors, what is exactly the benefit of
    that? I think for each client, an actor would be created; so, each actor can
    only service one client at a time.
  2. The other question is regrading to your publish subscribe implementation.
    I can see one test case fro that. What is the intention of that in Redis?
    Can the publish-subscribe actor (RedisClientWorker) be a remote actor?
  3. How can I run the test cases and my own application that uses your redis
    in Eclipse? I have added the scalatest.jar and akka.jar and also
    akkatestkit.jar into the path. But still I don't know how I can run the test
    cases in Eclipse.

My last comment is that the link for the akka snapshot (
github.com/jboner/akka/tree/wip-derekjw) does not work. I had a hard time to
find which version of akka snapshot I should use and also change the
build.sbt file.

Regards,
Samira

On Thu, Sep 8, 2011 at 12:24 PM, Derek Williams <
reply@reply.github.com>wrote:

Just to make sure, you are already running a server on localhost?

Reply to this email directly or view it on GitHub:
#9 (comment)

@derekjw
Copy link
Owner

derekjw commented Sep 8, 2011

  1. The benefit of implementing the client with actors is due to redis supporting pipelining of requests and it also makes the client thread safe. What this means is that internally the client can keep on sending requests to the server without having to wait for any previous responses to be received. For almost all uses of Redis this lets you use just a single client to connect to the server, even in a highly concurrent program like a web app. The only cases where a separate client is needed is when using the 'watch' command, or any redis command that blocks (like making a pubsub subscriber or using a command like 'blpop'). Even if you are using the client synchronously (using the 'sync' method) the client actor itself is not blocked, only the current thread is.

  2. pubsub in redis is a bit different then the rest of the server since it doesn't actually persist or retreive any data, it is only used for communicating between clients. Any client can connect to the server, local or remote, and either publish to a channel or subscribe to a channel. The publishers/subscribers are not limited to this client, any client can be used. So it can be used to communicate to an actor that is on a remote machine, but this does not use Akka's remote capabilities.

  3. I don't use Eclipse, but your best bet is to try this: https://github.com/typesafehub/sbteclipse

I made quite a bit of changes in the last couple months, and I haven't been doing a great job of keeping the documentation up to date. Having said that, your best bet is to use the 'akka-1.2' branch since it will use the latest RC release of Akka 1.2 (and the final 1.2 when it is released). I also publish snapshots (and later, releases) at http://repo.fyrie.net/ which can be used as dependencies in your own projects.

I hope that helps, and thanks for the feedback! I'm closing this issue, but feel free to send me any other questions you might have.

@derekjw derekjw closed this as completed Sep 8, 2011
@samira-t
Copy link
Author

samira-t commented Sep 8, 2011

Hi Derek,

Thanks for the responses.

  1. The benefit of implementing the client with actors is due to redis

supporting pipelining of requests and it also makes the client thread safe.
What this means is that internally the client can keep on sending requests
to the server without having to wait for any previous responses to be
received. For almost all uses of Redis this lets you use just a single
client to connect to the server, even in a highly concurrent program like a
web app. The only cases where a separate client is needed is when using the
'watch' command, or any redis command that blocks (like making a pubsub
subscriber or using a command like 'blpop'). Even if you are using the
client synchronously (using the 'sync' method) the client actor itself is
not blocked, only the current thread is.

Since all the clients in the same machine use the same socket, if there are
multiple clients, when the response is received (in the socket) how the
actors know which response is for which client?

  1. pubsub in redis is a bit different then the rest of the server since it
    doesn't actually persist or retreive any data, it is only used for
    communicating between clients. Any client can connect to the server, local
    or remote, and either publish to a channel or subscribe to a channel. The
    publishers/subscribers are not limited to this client, any client can be
    used. So it can be used to communicate to an actor that is on a remote
    machine, but this does not use Akka's remote capabilities.

Is that a part of services that redis-server provides?

  1. I don't use Eclipse, but your best bet is to try this:
    https://github.com/typesafehub/sbteclipse

I made quite a bit of changes in the last couple months, and I haven't been
doing a great job of keeping the documentation up to date. Having said that,
your best bet is to use the 'akka-1.2' branch since it will use the latest
RC release of Akka 1.2 (and the final 1.2 when it is released). I also
publish snapshots (and later, releases) at http://repo.fyrie.net/ which
can be used as dependencies in your own projects.

The latest version didn't work. I used the snapshot 2.0-20110817-000155 and
it worked. Not all of the test cases also passed. I'll give you more details
about the failed test cases.

Thanks again. I'll be in touch with you.

Regards,
Samira

@derekjw
Copy link
Owner

derekjw commented Sep 8, 2011

  1. Each client uses a different socket. The only thing shared between the clients (at least by default) is the IOManager, which is another actor that manages the actual NIO sockets and selector. If you meant 'what happens when multiple threads use the same client' each individual request is kept separate due to the responses being received in the same order as the requests were made.

  2. Yes, see: http://redis.io/topics/pubsub

  3. The Akka 2.0 api is currently unstable, but I try to sync up with the changes when I get the chance. There was a breaking change earlier today but it should all work now. But due to these rapid changes I highly recommend the 'akka-1.2' or 'akka-1.1' branch (I just recently backported the changes in master to 'akka-1.1' so everything is up to date'.

@samira-t
Copy link
Author

samira-t commented Sep 8, 2011

  1. Each client uses a different socket. The only thing shared between the
    clients (at least by default) is the IOManager, which is another actor that
    manages the actual NIO sockets and selector. If you meant 'what happens when
    multiple threads use the same client' each individual request is kept
    separate due to the responses being received in the same order as the
    requests were made.

Then you should keep track of requests that have been sent. If multiple
threads use the same client, then which thread (actor) should receive the
response? all of them?

@derekjw
Copy link
Owner

derekjw commented Sep 8, 2011

2 actors are used per client. One is for sending requests, the other is for receiving responses. Each one processes it's messages sequentially (well, mostly. the receiver 'suspends' the message it is working on if it needs to wait for more data to be read).

As of right now all responses are returned using futures, which is how the response ends up in the right place.

The only exception to this is PubSub, which is implemented by sending responses with actors. A PubSub subscriber is created with the 'RedisClient.subscriber(listener: ActorRef): ActorRef' method, which takes a user created ActorRef (like the one created in the PubSub test) and returns a client that only handles PubSub messages for that actor. If multiple listener actors are required, they each get a separate subscriber redis client. Usually only a single listener is actually required since mutiple channels can be subscribed to by a single client. From there it can send the received messages to the appropriate actor for actual processing.

@samira-t
Copy link
Author

samira-t commented Sep 9, 2011

2 actors are used per client. One is for sending requests, the other is for
receiving responses. Each one processes it's messages sequentially (well,
mostly. the receiver 'suspends' the message it is working on if it needs to
wait for more data to be read).

As of right now all responses are returned using futures, which is how the
response ends up in the right place.

And each client has a separate socket. So, they cannot share the same socket
(the requester writes into that and the receiver reads from that). What is
the role of IO actor? I think there is just one instance of that in the
application.

Regards,
Samira

@derekjw
Copy link
Owner

derekjw commented Sep 9, 2011

The IO stuff is all meant to be a simple NIO abstraction for use in Akka. It will be included in Akka 2.0, but I've included it with the fyrie-redis code for versions 1.2 and 1.1 since it works without issues.

The IO actor trait provides a simple api for an actor to read data in chunks. It uses Scala's delimited continuations plugin to turn imperative looking code into CPS style code. For example (taken from RedisClientWorker):

  def readBulk = {
    val length = socket read EOL
    matchC(length.utf8String.toInt) {
      case -1  RedisBulk.notfound
      case 0   RedisBulk.empty
      case n 
        val bytes = socket read n
        socket read EOL
        RedisBulk(Some(bytes))
    }
  }

socket read EOL returns a continuation that will only be run once the EOL bytes (\r\n) have been read. It looks like a blocking IO command, but actually isn't. Further down there is socket read n which returns a continuation that only gets run once n number of bytes are available to be read. This makes the code look like typical blocking IO, but it is actually non blocking.

The IO actor trait is not needed and this could all be done manually of course. Only the read method needs the IO trait to be used, the other methods like connect and write can be used from any actor (like the RedisClientSession actor). Also, the above socket is not the actual socket, it is just a case class that holds a reference to the ActorRef that should receive the messages and the NIO Channel that is used for the socket. This means that only immutable messages are sent between the IOManager and the actor.

The IOManager is the actor that creates and sends messages to the NIO selector thread that does the actual IO. Only 1 IOManager is required for an application, depending on if the selector can handle the load on it or not. I haven't delved too deeply into those types of issues yet and there doesn't seem to be much info out there about those issues other then it being dependent on the underlying operating system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants