Class: EaseEngine::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/ease_engine/application.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Application

Returns a new instance of Application.



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
# File 'lib/ease_engine/application.rb', line 52

def initialize( options )
  @options = options
  if ! @options.key?( :watcher )
    @options[ :watcher ] = {}
  end
  if ! @options.key?( :timer )
    @options[ :timer ] = {}
  end
  if ! @options.key?( :socket_timer )
    @options[ :socket_timer ] = {
      :connect_timeout_usec   => 10000000,
      :connected_timeout_usec => 10000000,
    }
  end
  @options[ :is_daemon ] = false if ! @options.key?( :is_daemon )
  
  @exit_status = 0
  @is_update = false
  
  @watcher = EaseEngine::Watcher.new( @options[ :watcher ] )
  @measure = EaseEngine::Measure.new
  @timer = EaseEngine::Timer.new( @options[ :timer ] )
  @socket_timer = EaseEngine::Timer.new( @options[ :socket_timer ] )
  
  @is_daemon = @options[ :is_daemon ]
end

Instance Attribute Details

#exit_statusObject

Returns the value of attribute exit_status.



47
48
49
# File 'lib/ease_engine/application.rb', line 47

def exit_status
  @exit_status
end

#is_daemonObject

Returns the value of attribute is_daemon.



50
51
52
# File 'lib/ease_engine/application.rb', line 50

def is_daemon
  @is_daemon
end

#is_updateObject

Returns the value of attribute is_update.



47
48
49
# File 'lib/ease_engine/application.rb', line 47

def is_update
  @is_update
end

#measureObject

Returns the value of attribute measure.



48
49
50
# File 'lib/ease_engine/application.rb', line 48

def measure
  @measure
end

#optionsObject

Returns the value of attribute options.



46
47
48
# File 'lib/ease_engine/application.rb', line 46

def options
  @options
end

#socket_timerObject

Returns the value of attribute socket_timer.



49
50
51
# File 'lib/ease_engine/application.rb', line 49

def socket_timer
  @socket_timer
end

#timerObject

Returns the value of attribute timer.



49
50
51
# File 'lib/ease_engine/application.rb', line 49

def timer
  @timer
end

#watcherObject

Returns the value of attribute watcher.



48
49
50
# File 'lib/ease_engine/application.rb', line 48

def watcher
  @watcher
end

Class Method Details

.run(options = {}) ⇒ Object



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
# File 'lib/ease_engine/application.rb', line 13

def self.run( options = {} )
  EaseEngine::Log.inf( "EaseEngine #{EaseEngine::VERSION} options=#{options}" )
  application = new( options )
  begin
    application.on_start
  rescue => err
    application.on_error( err )
    
    application.is_update = false
  end
  
  while application.is_update
    begin
      EaseEngine::Frame.update{|sleep_time_usec, sleep_time_f|
        application.watcher.watch( sleep_time_f )
      }
      application.timer.update
      application.socket_timer.update
      application.on_update
    rescue => err
      application.on_error( err )
    end
  end
  
  begin
    application.on_end
  rescue => err
    application.on_error( err )
  end
  
  application.exit_status
end

Instance Method Details

#add_connect_socket(socket) ⇒ Object



161
162
163
164
165
166
167
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
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/ease_engine/application.rb', line 161

def add_connect_socket( socket )
  application = self
  @watcher.add( socket, {
    :on_read => Proc.new{|socket|
      socket.err = SystemCallError.new( socket.errno )
      application.on_error_socket( socket )
      application.remove_socket( socket )
    },
    :on_write => Proc.new{|socket|
      application.remove_socket_timer( socket.to_i )
      
      socket.err = nil
      application.add_socket( socket )
      application.on_connected_socket( socket )
      
      if socket.is_heartbeat
        # connected timeout
        hash = {
          :socket       => socket,
          :timeout_usec => @options[ :socket_timer ][ :connected_timeout_usec ],
        }
        hash[ :callback ] = Proc.new{|hash|
          if hash[ :socket ].is_timeout
            application.timeout_socket( hash[ :socket ] )
            next
          end
          
          hash[ :socket ].is_timeout = true
          application.write_packet( socket, EaseEngine::HeartbeatBeginPacket.new )
          application.add_socket_timer( hash[ :socket ].to_i, hash[ :timeout_usec ], hash, hash[ :callback ] )
        }
        hash[ :callback ].call( hash )
      end
    },
    :on_remove => Proc.new{|socket|
      application.close_socket( socket )
    }
  })
  
  # connect timeout
  add_socket_timer( socket.to_i, @options[ :socket_timer ][ :connect_timeout_usec ], socket, Proc.new{|socket|
    application.timeout_socket( socket )
  })
end

#add_server_socket(socket) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ease_engine/application.rb', line 137

def add_server_socket( socket )
  application = self
  @watcher.add( socket, {
    :on_read => Proc.new{|socket|
      application.on_accept_socket( socket )
    },
    :on_remove => Proc.new{|socket|
      application.close_socket( socket )
    }
  })
end

#add_socket(socket) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ease_engine/application.rb', line 149

def add_socket( socket )
  application = self
  @watcher.add( socket, {
    :on_read => Proc.new{|socket|
      application.read_socket( socket )
    },
    :on_remove => Proc.new{|socket|
      application.close_socket( socket )
    }
  })
end

#add_socket_timer(socket_id, timeout_usec, arg, callback) ⇒ Object



261
262
263
# File 'lib/ease_engine/application.rb', line 261

