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

use Redis::PooledClient instead of own pool implementation #16

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,11 @@ The engine comes with a number of configuration options:
| database | which database to use when after connecting to redis. defaults to 0 |
| capacity | how many connections the connection pool should create. defaults to 20 |
| timeout | how long until a connection is considered long-running. defaults to 2.0 (seconds) |
| pool | an instance of `ConnectionPool(Redis)`. This overrides any setting in host or unixsocket |
| key_prefix | when saving sessions to redis, how should the keys be namespaced. defaults to `kemal:session:` |

When the Redis engine is instantiated and a connection pool isn't passed,
RedisEngine will create a connection pool for you. The pool will have 20 connections
and a timeout of 2 seconds. It's recommended that a connection pool be created
to serve the wider application and then that passed to the RedisEngine initializer.
When the Redis engine is instantiated,
`RedisEngine` will create a connection pool for you. The pool will have 20 connections
and a timeout of 2 seconds.

If no options are passed the `RedisEngine` will try to connect to a Redis using
default settings.
Expand Down
3 changes: 0 additions & 3 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ dependencies:
kemal-session:
github: kemalcr/kemal-session
version: ~> 1.0
pool:
github: ysbaddaden/pool
version: 0.2.3
redis:
github: stefanwille/crystal-redis
version: ~> 2.8.3
Expand Down
8 changes: 0 additions & 8 deletions spec/kemal-session-redis_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ describe "Kemal::Session::RedisEngine" do
redis = Kemal::Session::RedisEngine.new
redis.should_not be_nil
end

it "can be set up with a connection pool" do
pool = ConnectionPool.new(capacity: 1, timeout: 2.0) do
Redis.new
end
redis = Kemal::Session::RedisEngine.new(pool: pool)
redis.should_not be_nil
end
end

describe ".int" do
Expand Down
103 changes: 43 additions & 60 deletions src/kemal-session-redis.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require "uri"
require "json"
require "redis"
require "pool/connection"
require "kemal-session"

module Kemal
Expand Down Expand Up @@ -36,35 +35,29 @@ module Kemal
end

define_storage({
int: Int32,
int: Int32,
bigint: Int64,
string: String,
float: Float64,
bool: Bool,
object: Kemal::Session::StorableObject::StorableObjectContainer
float: Float64,
bool: Bool,
object: Kemal::Session::StorableObject::StorableObjectContainer,
})
end

@redis : ConnectionPool(Redis)
@redis : Redis::PooledClient
@cache : StorageInstance
@cached_session_id : String

def initialize(host = "localhost", port = 6379, password = nil, database = 0, capacity = 20, timeout = 2.0, unixsocket = nil, pool = nil, key_prefix = "kemal:session:")
@redis = uninitialized ConnectionPool(Redis)

if pool.nil?
@redis = ConnectionPool.new(capacity: capacity, timeout: timeout) do
Redis.new(
host: host,
port: port,
database: database,
unixsocket: unixsocket,
password: password
)
end
else
@redis = pool.as(ConnectionPool(Redis))
end
def initialize(host = "localhost", port = 6379, password = nil, database = 0, capacity = 20, timeout = 2.0, unixsocket = nil, key_prefix = "kemal:session:")
Copy link
Owner

Choose a reason for hiding this comment

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

I see you removed pool as an argument. My only piece of feedback is if someone wants to use a shared pool client across their entire application, they won't be able to pass that in.

What are your thoughts about adding that back in?

@redis = Redis::PooledClient.new(
host: host,
port: port,
database: database,
unixsocket: unixsocket,
password: password,
pool_size: capacity,
pool_timeout: timeout
)

@cache = Kemal::Session::RedisEngine::StorageInstance.new
@key_prefix = key_prefix
Expand All @@ -89,69 +82,60 @@ module Kemal

def load_into_cache(session_id)
@cached_session_id = session_id
conn = @redis.checkout
value = conn.get(prefix_session(session_id))
if !value.nil?
@cache = Kemal::Session::RedisEngine::StorageInstance.from_json(value)
else
value = @redis.get(prefix_session(session_id))

if value.nil?
@cache = StorageInstance.new
conn.set(

@redis.set(
prefix_session(session_id),
@cache.to_json,
ex: Kemal::Session.config.timeout.total_seconds.to_i
)
else
@cache = StorageInstance.from_json(value)
end
@redis.checkin(conn)
return @cache

@cache
end

def save_cache
conn = @redis.checkout
conn.set(
@redis.set(
prefix_session(@cached_session_id),
@cache.to_json,
ex: Kemal::Session.config.timeout.total_seconds.to_i
)
@redis.checkin(conn)
end

def is_in_cache?(session_id)
return session_id == @cached_session_id
session_id == @cached_session_id
end

def create_session(session_id : String)
load_into_cache(session_id)
end

def get_session(session_id : String) : (Kemal::Session | Nil)
conn = @redis.checkout
value = conn.get(prefix_session(session_id))
@redis.checkin(conn)
def get_session(session_id : String) : Session?
value = @redis.get(prefix_session(session_id))

return Kemal::Session.new(session_id) if value
nil
value ? Kemal::Session.new(session_id) : nil
end

def destroy_session(session_id : String)
conn = @redis.checkout
conn.del(prefix_session(session_id))
@redis.checkin(conn)
@redis.del(prefix_session(session_id))
end

def destroy_all_sessions
conn = @redis.checkout

cursor = 0

loop do
cursor, keys = conn.scan(cursor, "#{@key_prefix}*")
cursor, keys = @redis.scan(cursor, "#{@key_prefix}*")
keys = keys.as(Array(Redis::RedisValue)).map(&.to_s)
keys.each do |key|
conn.del(key)
end

keys.each { |key| @redis.del(key) }

break if cursor == "0"
end

@redis.checkin(conn)
end

def all_sessions : Array(Kemal::Session)
Expand All @@ -161,23 +145,22 @@ module Kemal
arr << session
end

return arr
arr
end

def each_session
conn = @redis.checkout

cursor = 0

loop do
cursor, keys = conn.scan(cursor, "#{@key_prefix}*")
cursor, keys = @redis.scan(cursor, "#{@key_prefix}*")
keys = keys.as(Array(Redis::RedisValue)).map(&.to_s)

keys.each do |key|
yield Kemal::Session.new(parse_session_id(key.as(String)))
end

break if cursor == "0"
end

@redis.checkin(conn)
end

macro define_delegators(vars)
Expand Down Expand Up @@ -206,11 +189,11 @@ module Kemal
end

define_delegators({
int: Int32,
int: Int32,
bigint: Int64,
string: String,
float: Float64,
bool: Bool,
float: Float64,
bool: Bool,
object: Kemal::Session::StorableObject::StorableObjectContainer,
})
end
Expand Down