diff --git a/app/models/cluster.rb b/app/models/cluster.rb new file mode 100644 index 0000000..e4923e7 --- /dev/null +++ b/app/models/cluster.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'securerandom' + +# A collective for a tally +class Cluster + attr_reader :count, :name, :status, :uuid + @@clusters = {} + + def initialize(name) + @uuid = SecureRandom.uuid + @name = name + @count = 0 + @status = :open + @mutex = Mutex.new + @@clusters[@uuid] = self + end + + def increment(var = 1) + @mutex.synchronize do + @count += var + end + end + + def decrement(var = 1) + @mutex.synchronize do + @count -= var + end + end + + class << self + def get(uuid) + @@clusters[uuid] + end + + def list + @@clusters + end + end +end diff --git a/test/models/cluster_test.rb b/test/models/cluster_test.rb new file mode 100644 index 0000000..9b57722 --- /dev/null +++ b/test/models/cluster_test.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'test_helper' +require 'concurrent/set' + +class ClusterTest < ActiveSupport::TestCase + test 'Cluster has instance record of all cluster' do + assert_equal 0, Cluster.list.size, 'starts off empty' + Cluster.new('foo') + Cluster.new('bar') + assert_equal 2, Cluster.list.size, 'Increases as more are added' + end + + test 'cluster are addressable by the UUID' do + Cluster.new('bar') + cluster = Cluster.new('foo') + assert_equal cluster, Cluster.get(cluster.uuid) + end + + test 'works' do + cluster = Cluster.new('foo') + cluster.increment + assert_equal 1, cluster.count + cluster.decrement + assert_equal 0, cluster.count + end + + test 'is thread safe' do + cluster = Cluster.new('foo') + threads = [] + (1..500).each { |_x| threads << Thread.new { cluster.increment } } + threads.each(&:join) + + assert_equal 500, cluster.count + end +end