data_hopper 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27c884262589c4b4caecbcde26f574ae98b024e3
4
+ data.tar.gz: 292ca14fe5a910bea84f6d4f7720d3be4241381f
5
+ SHA512:
6
+ metadata.gz: f8b0ac1913d6ec2034c552c41df239e8a96f860bd5d05fd9389c8d36867b73a6556f55d41ab890b863014c31daecbcda37ee32320486d2388c62d52ad59971f4
7
+ data.tar.gz: 65f6d95b7c82bd02cbaecae73fca6beb9918286760597a9f1e87a6b8eb9d3d56064c7a2a83b47e478c4291917ea46db79ee27242fb46643f45ab864b4759c311
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 hopper.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Doug Everly
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,58 @@
1
+ # Hopper
2
+
3
+ *Hopper* (noun): A storage container used to collect granular materials designed to easily dispense these materials through the use of gravity. (http://en.wikipedia.org/wiki/Hopper)
4
+
5
+ **Hopper** accumulates items and executes a block of code when its capacity is reached, or the timeout is reached, whichever event occurs first.
6
+
7
+ **Hopper** is useful for collecting a certain number of items before processing them, whilst not blocking too long if the capacity is not reached.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'hopper'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install hopper
22
+
23
+ ## Usage
24
+
25
+
26
+ Create a hopper:
27
+
28
+ h = Hopper.new capacity: 28, timeout: 1 do |items, timed_out|
29
+ puts "I have #{items.size} items"
30
+ puts "I timed out" if timed_out
31
+ end
32
+
33
+ Add items to the hopper:
34
+
35
+ h << 'an item'
36
+
37
+ To run the block even when there are no items present:
38
+
39
+ h = Hopper.new capacity: 28, timeout: 1 do |items, timed_out|
40
+ puts "I have #{items.size} items"
41
+ puts "I timed out" if timed_out
42
+ end
43
+
44
+ To stop the hopper:
45
+
46
+ h.stop
47
+
48
+ Hopper raises an exception if an item is added to the hopper while its not running.
49
+
50
+
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'hopper'
4
+
5
+ h = Hopper.new capacity: 10, timeout: 1, exact: true do |items, timed_out|
6
+ puts "I have #{items.size} items"
7
+ end
8
+
9
+
10
+ 22.times do |i|
11
+ h << i
12
+ end
13
+
14
+ h.stop
15
+ # h.start
16
+
17
+
18
+ sleep 3
19
+ begin
20
+ 1005.times do |i|
21
+ h << i
22
+ end
23
+ rescue Exception => e
24
+ puts e.message
25
+ end
26
+
27
+
28
+ # h.stop
data/hopper.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hopper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "data_hopper"
8
+ spec.version = Hopper::VERSION
9
+ spec.authors = ["Doug Everly"]
10
+ spec.email = ["Doug@Everly.org"]
11
+ spec.description = %q{Hopper accumulates items and executes a block of code when its capacity is reached, or the timeout is reached, whichever event occurs first.}
12
+ spec.summary = %q{Hopper is useful for collecting a certain number of items before processing them, whilst not blocking too long if the capacity is not reached.}
13
+ spec.homepage = "https://github.com/DougEverly/hopper"
14
+ spec.license = "MIT"
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
+ end
data/lib/hopper.rb ADDED
@@ -0,0 +1,75 @@
1
+ require_relative "hopper/version"
2
+ require 'thread'
3
+
4
+ class Hopper
5
+
6
+ def initialize(capacity: 10, timeout: 2, always: false, exact: true, &block)
7
+ @capacity = capacity
8
+ @timeout = timeout
9
+ @always = always
10
+ @exact = exact
11
+
12
+ @running = false
13
+ @condvar = ConditionVariable.new
14
+ @hopper_mutex = Mutex.new
15
+ @signal_mutex = Mutex.new
16
+ @hopper = Array.new
17
+ @block = block
18
+ @thread = nil
19
+
20
+ start
21
+ end
22
+
23
+ def start
24
+ @running = true
25
+ @thread = Thread.new do
26
+ while @running
27
+ timed_out = false
28
+
29
+ # wait for signal or timeout
30
+ @signal_mutex.synchronize {
31
+ if @condvar.wait(@signal_mutex, @timeout) then
32
+ timed_out = false
33
+ else
34
+ timed_out = true
35
+ end
36
+ }
37
+
38
+ # yield passed block
39
+ @hopper_mutex.synchronize {
40
+ if @always || @hopper.size > 0
41
+ @block.call @hopper, timed_out if @block
42
+ end
43
+ @hopper = Array.new
44
+ @condvar.signal if @exact
45
+ }
46
+
47
+ end
48
+ end
49
+ end
50
+
51
+ def stop
52
+ @running = false
53
+ @thread.join
54
+ end
55
+
56
+ def size
57
+ @hopper_mutex.synchronize {
58
+ return @hopper.size
59
+ }
60
+ end
61
+
62
+ def <<(item)
63
+ if !@running
64
+ raise "Hopper is not running."
65
+ end
66
+ @hopper_mutex.synchronize {
67
+ @hopper << item
68
+ if @hopper.size >= @capacity then
69
+ @condvar.signal
70
+ @condvar.wait(@hopper_mutex) if @exact
71
+ end
72
+ }
73
+ end
74
+
75
+ end
@@ -0,0 +1,3 @@
1
+ class Hopper
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: data_hopper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Doug Everly
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ description: Hopper accumulates items and executes a block of code when its capacity
28
+ is reached, or the timeout is reached, whichever event occurs first.
29
+ email:
30
+ - Doug@Everly.org
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - example/run_hopper.rb
41
+ - hopper.gemspec
42
+ - lib/hopper.rb
43
+ - lib/hopper/version.rb
44
+ homepage: https://github.com/DougEverly/hopper
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.2.0
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Hopper is useful for collecting a certain number of items before processing
68
+ them, whilst not blocking too long if the capacity is not reached.
69
+ test_files: []