File: concurrent_increment.rb

package info (click to toggle)
ruby-moneta 1.6.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,776 kB
  • sloc: ruby: 13,201; sh: 178; makefile: 7
file content (39 lines) | stat: -rw-r--r-- 1,195 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
shared_examples :concurrent_increment do
  def increment_thread(name)
    Thread.new do
      s = new_store
      begin
        # Create an array where each entry is a list of all the return values
        # from calling increment for a particular key.
        increments = (0...100).map { [] }
        100.times do
          100.times do |j|
            increments[j] << s.increment(j.to_s, 1, expires: false)
            Thread.pass if rand(1000) >= 995
          end
        end
        increments
      ensure
        s.close
      end
    end
  end

  it 'have atomic increment across multiple threads', isolate: true do
    results = %w{a b c}
      .map { |name| increment_thread(name) }
      .map(&:value)
      .transpose # Now the array is indexed by store key instead of thread

    # Sanity check
    expect(results.length).to eq 100

    results.each do |ith_values|
      # ensure that for each pair in the triple there are no overlapping values
      expect(ith_values.combination(2).map { |a, b| a & b }).to all be_empty

      # ensure that when joined together they cover the full 1..300 range
      expect(ith_values.inject(:+)).to contain_exactly(*1..300)
    end
  end
end