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