As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects
Unverified Commit d1c01fe8 authored by Nick Thomas's avatar Nick Thomas
Browse files

Remove direct redis integration

parent 73e2cf53
No related branches found
No related tags found
No related merge requests found
class Redis
unless defined?(::BasicObject)
class BasicObject
instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A(__|instance_eval)/ }
end
end
class Pipeline
attr_accessor :db
attr :futures
def initialize
@with_reconnect = true
@shutdown = false
@futures = []
end
def with_reconnect?
@with_reconnect
end
def without_reconnect?
!@with_reconnect
end
def shutdown?
@shutdown
end
def call(command, &block)
# A pipeline that contains a shutdown should not raise ECONNRESET when
# the connection is gone.
@shutdown = true if command.first == :shutdown
future = Future.new(command, block)
@futures << future
future
end
def call_pipeline(pipeline)
@shutdown = true if pipeline.shutdown?
@futures.concat(pipeline.futures)
@db = pipeline.db
nil
end
def commands
@futures.map { |f| f._command }
end
def with_reconnect(val=true)
@with_reconnect = false unless val
yield
end
def without_reconnect(&blk)
with_reconnect(false, &blk)
end
def finish(replies, &blk)
if blk
futures.each_with_index.map do |future, i|
future._set(blk.call(replies[i]))
end
else
futures.each_with_index.map do |future, i|
future._set(replies[i])
end
end
end
class Multi < self
def finish(replies)
exec = replies.last
return if exec.nil? # The transaction failed because of WATCH.
# EXEC command failed.
raise exec if exec.is_a?(CommandError)
if exec.size < futures.size
# Some command wasn't recognized by Redis.
raise replies.detect { |r| r.is_a?(CommandError) }
end
super(exec) do |reply|
# Because an EXEC returns nested replies, hiredis won't be able to
# convert an error reply to a CommandError instance itself. This is
# specific to MULTI/EXEC, so we solve this here.
reply.is_a?(::RuntimeError) ? CommandError.new(reply.message) : reply
end
end
def commands
[[:multi]] + super + [[:exec]]
end
end
end
class FutureNotReady < RuntimeError
def initialize
super("Value will be available once the pipeline executes.")
end
end
class Future < BasicObject
FutureNotReady = ::Redis::FutureNotReady.new
def initialize(command, transformation)
@command = command
@transformation = transformation
@object = FutureNotReady
end
def inspect
"<Redis::Future #{@command.inspect}>"
end
def _set(object)
@object = @transformation ? @transformation.call(object) : object
value
end
def _command
@command
end
def value
::Kernel.raise(@object) if @object.kind_of?(::RuntimeError)
@object
end
def is_a?(other)
self.class.ancestors.include?(other)
end
def class
Future
end
end
end
class Redis
class SubscribedClient
def initialize(client)
@client = client
end
def call(command)
@client.process([command])
end
def subscribe(*channels, &block)
subscription("subscribe", "unsubscribe", channels, block)
end
def subscribe_with_timeout(timeout, *channels, &block)
subscription("subscribe", "unsubscribe", channels, block, timeout)
end
def psubscribe(*channels, &block)
subscription("psubscribe", "punsubscribe", channels, block)
end
def psubscribe_with_timeout(timeout, *channels, &block)
subscription("psubscribe", "punsubscribe", channels, block, timeout)
end
def unsubscribe(*channels)
call([:unsubscribe, *channels])
end
def punsubscribe(*channels)
call([:punsubscribe, *channels])
end
protected
def subscription(start, stop, channels, block, timeout = 0)
sub = Subscription.new(&block)
unsubscribed = false
begin
@client.call_loop([start, *channels], timeout) do |line|
type, *rest = line
sub.callbacks[type].call(*rest)
unsubscribed = type == stop && rest.last == 0
break if unsubscribed
end
ensure
# No need to unsubscribe here. The real client closes the connection
# whenever an exception is raised (see #ensure_connected).
end
end
end
class Subscription
attr :callbacks
def initialize
@callbacks = Hash.new do |hash, key|
hash[key] = lambda { |*_| }
end
yield(self)
end
def subscribe(&block)
@callbacks["subscribe"] = block
end
def unsubscribe(&block)
@callbacks["unsubscribe"] = block
end
def message(&block)
@callbacks["message"] = block
end
def psubscribe(&block)
@callbacks["psubscribe"] = block
end
def punsubscribe(&block)
@callbacks["punsubscribe"] = block
end
def pmessage(&block)
@callbacks["pmessage"] = block
end
end
end
class Redis
VERSION = "3.3.3"
end
redis:
host: 127.0.1.1
port: 6378
pass: secure
database: 1
socket: /var/run/redis/redis.sock
namespace: my:gitlab
sentinels:
-
host: 127.0.0.1
port: 26380
Loading
Loading
@@ -4,21 +4,6 @@ require_relative '../lib/gitlab_config'
describe GitlabConfig do
let(:config) { GitlabConfig.new }
describe :redis do
before do
config_file = File.read('spec/fixtures/gitlab_config_redis.yml')
config.instance_variable_set(:@config, YAML.load(config_file))
end
it { config.redis['host'].should eq('127.0.1.1') }
it { config.redis['port'].should eq(6378) }
it { config.redis['database'].should eq(1) }
it { config.redis['namespace'].should eq('my:gitlab') }
it { config.redis['socket'].should eq('/var/run/redis/redis.sock') }
it { config.redis['pass'].should eq('secure') }
it { config.redis['sentinels'].should eq([{ 'host' => '127.0.0.1', 'port' => 26380 }]) }
end
describe :gitlab_url do
let(:url) { 'http://test.com' }
subject { config.gitlab_url }
Loading
Loading
Loading
Loading
@@ -434,60 +434,4 @@ describe GitlabNet, vcr: true do
store.should_receive(:add_path).with('test_path')
end
end
describe '#redis_client' do
let(:config) { double('config') }
context "with empty redis config" do
it 'returns default parameters' do
allow(gitlab_net).to receive(:config).and_return(config)
allow(config).to receive(:redis).and_return( {} )
expect_any_instance_of(Redis).to receive(:initialize).with({ host: '127.0.0.1',
port: 6379,
db: 0 })
gitlab_net.redis_client
end
end
context "with password" do
it 'uses the specified host, port, and password' do
allow(gitlab_net).to receive(:config).and_return(config)
allow(config).to receive(:redis).and_return( { 'host' => 'localhost', 'port' => 1123, 'pass' => 'secret' } )
expect_any_instance_of(Redis).to receive(:initialize).with({ host: 'localhost',
port: 1123,
db: 0,
password: 'secret'})
gitlab_net.redis_client
end
end
context "with sentinels" do
it 'uses the specified sentinels' do
allow(gitlab_net).to receive(:config).and_return(config)
allow(config).to receive(:redis).and_return({ 'host' => 'localhost', 'port' => 1123,
'sentinels' => [{'host' => '127.0.0.1', 'port' => 26380}] })
expect_any_instance_of(Redis).to receive(:initialize).with({ host: 'localhost',
port: 1123,
db: 0,
sentinels: [{host: '127.0.0.1', port: 26380}] })
gitlab_net.redis_client
end
end
context "with redis socket" do
let(:socket) { '/tmp/redis.socket' }
it 'uses the socket' do
allow(gitlab_net).to receive(:config).and_return(config)
allow(config).to receive(:redis).and_return( { 'socket' => socket })
expect_any_instance_of(Redis).to receive(:initialize).with({ path: socket, db: 0 })
gitlab_net.redis_client
end
end
end
end
This diff is collapsed.
# coding: utf-8
require 'spec_helper'
require 'gitlab_reference_counter'
describe GitlabReferenceCounter do
let(:redis_client) { double('redis_client') }
let(:reference_counter_key) { "git-receive-pack-reference-counter:/test/path" }
let(:gitlab_reference_counter) { GitlabReferenceCounter.new('/test/path') }
before do
allow(gitlab_reference_counter).to receive(:redis_client).and_return(redis_client)
$logger = double('logger').as_null_object
end
it 'increases and set the expire time of a reference count for a path' do
expect(redis_client).to receive(:incr).with(reference_counter_key)
expect(redis_client).to receive(:expire).with(reference_counter_key, GitlabReferenceCounter::REFERENCE_EXPIRE_TIME)
expect(gitlab_reference_counter.increase).to be(true)
end
it 'decreases the reference count for a path' do
allow(redis_client).to receive(:decr).and_return(0)
expect(redis_client).to receive(:decr).with(reference_counter_key)
expect(gitlab_reference_counter.decrease).to be(true)
end
it 'warns if attempting to decrease a counter with a value of one or less, and resets the counter' do
expect(redis_client).to receive(:decr).and_return(-1)
expect(redis_client).to receive(:del)
expect($logger).to receive(:warn).with("Reference counter for /test/path decreased when its value was less than 1. Reseting the counter.")
expect(gitlab_reference_counter.decrease).to be(true)
end
it 'get the reference count for a path' do
allow(redis_client).to receive(:get).and_return(1)
expect(gitlab_reference_counter.value).to be(1)
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment