Class: Rabbit::Twitter::GLibConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/rabbit/twitter.rb

Instance Method Summary collapse

Constructor Details

#initialize(logger, handler, options) ⇒ GLibConnection

Returns a new instance of GLibConnection.



120
121
122
123
124
125
126
127
# File 'lib/rabbit/twitter.rb', line 120

def initialize(logger, handler, options)
  @logger = logger
  @options = options
  @handler = handler
  @socket = nil
  @channel = nil
  @source_ids = []
end

Instance Method Details

#closeObject



195
196
197
198
199
200
201
202
203
# File 'lib/rabbit/twitter.rb', line 195

def close
  return if @socket.nil?
  @source_ids.reject! do |id|
    GLib::Source.remove(id)
    true
  end
  @channel = nil
  @socket.close
end

#connectObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/rabbit/twitter.rb', line 129

def connect
  close
  @socket = TCPSocket.new(@options[:host], "http")
  if GLib.const_defined?(:IOChannelWin32Socket)
    @channel = GLib::IOChannelWin32Socket.new(@socket.fileno)
  else
    @channel = GLib::IOChannel.new(@socket.fileno)
  end
  begin
    @channel.flags = GLib::IOChannel::FLAG_NONBLOCK
  rescue GLib::IOChannelError
    @logger.warn("[twitter][read][error] " +
                 "failed to set non-blocking mode: " +
                 "#{$!.message}(#{$!.class})")
  end
  reader_id = @channel.add_watch(GLib::IOChannel::IN) do |io, condition|
    @logger.debug("[twitter][read][start]")
    data = io.read(4096)
    @logger.debug("[twitter][read][done] #{data.bytesize}")
    if data.empty?
      @source_ids.reject! {|id| id == reader_id}
      @logger.debug("[twitter][read][eof]")
      false
    else
      @handler.receive_data(data)
      true
    end
  end
  @source_ids << reader_id
  error_id = @channel.add_watch(GLib::IOChannel::ERR) do |io, condition|
    @handler.receive_error(condition)
    true
  end
  @source_ids << error_id
  @handler.extend(GLibAdapter)
  @handler.connection = self
  @handler.connection_completed
end

#reconnect(options = {}) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/rabbit/twitter.rb', line 205

def reconnect(options={})
  close
  after = options[:after] || 0
  if after.zero?
    connect
  else
    id = GLib::Timeout.add(after) do
      connect
      false
    end
    @source_ids << id
  end
end

#send_data(data) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/rabbit/twitter.rb', line 168

def send_data(data)
  rest = data.bytesize
  writer_id = @channel.add_watch(GLib::IOChannel::OUT) do |io, condition|
    if rest.zero?
      @logger.debug("[twitter][flush][start]")
      @channel.flush
      @logger.debug("[twitter][flush][done]")
      @source_ids.reject! {|id| id == writer_id}
      false
    else
      @logger.debug("[twitter][write][start]")
      written_size = @channel.write(data)
      if written_size.is_a?(Numeric)
        @logger.debug("[twitter][write][done] #{written_size}")
        rest -= written_size
        data[0, written_size] = ""
      else
        # for Ruby/GLib2 < 0.90.9
        rest = 0
        data.replace("")
      end
      true
    end
  end
  @source_ids << writer_id
end