hobble 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: 914bf3cd69368d2c16fd36fdb5169253165c68a7
4
+ data.tar.gz: 9b5357e5bae8e6e05557f687dce73a0431eee5e3
5
+ SHA512:
6
+ metadata.gz: ec331915e446d78b9618d5d203d6d5adefaf0316550e8a68296faaeead2c97548ff16c24b2623d322a4f3b3afd5cfab82de94d8a28b96f1e2cf1d84c6fba1935
7
+ data.tar.gz: 587f81472093634c8ce540d57c1c09ebfc580a52a64e4e90b4f0e8cbffef9d3b8c8c1b9d92c5400b763b0e9684a874b26f6ddacabba011d47ce739d52592a9e7
@@ -0,0 +1,44 @@
1
+ module Hobble
2
+ # Stores both individual items, and a balance of
3
+ # how long they are taking to process.
4
+ class Collection
5
+ attr_reader :name, :items, :debt
6
+
7
+ def initialize(name, debt = 0)
8
+ @name = name
9
+ @debt = debt
10
+ @items = []
11
+ end
12
+
13
+ # Add `items' to this collection.
14
+ def add(items)
15
+ @items.concat(items)
16
+ end
17
+
18
+ # Wipe items, but doesn't clear
19
+ # the debt accrued already.
20
+ def clear!
21
+ @items.replace([])
22
+ end
23
+
24
+ # Execute the given `action' in
25
+ # the account of this collection.
26
+ def clock(&action)
27
+ t = Time.now
28
+ action.call(name, items)
29
+ @debt += (Time.now - t)
30
+ end
31
+
32
+ # Worth giving this collection a go?
33
+ def ready?
34
+ items.length > 0
35
+ end
36
+
37
+ # Compare by debt. If equal, swap round to
38
+ # reduce freqency of repeated scheduling.
39
+ def <=>(other)
40
+ value = debt <=> other.debt
41
+ value == 0 ? 1 : value
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,61 @@
1
+ module Hobble
2
+ # Responsible for scheduling a set of collections
3
+ # in a way that is perceived to be fair.
4
+ class Scheduler
5
+ attr_reader :collections
6
+
7
+ def initialize(groups = {})
8
+ @collections = []
9
+ schedule(groups)
10
+ end
11
+
12
+ # Schedule the given groups, creating
13
+ # or adding to new collections as needed.
14
+ def schedule(groups)
15
+ groups.each do |name, items|
16
+ collection_for(name).add(items)
17
+ end
18
+ end
19
+
20
+ # Clears pending jobs from the scheduler,
21
+ # but doesn't wipe accrued debt.
22
+ def clear!
23
+ collections.each(&:clear!)
24
+ end
25
+
26
+ # Executes `action' for each job in a sensible
27
+ # order, and finishes when done.
28
+ def run(&action)
29
+ loop { break unless run_once(&action) }
30
+ end
31
+
32
+ private
33
+
34
+ # Execute `action' for the next ready
35
+ # collection, if there is one.
36
+ def run_once(&action)
37
+ collection = next_ready
38
+ collection.clock(&action) if collection
39
+ collection
40
+ end
41
+
42
+ # Returns the least-indebted collection
43
+ # that has queued items, or nil.
44
+ def next_ready
45
+ collections.sort.detect(&:ready?)
46
+ end
47
+
48
+ # :nodoc:
49
+ def collection_for(name)
50
+ collection = collections.detect { |coll| coll.name == name }
51
+
52
+ if collection.nil?
53
+ start_debt = collections.map(&:debt).min || 0
54
+ collection = Hobble::Collection.new(name, start_debt)
55
+ @collections.unshift(collection)
56
+ end
57
+
58
+ collection
59
+ end
60
+ end
61
+ end
data/lib/hobble.rb ADDED
@@ -0,0 +1,23 @@
1
+ %w{ collection scheduler }.each do |file|
2
+ require File.expand_path('../hobble/' + file, __FILE__)
3
+ end
4
+
5
+ # Provides a way to schedule items in an
6
+ # order that is deemed fair.
7
+ #
8
+ # schedule = Hobble.schedule({
9
+ # jack: [:task1, :task2],
10
+ # john: [:task1, :task2, :task3]
11
+ # })
12
+ #
13
+ # schedule.run do |name, task|
14
+ # Task.process(task, for: name)
15
+ # end
16
+ #
17
+ module Hobble
18
+ # Returns a new scheduler for the
19
+ # given grouped items.
20
+ def self.schedule(groups)
21
+ Hobble::Scheduler.new(groups)
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hobble
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Josh Pencheon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.4.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.4.0
27
+ description: A ruby debt-based scheduling implementation
28
+ email:
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/hobble.rb
34
+ - lib/hobble/collection.rb
35
+ - lib/hobble/scheduler.rb
36
+ homepage: http://rubygems.org/gems/hobble
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.2.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Debt-based scheduling
60
+ test_files: []