roadrunner 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ == RoadRunner
2
+
3
+ Put appropriate LICENSE for your project here.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ == RoadRunner
2
+
3
+ You should document your project here.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/rdoctask'
11
+ require 'rake/testtask'
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = 'roadrunner'
15
+ s.version = '4.0.3'
16
+ s.has_rdoc = true
17
+ s.extra_rdoc_files = ['README', 'LICENSE']
18
+ s.summary = 'roadrunner'
19
+ s.description = s.summary
20
+ s.author = 'Charles Cui'
21
+ s.email = 'zheng.cuizh@gmail.com'
22
+ s.executables = ['controller.rb']
23
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,conf,controller,log,test}/**/*")
24
+ s.require_path = "lib"
25
+ s.bindir = "bin"
26
+ end
27
+
28
+ Rake::GemPackageTask.new(spec) do |p|
29
+ p.gem_spec = spec
30
+ p.need_tar = true
31
+ p.need_zip = true
32
+ end
33
+
34
+ Rake::RDocTask.new do |rdoc|
35
+ files =['README', 'LICENSE', 'lib/**/*.rb']
36
+ rdoc.rdoc_files.add(files)
37
+ rdoc.main = "README" # page to start on
38
+ rdoc.title = "dsmp Docs"
39
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
40
+ rdoc.options << '--line-numbers'
41
+ end
data/bin/controller.rb ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "logger"
5
+ require "yaml"
6
+ require File.join(File.dirname(__FILE__),'..','lib',"monitor")
7
+
8
+ USEAGE="Use age: controller.rb -t dd|mysql|svn|test [-f ./servers.yaml]"
9
+ (p USEAGE;return 1) if ARGV.size < 2
10
+
11
+ #-----------------------------Argv prepare.--------------------------------#
12
+
13
+ def args(key)
14
+ ARGV.each_with_index do |arg, i|
15
+ return ARGV[i+1] if "-#{key}" == arg
16
+ end
17
+ nil
18
+ end
19
+
20
+ unless args('t')
21
+ p USEAGE
22
+ p "parameter -t must be specified."
23
+ exit 1
24
+ end
25
+
26
+ #-----------------------------Log file initialize.--------------------------------#
27
+
28
+ log_file=File.join(File.dirname(__FILE__),'..','log','stdout.log')
29
+ FileUtils.rm log_file,:force=>true
30
+
31
+ File.open(log_file,"w"){|f|
32
+ f.puts "*"*60+$/
33
+ f.puts "DSMP (Distribute Store Manage Performance)".center(60,"*")+$/
34
+ f.puts "*"*60+$/+$/+$/
35
+ }
36
+
37
+ $log = Logger.new(log_file)
38
+ $log.level=Logger::INFO
39
+
40
+ $log.info "Controller Log Start".center(60,'*')+$/
41
+ $log.debug "ARGV:#{ARGV.inspect}"
42
+
43
+ #-----------------------------Servers Config initialize.--------------------------------#
44
+
45
+ conf_file=args('f')||File.join(File.dirname(__FILE__),'..','conf','server.yaml')
46
+
47
+ File.open( conf_file ) { |yf|
48
+ begin
49
+ $czservers=YAML::load( yf )
50
+ rescue Exception => e
51
+ $log.error("YAML Load Error!Plz check your yaml file => #{conf_file}.#{$/}#{e.to_s}")
52
+ exit 1
53
+ end
54
+ }
55
+
56
+ #-----------------------------exec your job and monitor work--------------------------------#
57
+
58
+ require File.join(File.dirname(__FILE__),'..','controller',"wrap")
59
+ include RoadRunnerModule
60
+
61
+ case args('t')
62
+ when /dd/ then
63
+ RRMonitor.monit($czservers,$log,"DD-Performance"){Wrap.work(3,$log,File.join(File.dirname(__FILE__),'..','controller','dd.sh'))}
64
+ when /mysql/ then
65
+ RRMonitor.monit($czservers,$log,"MySQL-Performance"){Wrap.work(3,$log,File.join(File.dirname(__FILE__),'..','controller','mysql.sh'))}
66
+ when /svn/ then
67
+ RRMonitor.monit($czservers,$log,"SVN-Performance"){Wrap.work(1,$log,File.join(File.dirname(__FILE__),'..','controller','svn.sh'))}
68
+ when /nbd/ then
69
+ RRMonitor.monit([],$log,"NBD-Performance"){require File.join(File.dirname(__FILE__),'..','controller',"ioperf")}
70
+ when /test/ then
71
+ RRMonitor.monit([],$log,"Test-Performance"){$log.info "Test Performance Start.....";sleep 60*2;$log.info "Test END."}
72
+ else
73
+ p USEAGE
74
+ exit 1
75
+ end
76
+
data/bin/hostmgr.rb ADDED
@@ -0,0 +1,69 @@
1
+ #!/bin/env ruby
2
+
3
+ (p "Use age : host_mgr.rb -c restart|shutdown|test [-f ./servers.yaml|-h]";exit 1) if ARGV.include("-h")
4
+
5
+ require "rubygems"
6
+ require "net/ssh"
7
+
8
+ class HostMgr
9
+ def initialize(opt={:server=>"0.0.0.0", :username=>"admin", :password=>"123456"})
10
+ begin
11
+ @sess=Net::SSH.start(opt[:server], opt[:username], :password => opt[:password],:timeout => 120)
12
+ rescue Exception => e
13
+ p e
14
+ p opt.inspect
15
+ raise e
16
+ end
17
+ end
18
+
19
+ def exec!(cmd)
20
+ p @sess.exec!(cmd)
21
+ p "#{cmd} --exec over."
22
+ end
23
+
24
+ def exit
25
+ @sess.exit
26
+ end
27
+ end
28
+
29
+ #-----------------------------Argv prepare.--------------------------------#
30
+
31
+ def args(key)
32
+ ARGV.each_with_index do |arg, i|
33
+ return ARGV[i+1] if "-#{key}" == arg
34
+ end
35
+ nil
36
+ end
37
+
38
+
39
+ #-----------------------------Servers Config initialize.--------------------------------#
40
+
41
+ conf_file=args('f')||File.join(File.dirname(__FILE__),'..','conf','server.yaml')
42
+
43
+ File.open( conf_file ) { |yf|
44
+ begin
45
+ $czservers=YAML::load( yf )
46
+ rescue Exception => e
47
+ $log.error("YAML Load Error!Plz check your yaml file => #{conf_file}.#{$/}#{e.to_s}")
48
+ exit 1
49
+ end
50
+ }
51
+
52
+ HOSTS=[]
53
+ $czservers.each do |h,obj|
54
+ #HOSTS<<HostMgr.new({:server=>h,:username=>"admin",:password=>"123456"})
55
+ HOSTS<<HostMgr.new({:server=>h,:username=>obj[:username],:password=>obj[:password]})
56
+ end
57
+
58
+ #p HOSTS.inspect
59
+
60
+ case args('c')
61
+ when /restart/,/reboot/,/re/
62
+ HOSTS.each{|h|h.exec!("init 6")}
63
+ when /shutdown/,/halt/,/sd/
64
+ HOSTS.each{|h|h.exec!("init 0")}
65
+ when /test/,/t/
66
+ HOSTS.each{|h|h.exec!("env")}
67
+ else
68
+ p "useage: host_mgr.rb cmd"
69
+ end
@@ -0,0 +1,88 @@
1
+ #!/bin/sh
2
+ #KV.....10.250.3.25-30..6......25.master.....kv-server.
3
+
4
+ #.......10.250.6.30
5
+ #root/goodluck@2010
6
+
7
+ #nbd....
8
+ #/home/admin/nbd
9
+
10
+ #...........
11
+ #/home/cuizheng
12
+ #/home/cuizheng/mysql
13
+ #/home/cuizheng/file1
14
+ #/home/cuizheng/file2
15
+
16
+
17
+ #......
18
+ mkdir /home/cuizheng
19
+ cd /home/cuizheng
20
+ LOG=/home/cuizheng/log/nbd-server.log
21
+ if [ -e $LOG ]; then
22
+ rm -f $LOG
23
+ fi
24
+
25
+ touch $LOG
26
+
27
+ #........nbd
28
+ umount ./file1
29
+ umount ./file2
30
+ umonut ./mysql
31
+
32
+ #..nbd-server..
33
+ ps axf|grep nbd-server|grep -v grep|awk '{printf "%s\n",$1}'|xargs kill -9
34
+
35
+ cd /home/admin/nbd/client/
36
+ #..nbd-client..
37
+ ./nbd-client -d /dev/nbd0
38
+ ./nbd-client -d /dev/nbd1
39
+ ./nbd-client -d /dev/nbd2
40
+
41
+ ps axf|grep nbd-client|grep -v grep|awk '{printf "%s\n",$1}'|xargs kill -9
42
+
43
+ cd /home/admin/nbd/server/
44
+ #.....
45
+ modprobe nbd
46
+ nohup ./nbd-server nuwa://10.250.3.25:10240/sys/kvengine/KVMaster >>$LOG 2>&1 &
47
+
48
+ cd /home/admin/nbd/client/
49
+ #.....
50
+ #sector_size=1024
51
+ #disk_size=50G
52
+ #device_id=second since 1970
53
+ #device=/dev/nbd0-nbd2
54
+
55
+ D=`date +"%Y-%m-%d %H:%M:%S"`
56
+
57
+ Device_id=`date +"%s"`
58
+ echo nbd0 device_id => $Device_id
59
+ ./nbd-client 1024 2G $Device_id /dev/nbd0
60
+ echo MySQL deveice id: >> $LOG
61
+ echo $Device_id >> $LOG
62
+
63
+ sleep 5
64
+
65
+ Device_id=`date +"%s"`
66
+ echo nbd1 device_id => $Device_id
67
+ ./nbd-client 1024 2G `date +"%s"` /dev/nbd1
68
+ echo File1 deveice id: >> $LOG
69
+ echo $Device_id >> $LOG
70
+
71
+ sleep 5
72
+
73
+ Device_id=`date +"%s"`
74
+ echo nbd2 device_id => $Device_id
75
+ ./nbd-client 1024 2G `date +"%s"` /dev/nbd2
76
+ echo File2 deveice id: >> $LOG
77
+ echo $Device_id >> $LOG
78
+
79
+ #...
80
+ mkfs /dev/nbd0
81
+ mkfs /dev/nbd1
82
+ mkfs /dev/nbd2
83
+
84
+ #....NBD......:
85
+ mount /dev/nbd0 /home/cuizheng/mysql
86
+ mount /dev/nbd1 /home/cuizheng/file1
87
+ mount /dev/nbd2 /home/cuizheng/file2
88
+
data/conf/servers.yaml ADDED
@@ -0,0 +1,29 @@
1
+ ---
2
+ 10.250.3.25:
3
+ :username: admin
4
+ :ts: Test-Performance
5
+ :password: "123456"
6
+ 10.250.3.26:
7
+ :username: admin
8
+ :ts: Test-Performance
9
+ :password: "123456"
10
+ 10.250.6.30:
11
+ :username: admin
12
+ :ts: Test-Performance
13
+ :password: "123456"
14
+ 10.250.3.27:
15
+ :username: admin
16
+ :ts: Test-Performance
17
+ :password: "123456"
18
+ 10.250.3.28:
19
+ :username: admin
20
+ :ts: Test-Performance
21
+ :password: "123456"
22
+ 10.250.3.29:
23
+ :username: admin
24
+ :ts: Test-Performance
25
+ :password: "123456"
26
+ 10.250.3.30:
27
+ :username: admin
28
+ :ts: Test-Performance
29
+ :password: "123456"
data/controller/dd.sh ADDED
@@ -0,0 +1,92 @@
1
+ #!/bin/sh
2
+ #file-name=nbd_perf_dd.sh
3
+
4
+ mkdir -p /home/cuizheng/log
5
+ cd /home/cuizheng
6
+ #LOG=/home/cuizheng/log/nbd_perf_dd_`date +"%Y-%m-%d=%H:%M:%S"`.log
7
+ LOG=/home/cuizheng/log/dd.log
8
+
9
+ echo "***********DD-Performance***********" >> $LOG
10
+
11
+ if [ -e $log ];then
12
+ rm -f $LOG
13
+ fi
14
+ touch $LOG
15
+ _START=`date +"%s"`
16
+
17
+ i=1
18
+
19
+ while [ $i -le 3 ];
20
+ do
21
+ SUB=`uuidgen`
22
+
23
+ cd /home/cuizheng/file1
24
+ mkdir dd_tmp_$SUB
25
+ cd dd_tmp_$SUB
26
+
27
+ #echo "dd 5mb start" >> $LOG
28
+ #UUID=`uuidgen`
29
+ #START=`date +"%s"`
30
+ #dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=10
31
+ #sync
32
+ #END=`date +"%s"`
33
+ #echo "
34
+ #dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=10
35
+ #sync
36
+ #START:$START,END:$END,SPEND:$((END-START))
37
+ #
38
+ #" >> $LOG
39
+
40
+
41
+ echo "dd 50mb start" >> $LOG
42
+ UUID=`uuidgen`
43
+ START=`date +"%s"`
44
+ dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=102
45
+ sync
46
+ END=`date +"%s"`
47
+ echo "
48
+ dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=102
49
+ sync
50
+ START:$START,END:$END,SPEND:$((END-START))
51
+
52
+ " >> $LOG
53
+
54
+ #echo "dd 500mb start" >> $LOG
55
+ #UUID=`uuidgen`
56
+ #START=`date +"%s"`
57
+ #dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=1024
58
+ #sync
59
+ #END=`date +"%s"`
60
+ #echo "
61
+ #dd if=/dev/zero of=./nbd_perf_test_file_$UUID.dat bs=512k count=102
62
+ #sync
63
+ #START:$START,END:$END,SPEND:$((END-START))
64
+ #
65
+ #" >> $LOG
66
+
67
+
68
+ echo "rm dd document start" >> $LOG
69
+ cd ..
70
+ START=`date +"%s"`
71
+ rm -rf dd_tmp_$SUB
72
+ sync
73
+ END=`date +"%s"`
74
+ echo "
75
+ rm -rf dd_tmp_$SUB
76
+ sync
77
+ START:$START,END:$END,SPEND:$((END-START))
78
+
79
+ " >> $LOG
80
+
81
+ i=$(($i + 1))
82
+ done
83
+
84
+ _END=`date +"%s"`
85
+
86
+ echo DD-Performance Total START:$_START,END:$_END,SPEND:$((_END-_START)) >> $LOG
87
+
88
+ exit 1
89
+
90
+ #...10..........
91
+ #nohup sh nbd_perf_dd.sh 1>/home/cuizheng/nbd_perf_dd.log 2>&1
92
+
@@ -0,0 +1,108 @@
1
+ require "rubygems"
2
+ require File.join(File.dirname(__FILE__),'..','lib','roadrunner')
3
+
4
+ #-----------------------------Argv prepare.--------------------------------#
5
+
6
+ def args(key)
7
+ ARGV.each_with_index do |arg, i|
8
+ return ARGV[i+1] if "-#{key}" == arg
9
+ end
10
+ nil
11
+ end
12
+
13
+ unless args('nbd')
14
+ p "[ruby ]controller.rb ioperf -nbd /dev/nbd[0-x]"
15
+ exit 1
16
+ end
17
+
18
+ #-----------------------------Logger prepare.--------------------------------#
19
+
20
+ $log ||= Logger.new(STDOUT)
21
+
22
+ NBD=begin
23
+ File.open(args('nbd'),"r+")
24
+ rescue Exception => e
25
+ $log.error "Can't open #{args('nbd')}!"
26
+ exit -1
27
+ end
28
+
29
+ NBD.sync=true
30
+
31
+ #-----------------------------Test scenario prepare.--------------------------------#
32
+
33
+ class IOPerf
34
+
35
+ class<<self
36
+
37
+ def rand_read(nbd,fs)
38
+ begin
39
+ mp=rand(fs).to_i
40
+ $log.info("rand_read:seek #{tmp} in #{nbd}.")
41
+ nbd.seek(tmp)
42
+ tmp=nbd.getc
43
+ $log.debug("rand_read:get #{tmp} from #{nbd}.")
44
+ rescue Exception => e
45
+ $log.error("#{nbd} read error!")
46
+ end
47
+ end
48
+
49
+ def rand_write(nbd,fs)
50
+ begin
51
+ tmp=rand(fs).to_i
52
+ $log.info("rand_write:seek #{tmp} in #{nbd}.")
53
+ nbd.seek(tmp)
54
+ tmp=('a'..'z').to_a[rand 26]
55
+ $log.debug("rand_write:write #{tmp} into #{nbd}.")
56
+ nbd.putc(tmp)
57
+ rescue Exception => e
58
+ $log.error("#{nbd} write error!")
59
+ end
60
+ end
61
+
62
+ def seq_read(nbd,fs)
63
+ begin
64
+ nbd.rewind if nbd.eof?
65
+ tmp=rand(fs)
66
+ $log.debug("seq_read:reading #{tmp} bytes from #{nbd}")
67
+ nbd.sysread(tmp)
68
+ rescue Exception => e
69
+ $log.error("#{nbd} read error!")
70
+ end
71
+
72
+ end
73
+
74
+ def seq_write(nbd,fs)
75
+ begin
76
+ nbd.rewind if nbd.eof?
77
+ tmp=rand(fs)
78
+ $log.debug("seq_read:writing #{tmp} bytes into #{nbd}")
79
+ nbd.syswrite('x'*tmp)
80
+ rescue Exception => e
81
+ $log.error("#{nbd} write error!")
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+
91
+ rr=RoadRunner.new
92
+ rr.mode,rr.users,rr.iterations='p',50,10000
93
+
94
+ # ['rand_read','rand_write','seq_read','seq_write']
95
+
96
+ IOPerf.singleton_methods[0..-2].each{|s|
97
+ ts_proc=proc{
98
+ IOPerf.send(s,NBD,File.size(NBD))
99
+ }
100
+ rr.send(s,&ts_proc)
101
+ }
102
+
103
+ NBD.close
104
+
105
+ rr.run
106
+ rr.report
107
+
108
+
@@ -0,0 +1,74 @@
1
+ #!/ur/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'activerecord'
5
+ require 'benchmark'
6
+ require 'logger'
7
+ require 'pp'
8
+
9
+ log_file=File.join(File.dirname(__FILE__),'log','mysql.log')
10
+ FileUtils.rm log_file,:force=>true
11
+
12
+ File.open(log_file,"w"){|f|
13
+ f.puts "*"*60+$/
14
+ f.puts "MySQL Store Performance Test".center(60,"*")+$/
15
+ f.puts "*"*60+$/+$/+$/
16
+ }
17
+
18
+ #$log = Logger.new(File.join(File.dirname(__FILE__),'log','stdout.log'))
19
+ $log = Logger.new(log_file)
20
+ $log.level=Logger::ERROR
21
+
22
+ begin
23
+ ActiveRecord::Base.establish_connection(
24
+ :adapter =>"mysql",
25
+ :username => "houyi",
26
+ :password =>"111111",
27
+ :database => "SNS",
28
+ :host =>"10.250.6.30"
29
+ )
30
+ $log.info "MySQL Connect Success."
31
+ rescue => e
32
+ $log.error "MySQL Connect Failed!"
33
+ $log.error e.to_s
34
+ end
35
+
36
+ # N => count of iterations.
37
+ N=10000
38
+
39
+ class RRData < ActiveRecord::Base
40
+ set_table_name "qa_posts"
41
+ set_primary_key "ID"
42
+ end
43
+
44
+ def insert_records(x=N)
45
+ qp=RRData.new
46
+ RRData.columns.each do |c|
47
+ qp.send(c.to_s+"=",rand(x)) unless c=="ID"||c=='id'
48
+ end
49
+ ts=Benchmark.measure{qp.save!}
50
+ `sync`
51
+ $log.debug qp.inspect
52
+ $log.info "One Record insert. ts=>#{ts.inspect}"
53
+ end
54
+
55
+ def select_record(id=1)
56
+ qp=nil
57
+ ts=Benchmark.measure{qp=RRData.find_by_id(id)}
58
+ $log.debug qp.inspect
59
+ $log.info "One Record Select. ts=>#{ts.inspect}"
60
+ end
61
+
62
+
63
+ $log.info "#{N} iterations start.".center(60,'*')
64
+
65
+ ts = Benchmark.measure{
66
+ N.times do |x|
67
+ # insert_records(x)
68
+ # select_record(rand(3000)*2)
69
+ # RRData.find_by_sql()
70
+ end
71
+ }
72
+
73
+ $log.info "#{N} iterations end.".center(60,'*')
74
+ $log.info "#{N} iterations cost ts=>#{ts.inspect}".center(60,'*')
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+ /etc/init.d/mysql stop
3
+ rm -rf /home/cuizheng/mysql/*
4
+ sync
5
+ cp /home/admin/data /home/cuizheng/mysql/
6
+ sync
7
+ /etc/init.d/mysql start
8
+
9
+ ruby /home/cuizheng/controller/mysql.rb
data/controller/svn.sh ADDED
@@ -0,0 +1,49 @@
1
+ #!/bin/sh
2
+ #file-name=svn.sh
3
+
4
+ mkdir -p /home/cuizheng/log
5
+ cd /home/cuizheng
6
+ #LOG=/home/cuizheng/log/nbd_perf_svn_`date +"%Y-%m-%d=%H:%M:%S"`.log
7
+ LOG=/home/cuizheng/log/svn.log
8
+
9
+
10
+ cd /home/cuizheng/file1
11
+ rm -rf *
12
+ sync
13
+ cp /root/code ./ -r
14
+ sync
15
+ rm -rf /home/cuizheng/file2/*
16
+ sync
17
+
18
+
19
+ i=1
20
+
21
+ while [ $i -le 10 ];
22
+ do
23
+
24
+ START=`date +"%s"`
25
+ mv /home/cuizheng/file1/* /home/cuizheng/file2/
26
+ sync
27
+ END=`date +"%s"`
28
+ echo "
29
+ mv /home/cuizheng/file1/* /home/cuizheng/file2/
30
+ sync
31
+ START:$START,END:$END,SPEND:$((END-START))
32
+
33
+ " >>$LOG
34
+
35
+ START=`date +"%s"`
36
+ mv /home/cuizheng/file2/* /home/cuizheng/file1/
37
+ sync
38
+ END=`date +"%s"`
39
+ echo "
40
+ mv /home/cuizheng/file2/* /home/cuizheng/file1/
41
+ sync
42
+ START:$START,END:$END,SPEND:$((END-START))
43
+
44
+ " >> $LOG
45
+
46
+ i=$(($i + 1))
47
+ done
48
+
49
+ exit 1
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__),'..','lib','roadrunner.rb')
4
+ module RoadRunnerModule
5
+
6
+ module Wrap
7
+
8
+ def self.work(n,log,sh)
9
+ worker=RoadRunner.new
10
+
11
+ worker.users=n
12
+ worker.iterations=1
13
+ worker.log=log
14
+
15
+ worker.action{log.info `sh #{@sh} 2>&1`}
16
+
17
+ worker.run
18
+ worker.report
19
+ end
20
+ end
21
+
22
+
23
+ end
data/lib/action.rb ADDED
@@ -0,0 +1,14 @@
1
+ #Here is LR Action function
2
+
3
+ module RoadRunnerModule
4
+ def action(&blk)
5
+
6
+ if block_given?
7
+ @actBlk=blk
8
+ register_transactions('actoin',&blk)
9
+ else
10
+ raise ArgumentError, "no block"
11
+ end
12
+
13
+ end
14
+ end