load_runner 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in load_runner.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Don Najd
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # LoadRunner
2
+
3
+ ![alt text](http://my.stratos.net/~hewston95/RTM45/loderunner.png "Logo Title Text 1")
4
+
5
+ Take some Ruby Code and pass it to LoadRunner::Queue and you'll be able to
6
+ * Run the code n number of times in parallel
7
+ * Rand stagger the execution
8
+ * Run the code threaded and staggered for a specific amount of time (ex. 5 minutes)
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'load_runner'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install load_runner
23
+
24
+ ## Basic Usage
25
+
26
+ Create a LoadRunner Queue
27
+
28
+ q = LoadRunner::Queue.new
29
+
30
+ pass a block of work for 4 threads
31
+
32
+ q.load(4) do
33
+ puts 'hi'
34
+ end
35
+
36
+ run it
37
+
38
+ q.run
39
+
40
+ ## Ways to Run a Queue
41
+
42
+ Run parallel threads
43
+
44
+ q.run
45
+
46
+ Run threads and stagger by rand number between 1-5
47
+
48
+ q.run_and_stagger(5)
49
+
50
+ Run threads for 2 minutes
51
+
52
+ q.run_for_duration(120)
53
+
54
+ Run threads for 2 minutes and stagger by rand number between 1-5
55
+
56
+ q.run_for_duration(120, 5)
57
+
58
+
59
+ ## Concurrency
60
+
61
+ To run the threads in a truely concurrent fashion across multiple processors you must:
62
+ * Add LoadRunner Gem to your GemFile
63
+ * Then set your project up to use JRuby.
64
+
65
+ I use RBEnv so I run the following commands from the project folder:
66
+
67
+ rbenv install jruby-1.7.3
68
+ rbenv local jruby-1.7.3
69
+
70
+
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork it
75
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
76
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
77
+ 4. Push to the branch (`git push origin my-new-feature`)
78
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,143 @@
1
+ require "load_runner/version"
2
+
3
+ module LoadRunner
4
+
5
+ class Queue
6
+ attr_accessor :failures
7
+
8
+ def initialize(logger = nil)
9
+
10
+ # logger
11
+ if logger!=nil
12
+ @logger = logger
13
+ end
14
+
15
+ # setup
16
+ @threads = []
17
+ @transactions = 0
18
+ @num_threads = 1
19
+ @failures = 0
20
+ end
21
+
22
+ def load(num_threads=1, &work)
23
+ @num_threads = num_threads
24
+ @work = work # save work for new threads
25
+
26
+ # create threads
27
+ num_threads.times do ||
28
+
29
+ # do work
30
+ create_thread
31
+
32
+ # log
33
+ if @logger!=nil
34
+ @logger.debug "action=create|name=thread"
35
+ end
36
+ end
37
+ end
38
+
39
+ def run()
40
+ @start_time = Time.now
41
+ start_all
42
+ wait_until_finished
43
+ end
44
+
45
+ def run_and_stagger(max_sleep=10)
46
+ @start_time = Time.now
47
+ start_all { rand_sleep(max_sleep) }
48
+ wait_until_finished
49
+ end
50
+
51
+ def run_for_duration(num_seconds, max_sleep=0)
52
+ @start_time = Time.now
53
+
54
+ # keep them running
55
+ to_time = Time.now + num_seconds
56
+
57
+ # log
58
+ if @logger!=nil
59
+ @logger.debug "action=run_for_durration|until=#{to_time}"
60
+ end
61
+
62
+ # duration
63
+ while (Time.now <= to_time)
64
+ @threads.each do |t|
65
+
66
+ # restart threads
67
+ if (t.status=="sleep")
68
+ rand_sleep(max_sleep)
69
+ t.run
70
+ end
71
+
72
+ if (t.status==false or t.status == nil)
73
+ @transactions += 1
74
+ @threads.delete t
75
+ thread = create_thread
76
+ rand_sleep(max_sleep)
77
+ thread.run
78
+
79
+ # log
80
+ if @logger!=nil
81
+ @logger.debug "thread_count=#{@threads.count}"
82
+ end
83
+ end
84
+ end
85
+ end
86
+ wait_until_finished()
87
+ end
88
+
89
+ private
90
+
91
+ def create_thread()
92
+ thread = Thread.new do ||
93
+ Thread.stop
94
+ @work.call
95
+ end
96
+ @threads << thread
97
+ return thread
98
+ end
99
+
100
+ def start_all(&block)
101
+ @threads.each do |t|
102
+
103
+ # pausing block?
104
+ block
105
+
106
+ # log
107
+ if @logger!=nil
108
+ @logger.debug "action=start|name=thread"
109
+ end
110
+
111
+ # run thread
112
+ t.run
113
+ end
114
+ end
115
+
116
+ # wait for threads to complete
117
+ def wait_until_finished()
118
+ @threads.each do |t|
119
+ if (t.status=="run")
120
+ t.join; # wait to finish
121
+
122
+ # log
123
+ if @logger!=nil
124
+ @logger.debug "action=stop|name=thread"
125
+ end
126
+ end
127
+ end
128
+
129
+ # log
130
+ if @logger!=nil
131
+ @logger.debug "transactions=#{@transactions}|threads=#{@num_threads}|failures=#{@failures}|duration=#{Time.now - @start_time}"
132
+ end
133
+ end
134
+
135
+ # random sleep
136
+ def rand_sleep(max_sleep=10)
137
+ if max_sleep > 0
138
+ time_to_sleep = rand(0)/max_sleep
139
+ sleep(time_to_sleep)
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,3 @@
1
+ module LoadRunner
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'load_runner/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "load_runner"
8
+ spec.version = LoadRunner::VERSION
9
+ spec.authors = ["Don Najd"]
10
+ spec.email = ["dnajd7@gmail.com"]
11
+ spec.description = %q{Load Runner Ruby Gem allows you to run a block of code many times in parallel, stagger execution or run it for a specific amount of time}
12
+ spec.summary = %q{Run a block of code many times in parallel, stagger execution or run it for a specific amount of time}
13
+ spec.homepage = "https://github.com/dnajd/load_runner"
14
+ spec.license = "BSD"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: load_runner
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Don Najd
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Load Runner Ruby Gem allows you to run a block of code many times in
47
+ parallel, stagger execution or run it for a specific amount of time
48
+ email:
49
+ - dnajd7@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - lib/load_runner.rb
60
+ - lib/load_runner/version.rb
61
+ - load_runner.gemspec
62
+ homepage: https://github.com/dnajd/load_runner
63
+ licenses:
64
+ - BSD
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.23
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Run a block of code many times in parallel, stagger execution or run it for
87
+ a specific amount of time
88
+ test_files: []