def add_socket_timer( socket_id, timeout_usec, arg, callback )
  @socket_timer.add( socket_id, timeout_usec, arg, callback )
end

#add_timer(group_id, timeout_usec, arg, callback) ⇒ Object



253
254
255
# File 'lib/ease_engine/application.rb', line 253

def add_timer( group_id, timeout_usec, arg, callback )
  @timer.add( group_id, timeout_usec, arg, callback )
end

#check_socket(socket) ⇒ Object



237
238
239
240
# File 'lib/ease_engine/application.rb', line 237

def check_socket( socket )
  on_error_socket( socket ) if ! socket.err.nil?
  remove_socket( socket ) if socket.is_disable
end

#close_socket(socket) ⇒ Object



247
248
249
250
251
# File 'lib/ease_engine/application.rb', line 247

def close_socket( socket )
  remove_socket_timer( socket.to_i )
  on_close_socket( socket )
  socket.close
end

#on_accept_socket(socket) ⇒ Object



102
103
104
105
106
107
108
109
110
111
# File 'lib/ease_engine/application.rb', line 102

def on_accept_socket( socket )
  accepted_socket = socket.accept
  if ! socket.err.nil?
    on_error_socket( socket )
    return
  end
  
  add_socket( accepted_socket )
  on_accepted_socket( accepted_socket, socket )
end

#on_accepted_socket(accepted_socket, server_socket) ⇒ Object



113
114
# File 'lib/ease_engine/application.rb', line 113

def on_accepted_socket( accepted_socket, server_socket )
end

#on_close_socket(socket) ⇒ Object



122
123
# File 'lib/ease_engine/application.rb', line 122

def on_close_socket( socket )
end

#on_connected_socket(socket) ⇒ Object



116
117
# File 'lib/ease_engine/application.rb', line 116

def on_connected_socket( socket )
end

#on_endObject



96
97
98
99
100
# File 'lib/ease_engine/application.rb', line 96

def on_end
  @watcher.each{|info|
    @watcher.remove( info.io )
  }
end

#on_error(err) ⇒ Object



133
134
135
# File 'lib/ease_engine/application.rb', line 133

def on_error( err )
  EaseEngine::Log.err( "on_error #{err.class.name}: #{err}\n#{err.backtrace}" )
end

#on_error_socket(socket) ⇒ Object



129
130
131
# File 'lib/ease_engine/application.rb', line 129

def on_error_socket( socket )
  EaseEngine::Log.err( "on_error_socket #{socket} #{socket.err.class.name}: #{socket.err}\n#{socket.err.backtrace}" )
end

#on_read_socket(socket, packet) ⇒ Object



119
120
# File 'lib/ease_engine/application.rb', line 119

def on_read_socket( socket, packet )
end

#on_startObject



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ease_engine/application.rb', line 79

def on_start
  trap( :INT ){
    @is_update = false
    @exit_status = :INT
  }
  
  trap( :TERM ){
    @is_update = false
    @exit_status = :TERM
  }
  
  trap( :PIPE ){}
end

#on_timeout_socket(socket) ⇒ Object



125
126
127
# File 'lib/ease_engine/application.rb', line 125

def on_timeout_socket( socket )
  EaseEngine::Log.wrn( "on_timeout_socket #{socket}" )
end

#on_updateObject



93
94
# File 'lib/ease_engine/application.rb', line 93

def on_update
end

#read_socket(socket) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/ease_engine/application.rb', line 210

def read_socket( socket )
  Packet.creates( socket ).each{|packet|
    case packet.packet_name
    when "EaseEngine.HeartbeatBeginPacket"
      write_packet( socket, EaseEngine::HeartbeatEndPacket.new )
    when "EaseEngine.HeartbeatEndPacket"
    else
      on_read_socket( socket, packet )
    end
  }
  check_socket( socket )
end

#reflect_socket(socket, recv_flags = 0, send_flags = 0) ⇒ Object



227
228
229
230
231
232
233
234
235
# File 'lib/ease_engine/application.rb', line 227

def reflect_socket( socket, recv_flags = 0, send_flags = 0 )
  buf = socket.recv( socket.read_max_size, recv_flags )
  if ! buf.empty?
    result = socket.send( buf, send_flags )
    return if result == buf.length
    EaseEngine::Log.err( "reflect_socket #{result} != #{buf.length}" ) if 0 < result && result != buf.length
  end
  check_socket( socket )
end

#remove_socket(socket) ⇒ Object



206
207
208
# File 'lib/ease_engine/application.rb', line 206

def remove_socket( socket )
  @watcher.remove( socket )
end

#remove_socket_timer(socket_id, timer_id = 0) ⇒ Object



265
266
267
# File 'lib/ease_engine/application.rb', line 265

def remove_socket_timer( socket_id, timer_id = 0 )
  @socket_timer.remove( socket_id, timer_id )
end

#remove_timer(group_id, timer_id = 0) ⇒ Object



257
258
259
# File 'lib/ease_engine/application.rb', line 257

def remove_timer( group_id, timer_id = 0 )
  @timer.remove( group_id, timer_id )
end

#timeout_socket(socket) ⇒ Object



242
243
244
245
# File 'lib/ease_engine/application.rb', line 242

def timeout_socket( socket )
  on_timeout_socket( socket )
  remove_socket( socket )
end

#write_packet(socket, packet, flags = 0, *args) ⇒ Object



223
224
225
# File 'lib/ease_engine/application.rb', line 223

def write_packet( socket, packet, flags = 0, *args )
  packet.write( socket, flags, *args )
end