stefanwille / crystal-redis

Full featured Redis client for Crystal
MIT License
380 stars 61 forks source link

Unhandled exception in spawn - multiple coroutines access the same Redis object #37

Closed z64 closed 7 years ago

z64 commented 7 years ago

Hi! I'm looking to understand why this is occurring in the following code, and how to handle it.

I have the issue of generating an ID with INCR and immediately using it to SET. My app receives packets from a websocket connection and I'm caching them for potentially multiple clients to replay, so I'm just using this to ensure a sortable ID that clients can request.

require "redis"

redis = Redis.new

redis.select 3

1000.times do
  spawn do
    id = redis.incr "test"
    redis.set "test:#{id}", "OK"
  end
end

sleep

Produces:

Unhandled exception in spawn:
cast from Int64 to (String | Nil) failed, at /home/lune/git/redis-gateway/lib/redis/src/redis/command_execution/value_oriented.cr:37 (TypeCastError)
0x46713e: *Redis at /home/lune/git/redis-gateway/lib/redis/src/redis/command_execution/value_oriented.cr 37:9
0x467042: *Redis at /home/lune/git/redis-gateway/lib/redis/src/redis/commands.cr 54:7
0x466f75: *Redis at /home/lune/git/redis-gateway/lib/redis/src/redis/commands.cr 47:5
0x442e8e: *Fiber#run:(IO::FileDescriptor | Nil) at /usr/lib/crystal/fiber.cr 114:3
0x4376b6: ~proc2Proc(Fiber, (IO::FileDescriptor | Nil)) at /usr/lib/crystal/concurrent.cr 60:3
0x0: ??? at ??

Is there something else I should be using to facilitate this pattern, or is there something else afoot?

z64 commented 7 years ago

Upon reading closed issues, it would seem the following hadn't made it's way into the docs, as the example provided in https://github.com/stefanwille/crystal-redis/issues/8#issuecomment-158613225 seems to have fixed my use case.

The code shares one socket across multiple threads, and that can't work. Each thread must have it's own tcp connection to Redis.

As shown in the snippet, instancing a new connection in the event thread appears to work.

stefanwille commented 7 years ago

Hi Zac, this is documented here: https://github.com/stefanwille/crystal-redis/blob/master/src/redis.cr#L31-L34

z64 commented 7 years ago

Apologies - Not sure how I missed that!

Thank you.

stefanwille commented 7 years ago

No problem :)

stefanwille commented 7 years ago

I have renamed the issue in case somebody else with the same problem searches the issue list.

kostya commented 7 years ago

try: https://github.com/kostya/redisoid