Guest User

Untitled

a guest
Jul 20th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. #!/usr/bin/ruby
  2.  
  3. $0 = "em_server_test_leak.rb"
  4.  
  5. require "eventmachine"
  6. begin
  7. require "iobuffer"
  8. rescue LoadError
  9. $stderr.puts "ERROR: iobuffer gem is required:\n gem install iobuffer"
  10. exit 1
  11. end
  12. require "socket"
  13.  
  14.  
  15. class Message
  16. attr_accessor :connection, :data, :source_ip, :source_port
  17.  
  18. def initialize(data)
  19. @data = data
  20. end
  21. end
  22.  
  23.  
  24.  
  25. class TestLeakServer < EM::Connection
  26.  
  27. attr_reader :source_ip, :source_port
  28.  
  29. def initialize
  30. super
  31. @buffer = IO::Buffer.new
  32. @state = :init
  33. @num_request = 0
  34. @num_response = 0
  35. end
  36.  
  37. def post_init
  38. @source_port, @source_ip = ::Socket.unpack_sockaddr_in(get_peername)
  39. puts "post_init: self.object_id = #{self.object_id}"
  40. end
  41.  
  42. def receive_data(data)
  43. @buffer << data
  44.  
  45. while case @state
  46. when :init
  47. @state = :message
  48. when :message
  49. parse_message
  50. when :finished
  51. process_request(@msg)
  52. @state = :init
  53. when :invalid
  54. $stderr.puts "FATAL: state invalid"
  55. raise "invalid state!!!"
  56. else
  57. raise RuntimeError, "invalid state: #{@state}"
  58. end
  59. end
  60. end
  61.  
  62. def parse_message
  63. return false if @buffer.size < 1
  64.  
  65. @msg = Message.new(@buffer.read(1))
  66. @num_request += 1
  67. @state = :finished
  68.  
  69. return true
  70. end
  71.  
  72. def process_request(msg)
  73. puts "requests = #{@num_request} - responses = #{@num_response} => diff = #{@num_request-@num_response}"
  74.  
  75. msg.source_ip = @source_ip
  76. msg.source_port = @source_port
  77.  
  78. if msg.data == "A"
  79. send_data "a"
  80. @num_response += 1
  81.  
  82. elsif msg.data == "B"
  83. EM.next_tick do
  84. send_data "b"
  85. @num_response += 1
  86. end
  87.  
  88. elsif msg.data == "C"
  89. msg.connection = self
  90. operation = proc { msg }
  91. callback = proc do |result|
  92. result.connection.send_data "c"
  93. @num_response += 1
  94. end
  95. EM.defer( operation, callback )
  96.  
  97. else
  98. raise "msg.data is not \"A\" or \"B\" or \"C\" !!!"
  99. end
  100.  
  101. return true
  102. end
  103.  
  104. end
  105.  
  106.  
  107. EM.threadpool_size = 10
  108. EM.run do
  109.  
  110. EM.start_server("0.0.0.0", 6666, TestLeakServer)
  111. puts "INFO: TCP server listening on 0.0.0.0:6666"
  112.  
  113. EM.add_periodic_timer(3) do
  114. $stderr.puts
  115. $stderr.puts "[[[ #{Time.now} ]]]"
  116. GC.start
  117. $stderr.puts "GC.start executed"
  118. $stderr.puts "ObjectSpace.each_object:"
  119. $stderr.puts "TOTAL objets: #{ObjectSpace.each_object() {} }"
  120. $stderr.puts "TOTAL EM::Connection: #{ObjectSpace.each_object(EM::Connection) {} }"
  121. $stderr.puts "TOTAL TestLeakServer: #{ObjectSpace.each_object(TestLeakServer) {} }"
  122. num_conn = 0
  123. ObjectSpace.each_object(TestLeakServer) do |conn|
  124. if conn.source_port and (num_conn+=1) <= 20
  125. $stderr.puts "- connection: source port = #{conn.source_port} | error? = #{conn.error?} | object_id = #{conn.object_id}"
  126. end
  127. end
  128. $stderr.puts "TOTAL Message: #{ObjectSpace.each_object(Message) {} }"
  129. num_msg = 0
  130. ObjectSpace.each_object(Message) do |msg|
  131. $stderr.puts "- message source port: #{msg.source_port}"
  132. if (num_msg+=1) > 20
  133. $stderr.puts "- [more...]"
  134. break
  135. end
  136. end
  137. end
  138.  
  139. end
Add Comment
Please, Sign In to add comment