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.



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

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

#close_write(error = nil) ⇒ Object



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

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.



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

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

#window_updated(size) ⇒ Object



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

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

#write(chunk) ⇒ Object



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

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