Module: RoadRunnerModule

Included in:
RoadRunner
Defined in:
lib/run.rb,
lib/db.rb,
lib/init.rb,
lib/ended.rb,
lib/action.rb,
lib/report.rb,
lib/rrhelper.rb,
lib/rrmonitor.rb

Overview

Rrhelper will include many helpful methods for RoadRunner

Defined Under Namespace

Modules: Dbhelper, Rrhelper Classes: RRMonitor

Instance Method Summary collapse

Instance Method Details

#action(&blk) ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'lib/action.rb', line 4

def action(&blk)

  if block_given?
    @actBlk=blk
    register_transactions('actoin',&blk)
  else
    raise ArgumentError, "no block"
  end

end

#ended(&blk) ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'lib/ended.rb', line 4

def ended(&blk)

  if block_given?
    @endBlk=blk
    register_transactions('end',&blk)
  else
    raise ArgumentError, "no block"
  end

end

#init(&blk) ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'lib/init.rb', line 4

def init(&blk)

  if block_given?
    @initBlk=blk
    register_transactions('init',&blk)
  else
    raise ArgumentError, "no block"
  end

end

#iterationIdObject



5
6
7
8
9
10
11
# File 'lib/rrhelper.rb', line 5

def iterationId
  if(@mode=='thread')then
    @thread_pool[Thread.current][:iterationId]
  else
    @iterationId
  end
end

#report(label = '', width = 0) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/report.rb', line 6

def report(label='',width=0)
  p "      Wait for moment,the report is collecting......"
  content = if @rep
    @succRates = getSuccessRate @transactions
    <<-DOC
    #{"Performance Reports".center(50, '*')}
    #{label.ljust(width)}
    #{Benchmark::Tms::CAPTION}
    #{@rep.format}
    #{'--'*32}
    The Virtual User is #{@users}.
    Total Execute #{@iterations*@users} Action(s).
    Total Cost #{@rep.real} Second(s).
    This Scenario's TPS : #{@tps}.
    The longest action cost #{@longest || 0} seconds.
    #{'Transaction Report'.center(50, '-')}
    #{@transactions.inject("") { |str,k|
    str += "#{k[0].to_s} : count => #{k[1].size} time(s) , cost => #{k[1].inject(0){|c,v|c+=v[:cost].to_f}.to_s[0..3]} sec(s) , success rate => #{@succRates[k[0]]}\n      "
    }.gsub(/\n$/,'')}
    #{'--'*32}
    User defined params as below: 
    #{@global}
    #{"End of Reports".center(50, '*')}
    DOC
  else
    "None Report before RoadRunner run."
  end
  puts content
  self.log.info content
end

#runObject



5
6
7
8
9
10
11
12
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
45
46
47
48
49
50
51
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/run.rb', line 5

