Module: Sus::Fixtures::Async::SchedulerContext

Defined in:
lib/sus/fixtures/async/scheduler_context.rb

Instance Method Summary collapse

Instance Method Details

#around(&block) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/sus/fixtures/async/scheduler_context.rb', line 66

def around(&block)
	Sync do |task|
		task.annotate(self.class)
		
		run_with_timeout(self.timeout) do
			# This ensures all before/after blocks are also run in the scheduler context.
			super(&block)
		end
	end
end

#run_with_timeout(timeout = nil, &block) ⇒ Object



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
# File 'lib/sus/fixtures/async/scheduler_context.rb', line 11

def run_with_timeout(timeout = nil, &block)
	task = ::Async::Task.current
	
	result = nil
	timer_task = nil
	
	if timeout
		timer_task = task.async(transient: true) do |task|
			# Wait for the timeout, at any point this task might be cancelled if the user code completes:
			task.annotate("Timer task timeout=#{timeout}.")
			task.sleep(timeout)
			
			# The timeout expired, so generate an error:
			buffer = StringIO.new
			scheduler.print_hierarchy(buffer)
			
			# Raise an error so it is logged:
			raise Async::TimeoutError, "Run time exceeded timeout #{timeout}s:\n#{buffer.string}"
		end
	end
	
	spec_task = task.async do |spec_task|
		spec_task.annotate("running example")
		
		begin
			result = yield(spec_task)
		ensure
			# We are finished, so stop the timer task if it was started:
			timer_task&.stop
		end
		
		# Now stop the scheduler:
		raise Async::Stop
	end
	
	begin
		timer_task&.wait
		spec_task.wait
	ensure
		spec_task.stop
	end
	
	return result
end

#schedulerObject Also known as: reactor



60
61
62
# File 'lib/sus/fixtures/async/scheduler_context.rb', line 60

def scheduler
	Fiber.scheduler
end

#timeoutObject



56
57
58
# File 'lib/sus/fixtures/async/scheduler_context.rb', line 56

def timeout
	60
end