Commit e6729f5f authored by Bob Van Landuyt's avatar Bob Van Landuyt

Make setting attributes on a class reusable

We were already using this for workers, but we'll need it for
controllers as well.
parent 70fdf061
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
module WorkerAttributes module WorkerAttributes
extend ActiveSupport::Concern extend ActiveSupport::Concern
include Gitlab::ClassAttributes
# Resource boundaries that workers can declare through the # Resource boundaries that workers can declare through the
# `resource_boundary` attribute # `resource_boundary` attribute
...@@ -30,24 +31,24 @@ module WorkerAttributes ...@@ -30,24 +31,24 @@ module WorkerAttributes
}.stringify_keys.freeze }.stringify_keys.freeze
class_methods do class_methods do
def feature_category(value) def feature_category(value, *extras)
raise "Invalid category. Use `feature_category_not_owned!` to mark a worker as not owned" if value == :not_owned raise "Invalid category. Use `feature_category_not_owned!` to mark a worker as not owned" if value == :not_owned
worker_attributes[:feature_category] = value class_attributes[:feature_category] = value
end end
# Special case: mark this work as not associated with a feature category # Special case: mark this work as not associated with a feature category
# this should be used for cross-cutting concerns, such as mailer workers. # this should be used for cross-cutting concerns, such as mailer workers.
def feature_category_not_owned! def feature_category_not_owned!
worker_attributes[:feature_category] = :not_owned class_attributes[:feature_category] = :not_owned
end end
def get_feature_category def get_feature_category
get_worker_attribute(:feature_category) get_class_attribute(:feature_category)
end end
def feature_category_not_owned? def feature_category_not_owned?
get_worker_attribute(:feature_category) == :not_owned get_feature_category == :not_owned
end end
# This should be set to :high for jobs that need to be run # This should be set to :high for jobs that need to be run
...@@ -61,11 +62,11 @@ module WorkerAttributes ...@@ -61,11 +62,11 @@ module WorkerAttributes
def urgency(urgency) def urgency(urgency)
raise "Invalid urgency: #{urgency}" unless VALID_URGENCIES.include?(urgency) raise "Invalid urgency: #{urgency}" unless VALID_URGENCIES.include?(urgency)
worker_attributes[:urgency] = urgency class_attributes[:urgency] = urgency
end end
def get_urgency def get_urgency
worker_attributes[:urgency] || :low class_attributes[:urgency] || :low
end end
# Set this attribute on a job when it will call to services outside of the # Set this attribute on a job when it will call to services outside of the
...@@ -73,85 +74,64 @@ module WorkerAttributes ...@@ -73,85 +74,64 @@ module WorkerAttributes
# doc/development/sidekiq_style_guide.md#Jobs-with-External-Dependencies for # doc/development/sidekiq_style_guide.md#Jobs-with-External-Dependencies for
# details # details
def worker_has_external_dependencies! def worker_has_external_dependencies!
worker_attributes[:external_dependencies] = true class_attributes[:external_dependencies] = true
end end
# Returns a truthy value if the worker has external dependencies. # Returns a truthy value if the worker has external dependencies.
# See doc/development/sidekiq_style_guide.md#Jobs-with-External-Dependencies # See doc/development/sidekiq_style_guide.md#Jobs-with-External-Dependencies
# for details # for details
def worker_has_external_dependencies? def worker_has_external_dependencies?
worker_attributes[:external_dependencies] class_attributes[:external_dependencies]
end end
def worker_resource_boundary(boundary) def worker_resource_boundary(boundary)
raise "Invalid boundary" unless VALID_RESOURCE_BOUNDARIES.include? boundary raise "Invalid boundary" unless VALID_RESOURCE_BOUNDARIES.include? boundary
worker_attributes[:resource_boundary] = boundary class_attributes[:resource_boundary] = boundary
end end
def get_worker_resource_boundary def get_worker_resource_boundary
worker_attributes[:resource_boundary] || :unknown class_attributes[:resource_boundary] || :unknown
end end
def idempotent! def idempotent!
worker_attributes[:idempotent] = true class_attributes[:idempotent] = true
end end
def idempotent? def idempotent?
worker_attributes[:idempotent] class_attributes[:idempotent]
end end
def weight(value) def weight(value)
worker_attributes[:weight] = value class_attributes[:weight] = value
end end
def get_weight def get_weight
worker_attributes[:weight] || class_attributes[:weight] ||
NAMESPACE_WEIGHTS[queue_namespace] || NAMESPACE_WEIGHTS[queue_namespace] ||
1 1
end end
def tags(*values) def tags(*values)
worker_attributes[:tags] = values class_attributes[:tags] = values
end end
def get_tags def get_tags
Array(worker_attributes[:tags]) Array(class_attributes[:tags])
end end
def deduplicate(strategy, options = {}) def deduplicate(strategy, options = {})
worker_attributes[:deduplication_strategy] = strategy class_attributes[:deduplication_strategy] = strategy
worker_attributes[:deduplication_options] = options class_attributes[:deduplication_options] = options
end end
def get_deduplicate_strategy def get_deduplicate_strategy
worker_attributes[:deduplication_strategy] || class_attributes[:deduplication_strategy] ||
Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DEFAULT_STRATEGY Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DEFAULT_STRATEGY
end end
def get_deduplication_options def get_deduplication_options
worker_attributes[:deduplication_options] || {} class_attributes[:deduplication_options] || {}
end
protected
# Returns a worker attribute declared on this class or its parent class.
# This approach allows declared attributes to be inherited by
# child classes.
def get_worker_attribute(name)
worker_attributes[name] || superclass_worker_attributes(name)
end
private
def worker_attributes
@attributes ||= {}
end
def superclass_worker_attributes(name)
return unless superclass.include? WorkerAttributes
superclass.get_worker_attribute(name)
end end
end end
end end
# frozen_string_literal: true
module Gitlab
module ClassAttributes
extend ActiveSupport::Concern
class_methods do
protected
# Returns an attribute declared on this class or its parent class.
# This approach allows declared attributes to be inherited by
# child classes.
def get_class_attribute(name)
class_attributes[name] || superclass_attributes(name)
end
private
def class_attributes
@class_attributes ||= {}
end
def superclass_attributes(name)
return unless superclass.include? Gitlab::ClassAttributes
superclass.get_class_attribute(name)
end
end
end
end
# frozen_string_literal: true
require 'fast_spec_helper'
RSpec.describe Gitlab::ClassAttributes do
let(:klass) do
Class.new do
include Gitlab::ClassAttributes
def self.get_attribute(name)
get_class_attribute(name)
end
def self.set_attribute(name, value)
class_attributes[name] = value
end
end
end
let(:subclass) { Class.new(klass) }
describe ".get_class_attribute" do
it "returns values set on the class" do
klass.set_attribute(:foo, :bar)
expect(klass.get_attribute(:foo)).to eq(:bar)
end
it "returns values set on a superclass" do
klass.set_attribute(:foo, :bar)
expect(subclass.get_attribute(:foo)).to eq(:bar)
end
it "returns values from the subclass over attributes from a superclass" do
klass.set_attribute(:foo, :baz)
subclass.set_attribute(:foo, :bar)
expect(subclass.get_attribute(:foo)).to eq(:bar)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment