File: cancellation_spec.rb

package info (click to toggle)
ruby-concurrent 1.1.6%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 30,284 kB
  • sloc: ruby: 30,875; java: 6,117; ansic: 288; makefile: 9; sh: 6
file content (91 lines) | stat: -rw-r--r-- 2,909 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
RSpec.describe 'Concurrent' do
  describe 'Cancellation', edge: true do
    specify 'basic' do
      cancellation, origin = Concurrent::Cancellation.new
      expect(cancellation.origin).to eq origin
      expect(cancellation.to_s).to match(/Cancellation.*pending/)

      futures1 = ::Array.new(2) do
        Concurrent::Promises.future(cancellation) do |c|
          loop { Thread.pass; break if c.canceled? }
          :done
        end
      end

      futures2 = ::Array.new(2) do
        Concurrent::Promises.future(cancellation) do |c|
          loop { c.check!; Thread.pass } rescue $!
        end
      end

      sleep 0.01
      origin.resolve
      expect(cancellation.to_s).to match(/Cancellation.*canceled/)

      futures1.each do |future|
        expect(future.value!).to eq :done
      end
      futures2.each do |future|
        expect(future.value!).to be_a_kind_of Concurrent::CancelledOperationError
      end
    end

    specify do
      cancellation, origin = Concurrent::Cancellation.new
      origin.resolve
      expect(cancellation.canceled?).to be_truthy

      cancellable_branch = Concurrent::Promises.delay { 1 }
      expect((cancellable_branch | origin).value).to be_nil
      expect(cancellable_branch.resolved?).to be_falsey
    end

    specify do
      _, source = Concurrent::Cancellation.new

      cancellable_branch = Concurrent::Promises.delay { 1 }
      expect(Concurrent::Promises.any_resolved_future(cancellable_branch, source).value).to eq 1
      expect(cancellable_branch.resolved?).to be_truthy
    end

    specify do
      cancellation, origin = Concurrent::Cancellation.new(Concurrent::Promises.resolvable_future)
      origin.resolve false, nil, err = StandardError.new('Cancelled')
      expect(cancellation.canceled?).to be_truthy

      cancellable_branch = Concurrent::Promises.delay { 1 }
      expect((cancellable_branch | origin.to_future).reason).to eq err
      expect(cancellable_branch.resolved?).to be_falsey
    end

    specify do
      head                 = Concurrent::Promises.resolvable_future
      cancellation, origin = Concurrent::Cancellation.new head.then(&:succ)

      futures = ::Array.new(2) do
        Concurrent::Promises.future(cancellation) do |c|
          loop { Thread.pass; break if c.canceled? }
          :done
        end
      end

      head.fulfill 1
      futures.each do |future|
        expect(future.value!).to eq :done
      end
      expect(origin.to_future.value!).to eq 2
    end

    specify '#join' do
      cancellation_a, origin_a = Concurrent::Cancellation.new
      cancellation_b, _        = Concurrent::Cancellation.new
      combined_cancellation    = cancellation_a.join(cancellation_b)

      origin_a.resolve

      expect(cancellation_a.canceled?).to be_truthy
      expect(cancellation_b.canceled?).to be_falsey
      expect(combined_cancellation.canceled?).to be_truthy
    end
  end
end