-
Notifications
You must be signed in to change notification settings - Fork 27
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
THREESCALE-8404: Add ACL and TLS support for Redis #350
Changes from 2 commits
89fe2ef
bde5ea1
0677638
08e5a3b
be9c1e6
b99e307
f0418d7
b739462
c91b00a
c94bd27
8d8c4af
d5fd900
5e8f66c
8c28110
cdc25bb
e928e84
b7ffd43
a2ef569
a9c4dd9
d12c72d
6065bbe
cbc9fec
0972555
f53877f
a81a4e9
c429e71
73da74b
decfeb9
312179a
ad3dc2a
18a0840
fc397b7
1ff0b66
70034ab
e6d1e5d
70c95db
c8bdef8
1279b06
19dda59
048904b
a126a9b
4dc7cab
821f08c
0970789
2bc318c
e64a151
64d0f22
da556bf
f9bb6fa
40d9932
6c45bca
34dfc4f
6bbf375
7093a8c
c002ab2
578a0e2
4b6e8cf
d996c17
f0d0c53
1cc4c2c
470e9d5
1e1e257
cb28b7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
require '3scale/backend/storage_async/methods' | ||
require '3scale/backend/storage_async/client' | ||
require '3scale/backend/storage_async/pipeline' | ||
require '3scale/backend/storage_async/resque_extensions' |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,123 @@ | ||||||||||
# frozen_string_literal: true | ||||||||||
|
||||||||||
module ThreeScale | ||||||||||
module Backend | ||||||||||
module StorageAsync | ||||||||||
module Methods | ||||||||||
# Now we are going to define the methods to run redis commands | ||||||||||
# following the interface of the redis-rb lib. | ||||||||||
# | ||||||||||
# These are the different cases: | ||||||||||
# 1) Methods that can be called directly. For example SET: | ||||||||||
# @redis_async.call('SET', some_key) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Not sure if that's correct, but assuming that there is no mention of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, I copied that comment from the old file and didn't check it. |
||||||||||
# 2) Methods that need to be "boolified". These are methods for which | ||||||||||
# redis-rb returns a boolean, but redis just returns an integer. | ||||||||||
# For example, Redis returns 0 or 1 for the EXISTS command, but | ||||||||||
# redis-rb transforms that into a boolean. | ||||||||||
# 3) There are a few methods that need to be treated differently and | ||||||||||
# do not fit in any of the previous categories. For example, SSCAN | ||||||||||
# which accepts a hash of options in redis-rb. | ||||||||||
# | ||||||||||
# All of this might be simplified a bit in the future using the | ||||||||||
# "methods" in async-redis | ||||||||||
# https://github.com/socketry/async-redis/tree/master/lib/async/redis/methods | ||||||||||
# but there are some commands missing, so for now, that's not an option. | ||||||||||
|
||||||||||
METHODS_TO_BE_CALLED_DIRECTLY = [ | ||||||||||
:del, | ||||||||||
:exists, | ||||||||||
:expire, | ||||||||||
:expireat, | ||||||||||
:flushdb, | ||||||||||
:get, | ||||||||||
:hset, | ||||||||||
:hmget, | ||||||||||
:incr, | ||||||||||
:incrby, | ||||||||||
:keys, | ||||||||||
:llen, | ||||||||||
:lpop, | ||||||||||
:lpush, | ||||||||||
:lrange, | ||||||||||
:ltrim, | ||||||||||
:mget, | ||||||||||
:ping, | ||||||||||
:rpush, | ||||||||||
:sadd, | ||||||||||
:scard, | ||||||||||
:setex, | ||||||||||
:smembers, | ||||||||||
:srem, | ||||||||||
:sunion, | ||||||||||
:ttl, | ||||||||||
:zcard, | ||||||||||
:zrangebyscore, | ||||||||||
:zremrangebyscore, | ||||||||||
:zrevrange | ||||||||||
].freeze | ||||||||||
private_constant :METHODS_TO_BE_CALLED_DIRECTLY | ||||||||||
|
||||||||||
METHODS_TO_BE_CALLED_DIRECTLY.each do |method| | ||||||||||
define_method(method) do |*args| | ||||||||||
call(method, *args.flatten) | ||||||||||
end | ||||||||||
end | ||||||||||
|
||||||||||
METHODS_TO_BOOLIFY = [ | ||||||||||
:exists?, | ||||||||||
:sismember, | ||||||||||
:sadd?, | ||||||||||
:srem?, | ||||||||||
:zadd | ||||||||||
].freeze | ||||||||||
private_constant :METHODS_TO_BOOLIFY | ||||||||||
|
||||||||||
METHODS_TO_BOOLIFY.each do |method| | ||||||||||
command = method.to_s.delete('?') | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the story behind all the methods that got an extra There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, probably because of apisonator/lib/3scale/backend/storage_async/client.rb Lines 46 to 49 in 8e26728
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aisonator uses the API from the The API changed in redis-rb 5, now they addded the methods For the commands coming with an ending |
||||||||||
define_method(method) do |*args| | ||||||||||
call(command, *args.flatten) > 0 | ||||||||||
end | ||||||||||
end | ||||||||||
|
||||||||||
def blpop(*args) | ||||||||||
call_args = ['BLPOP'] + args | ||||||||||
|
||||||||||
# redis-rb accepts a Hash as last arg that can contain :timeout. | ||||||||||
if call_args.last.is_a? Hash | ||||||||||
timeout = call_args.pop[:timeout] | ||||||||||
call_args << timeout | ||||||||||
end | ||||||||||
|
||||||||||
call(*call_args.flatten) | ||||||||||
end | ||||||||||
|
||||||||||
def set(key, val, opts = {}) | ||||||||||
args = ['SET', key, val] | ||||||||||
|
||||||||||
args += ['EX', opts[:ex]] if opts[:ex] | ||||||||||
args << 'NX' if opts[:nx] | ||||||||||
|
||||||||||
call(*args) | ||||||||||
end | ||||||||||
|
||||||||||
def sscan(key, cursor, opts = {}) | ||||||||||
args = ['SSCAN', key, cursor] | ||||||||||
|
||||||||||
args += ['MATCH', opts[:match]] if opts[:match] | ||||||||||
args += ['COUNT', opts[:count]] if opts[:count] | ||||||||||
|
||||||||||
call(*args) | ||||||||||
end | ||||||||||
|
||||||||||
def scan(cursor, opts = {}) | ||||||||||
args = ['SCAN', cursor] | ||||||||||
|
||||||||||
args += ['MATCH', opts[:match]] if opts[:match] | ||||||||||
args += ['COUNT', opts[:count]] if opts[:count] | ||||||||||
|
||||||||||
call(*args) | ||||||||||
end | ||||||||||
end | ||||||||||
end | ||||||||||
end | ||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with such an approach if using proper async is not trivial. But it appears to me that
async-redis
was built to handle concurrency. So mayeb gove a little more explanation why do we need a separate client per thread?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async-redis
relies on Fibers to implement concurrency, but concurrency doesn't mean parallelism. Whatasync-redis
does, AFAIK, is to switch between fibers on IO operations, e.g. when one fiber is waiting for answer from Redis. But all Fibers run in the same Thread. In Our case, we are callingStorage.instance
from different Threads,@redis_async
was being shared between threads and that caused an errorFiber called across threads
which blocked the test.@eguzki Does this make sense to you?