ninja 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ dist
2
+ doc
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2008-2009 Nicolas Sanguinetti
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 NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ = Ninja!
2
+
3
+ He runs in the background, without being seen
4
+
5
+ == Install
6
+
7
+ gem install ninja
8
+
9
+ == Use
10
+
11
+ require "ninja/threaded"
12
+
13
+ # Use a thread pool to run the background jobs
14
+ Ninja.hide_in(Ninja::Threaded.new(4))
15
+
16
+ class FooBar
17
+ include Ninja
18
+
19
+ def my_method
20
+ # some code
21
+ in_background do
22
+ # this code will run in background
23
+ end
24
+ # mode code
25
+ end
26
+ end
27
+
28
+ == Credits
29
+
30
+ Author:: Nicolás Sanguinetti
31
+ License:: MIT (see LICENSE file)
@@ -0,0 +1,25 @@
1
+ require "rake/testtask"
2
+
3
+ begin
4
+ require "hanna/rdoctask"
5
+ rescue LoadError
6
+ require "rake/rdoctask"
7
+ end
8
+
9
+ Rake::RDocTask.new do |rd|
10
+ rd.main = "README"
11
+ rd.title = "API Documentation for Ninja!"
12
+ rd.rdoc_files.include("README.rdoc", "LICENSE", "lib/**/*.rb")
13
+ rd.rdoc_dir = "doc"
14
+ end
15
+
16
+ begin
17
+ require "mg"
18
+ MG.new("ninja.gemspec")
19
+ rescue LoadError
20
+ end
21
+
22
+ desc "Default: run tests"
23
+ task :default => :test
24
+
25
+ Rake::TestTask.new
@@ -0,0 +1,12 @@
1
+ module Ninja
2
+ class << self
3
+ attr_accessor :hide_in
4
+ end
5
+
6
+ PlainSight = lambda {|b| b.call }
7
+ self.hide_in = PlainSight
8
+
9
+ def in_background(&block)
10
+ Ninja.hide_in.call(block)
11
+ end
12
+ end
@@ -0,0 +1,131 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../ninja")
2
+ require "thread"
3
+
4
+ module Ninja
5
+ # A thread pool based build engine. This engine simply adds jobs to an
6
+ # in-memory queue, and processes them as soon as possible.
7
+ class Threaded
8
+ # The optional pool size controls how many threads will be created.
9
+ def initialize(pool_size = 2)
10
+ @pool = ThreadPool.new(pool_size)
11
+ end
12
+
13
+ # Adds a job to the queue.
14
+ def call(job)
15
+ @pool << job
16
+ end
17
+
18
+ # The number of jobs currently in the queue.
19
+ def njobs
20
+ @pool.njobs
21
+ end
22
+
23
+ # This method will not return until #njobs returns 0.
24
+ def wait!
25
+ Thread.pass until @pool.njobs == 0
26
+ end
27
+
28
+ # Manage a pool of threads, allowing for spin up / spin down of the
29
+ # contained threads.
30
+ # Simply processes work added to it's queue via #push.
31
+ # The default size for the pool is 2 threads.
32
+ class ThreadPool
33
+
34
+ # A thread safe single value for use as a counter.
35
+ class Incrementor
36
+ # The value passed in will be the initial value.
37
+ def initialize(v = 0)
38
+ @m = Mutex.new
39
+ @v = v
40
+ end
41
+ # Add the given value to self, default 1.
42
+ def inc(v = 1)
43
+ sync { @v += v }
44
+ end
45
+ # Subtract the given value to self, default 1.
46
+ def dec(v = 1)
47
+ sync { @v -= v }
48
+ end
49
+ # Simply shows the value inspect for convenience.
50
+ def inspect
51
+ @v.inspect
52
+ end
53
+ # Extract the value.
54
+ def to_i
55
+ @v
56
+ end
57
+
58
+ private
59
+ # Wrap the given block in a mutex.
60
+ def sync(&b)
61
+ @m.synchronize &b
62
+ end
63
+ end
64
+
65
+ # The number of threads in the pool.
66
+ attr_reader :size
67
+ # The job queue.
68
+ attr_reader :jobs
69
+
70
+ # Set the size of the thread pool. Asynchronously run down threads
71
+ # that are no longer required, and synchronously spawn new required
72
+ # threads.
73
+ def size=(other)
74
+ @size = other
75
+
76
+ if @workers.size > @size
77
+ (@workers.size - @size).times do
78
+ @workers.shift[:run] = false
79
+ end
80
+ else
81
+ (@size - @workers.size).times do
82
+ @workers << spawn
83
+ end
84
+ end
85
+ end
86
+
87
+ # Default pool size is 2 threads.
88
+ def initialize(size = nil)
89
+ size ||= 2
90
+ @jobs = Queue.new
91
+ @njobs = Incrementor.new
92
+ @workers = Array.new(size) { spawn }
93
+ end
94
+
95
+ # Adds a job to the queue, the job can be any number of objects
96
+ # responding to call, and/or a block.
97
+ def add(*jobs, &blk)
98
+ jobs = jobs + Array(blk)
99
+
100
+ jobs.each do |job|
101
+ @jobs << job
102
+ @njobs.inc
103
+ end
104
+ end
105
+
106
+ alias_method :push, :add
107
+ alias_method :<<, :add
108
+
109
+ # A peak at the number of jobs in the queue. N.B. May differ, but
110
+ # should be more accurate than +jobs.size+.
111
+ def njobs
112
+ @njobs.to_i
113
+ end
114
+
115
+ private
116
+ # Create a new thread and return it. The thread will run until the
117
+ # thread-local value +:run+ is changed to false or nil.
118
+ def spawn
119
+ Thread.new do
120
+ c = Thread.current
121
+ c[:run] = true
122
+
123
+ while c[:run]
124
+ @jobs.pop.call
125
+ @njobs.dec
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,33 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "ninja"
3
+ s.version = "0.1"
4
+ s.date = "2009-08-07"
5
+
6
+ s.description = "Run background tasks easily"
7
+ s.summary = "Provide several ways to offload tasks to the background"
8
+ s.homepage = "http://github.com/foca/ninja"
9
+
10
+ s.authors = ["Nicolás Sanguinetti"]
11
+ s.email = "contacto@nicolassanguinetti.info"
12
+
13
+ s.require_paths = ["lib"]
14
+ s.rubyforge_project = "integrity"
15
+ s.has_rdoc = true
16
+ s.rubygems_version = "1.3.1"
17
+
18
+ if s.respond_to?(:add_development_dependency)
19
+ s.add_development_dependency "sr-mg"
20
+ s.add_development_dependency "contest"
21
+ s.add_development_dependency "redgreen"
22
+ end
23
+
24
+ s.files = %w[
25
+ .gitignore
26
+ LICENSE
27
+ README.rdoc
28
+ Rakefile
29
+ ninja.gemspec
30
+ lib/ninja.rb
31
+ lib/ninja/threaded.rb
32
+ ]
33
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ninja
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - "Nicol\xC3\xA1s Sanguinetti"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-07 00:00:00 -03:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sr-mg
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: contest
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: redgreen
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: Run background tasks easily
46
+ email: contacto@nicolassanguinetti.info
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ files:
54
+ - .gitignore
55
+ - LICENSE
56
+ - README.rdoc
57
+ - Rakefile
58
+ - ninja.gemspec
59
+ - lib/ninja.rb
60
+ - lib/ninja/threaded.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/foca/ninja
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project: integrity
85
+ rubygems_version: 1.3.4
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Provide several ways to offload tasks to the background
89
+ test_files: []
90
+