def run
  @strat_time = Time.now
  @initBlk.call
  @thread_pool = {}
  @counter = 0

  @log.debug "Mode => #{@mode}"
  iterationBlk = case @mode
  when /thread/,/t/ then
    proc {      
      @users.times do |userId|
        @thread_pool[Thread.start(){
          @iterations.times do |iterationId|
            
            rcost = 0
            @transaction_blk.each_pair{|k,v|
              rcost = self.transaction(k,v)
            }
            
            # rcost = self.transaction('Action',&@actBlk)
            self.log.debug "IterationID is #{self.iterationId};UserID is #{self.userId};This Action Cost #{rcost} seconds"
            @longest = (@longest<rcost)?rcost:@longest
            @thread_pool[Thread.current][:iterationId] = iterationId
          end
          @counter += 1
        }]={:userId=>userId}
      end
#      @thread_pool.keys.each{|t|t.join}
      while @counter != @users do
        Thread.pass
      end
    }
  when /process/,/p/ then
    proc {
      ppid=Process.pid
      @log.info("Main Process pid => #{ppid}")
      
      pids=[]
      @users.times { |userId|
        pids << Process.fork { 
          @userId=userId
          @iterations.times do |iterationId|
            @iterationId=iterationId
            
            rcost = 0
            @transaction_blk.each_pair{|k,v|
              rcost = self.transaction(k,v)
            }
            
            # rcost = self.transaction('Action',&@actBlk)
            @longest = (@longest<rcost)?rcost:@longest
          end
          @log.info("<PID:#{Process.pid}> going down.Longest job cost #{@longest}")
          
          Process.kill("HUP", ppid)
        }
      }
      
      switch=true
      c=0
      Signal.trap("HUP", proc { @log.info("One User(Process) done."); (switch = false;p "Main process<#{Process.pid}> going down.") if ((c+=1) == @users) })
      
      @log.info "Waiting Processes => #{pids.inspect}"
      
      p "Processes<#{pids.inspect}> working."
      while switch
        STDOUT.puts '.'
        sleep 5
      end
      p $/
      
      Process.waitall
      @log.info "Processes down."
    }
  else
    proc {
      @iterations.times do |iterationId|
        @iterationId=iterationId
        @users.times do |userId|
          @userId=userId
          
          rcost = 0
          @transaction_blk.each_pair{|k,v|
            rcost = self.transaction(k,v)
          }
          
          # rcost = self.transaction('Action',&@actBlk)
          
          # => the below sentence cost a lot of system resource
          # => if you run for production result,keep it annotated!!!
#          self.log.debug "IterationID is #{self.iterationId};UserID is #{self.userId};This Action Cost #{rcost} seconds"
          @longest = (@longest<rcost)?rcost:@longest
        end
      end
    }
  end

  p '      '+"RoadRunner".center(50, '*')
  p '      *'+"---Run , on your way.".rjust(48, ' ')+'*'
  p '      '+'*'*50
  p
  p "      Running......"
  @rep = Benchmark::measure(&iterationBlk)
  p "      Ending......"
  @endBlk.call

  @tps = @iterations*@users/@rep.real
end

#save_report(opts = {:author=>'Anonymous',:script=>""}) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
78
79
80
81
82
83
84
# File 'lib/report.rb', line 37

def save_report(opts={:author=>'Anonymous',:script=>""})

  p "      Saving report to database......"
  opts={:author=>'Anonymous',:script=>""}.merge opts
  if @data_write then
    unless opts[:name] then
      self.log.warn "scenario name may be needed."
      require 'uuidtools' unless defined?UUID
      # scenario || UUID.random_create.to_s is for debug
      opts[:name] = opts[:name] || UUID.random_create.to_s
      self.log.info "scenario is created as #{opts[:name]}"
    end
    # => scenario = Scenario.find_or_create_by_name(opts.merge({:create_at=>Time.now})).shift
    scenario = Scenario.find_or_create_by_name(opts.merge({:create_at=>Time.now}))
    scenario.tps+=@iterations*@users/@rep.real

    # => if opts[:script] is set as <your script>.rb 's path
    # => opts[:script] = __FILE__
    # => then scenario.script will be set.
    if FileTest.exist?(opts[:script]) then
      scenario.script = ""
      IO.foreach(opts[:script]){|x|scenario.script << x}
    end

    @succRates = @succRates || (getSuccessRate @transactions)
    # k is transaction name ,
    # v is reports in every transaction.
    @transactions.each do |k,v|
      transaction  = Transaction.new({:name=>k,:create_at=>Time.now,:success_rate=>@succRates[k]})
      v.each_index do |id|
        transaction.records << Record.new(v[id].merge({:seq=>id,:ts=>v[id][:create_at].to_f-@strat_time.to_f}))
        self.log.debug "v[#{id}] = #{v[id].inspect}"
      end
      scenario.transactions << transaction
    end
    begin
      scenario.save!
      p "      Saved OK!"
    rescue =>e
      self.log.error e
      p e
    end
    self.log.info "records has saved in DB."
  else
    p '      Error:You didn\'t connect any database.'
    self.log.error 'You didn\'t connect any database.'
  end
end

#userIdObject



13
14
15
16
17
18
19
# File 'lib/rrhelper.rb', line 13

def userId
  if(@mode=='thread')then
    @thread_pool[Thread.current][:userId]
  else
    @userId
  end
end