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 +7 -0
- data/lib/hobble/collection.rb +44 -0
- data/lib/hobble/scheduler.rb +61 -0
- data/lib/hobble.rb +23 -0
- metadata +60 -0
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: []
|