Class: Async::HTTP::Protocol::HTTP2::Output

Inherits:
Object
  • Object
show all
Defined in:
lib/async/http/protocol/http2/output.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream, body, trailer = nil) ⇒ Output

Returns a new instance of Output.



13
14
15
16
17
18
19
20
21
22
# File 'lib/async/http/protocol/http2/output.rb', line 13

def initialize(stream, body, trailer = nil)
	@stream = stream
	@body = body
	@trailer = trailer
	
	@task = nil
	
	@guard = ::Mutex.new
	@window_updated = ::ConditionVariable.new
end

Instance Attribute Details

#trailerObject (readonly)

Returns the value of attribute trailer.



24
25
26
# File 'lib/async/http/protocol/http2/output.rb', line 24

def trailer
  @trailer
end

Instance Method Details

#close(error = nil) ⇒ Object

This method should only be called from within the context of the output task.



71
72
73
74
# File 'lib/async/http/protocol/http2/output.rb', line 71

def close(error = nil)
	close_write(error)
	stop(error)
end

#close_write(error = nil) ⇒ Object



63
64
65
66
67
68
# File 'lib/async/http/protocol/http2/output.rb', line 63

def close_write(error = nil)
	if stream = @stream
		@stream = nil
		stream.finish_output(error)
	end
end

#start(parent: Task.current) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/async/http/protocol/http2/output.rb', line 26

def start(parent: Task.current)
	raise "Task already started!" if @task
	
	if @body.stream?
		@task = parent.async(&self.method(:stream))
	else
		@task = parent.async(&self.method(:passthrough))
	end
end

#stop(error) ⇒ Object

This method should only be called from within the context of the HTTP/2 stream.



77
78
79
80
81
82
# File 'lib/async/http/protocol/http2/output.rb', line 77

def stop(error)
	if task = @task
		@task = nil
		task.stop(error)
	end
end

#window_updated(size) ⇒ Object



36
37
38
39
40
# File 'lib/async/http/protocol/http2/output.rb', line 36

def window_updated(size)
	@guard.synchronize do
		@window_updated.signal
	end
end

#write(chunk) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/async/http/protocol/http2/output.rb', line 42

def write(chunk)
	until chunk.empty?
		maximum_size = @stream.available_frame_size
		
		# We try to avoid synchronization if possible:
		if maximum_size <= 0
			@guard.synchronize do
				maximum_size = @stream.available_frame_size
				
				while maximum_size <= 0
					@window_updated.wait(@guard)
					
					maximum_size = @stream.available_frame_size
				end
			end
		end
		
		break unless chunk = send_data(chunk, maximum_size)
	end
end