hobble 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []