cloud-crowd 0.7.5 → 0.7.6
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 +4 -4
- data/config/database.example.yml +4 -5
- data/lib/cloud-crowd.rb +15 -13
- data/lib/cloud_crowd/models.rb +5 -0
- data/lib/cloud_crowd/models/black_listed_action.rb +27 -0
- data/lib/cloud_crowd/models/node_record.rb +4 -0
- data/lib/cloud_crowd/models/work_unit.rb +2 -1
- data/lib/cloud_crowd/schema.rb +5 -0
- data/lib/cloud_crowd/server.rb +25 -0
- data/lib/cloud_crowd/version.rb +2 -2
- data/public/css/admin_console.css +19 -1
- data/public/js/admin_console.js +23 -0
- data/test/test_helper.rb +1 -0
- data/test/unit/test_black_listed_action.rb +33 -0
- data/views/operations_center.erb +16 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d33763aebe17845688903d5e4c15f7c9be07833
|
|
4
|
+
data.tar.gz: 95c586ec36d78a80c4e648017ad3e8c245b73206
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f04bca0a15c63970099d8595323237962764a6050d0a433ac4c1b8cb6c00f2881578cd24a769adaf20952ba852f3cb21b2cec667456dcce670442acd05ff0a89
|
|
7
|
+
data.tar.gz: 4a26778718399824ffbc749c099808b38433d3b6864fb1439336b5bf4d8b1a4c1b50db29c2dc11263c1d11d8c3a5ce105c0dac93bb0134ef76b2626aecdbaf74
|
data/config/database.example.yml
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
# to use any database that ActiveRecord supports. Only the central server needs
|
|
3
3
|
# this file to be configured -- nodes never connect directly to the database.
|
|
4
4
|
|
|
5
|
-
:adapter:
|
|
6
|
-
:encoding:
|
|
7
|
-
:
|
|
8
|
-
:password:
|
|
9
|
-
:socket: /tmp/mysql.sock
|
|
5
|
+
:adapter: postgresql
|
|
6
|
+
:encoding: unicode
|
|
7
|
+
:host: localhost
|
|
10
8
|
:database: cloud_crowd
|
|
9
|
+
allow_concurrency: true
|
|
11
10
|
|
|
12
11
|
# If you'd prefer to use an SQLite database instead, the following configuration
|
|
13
12
|
# will do nicely:
|
data/lib/cloud-crowd.rb
CHANGED
|
@@ -35,21 +35,23 @@ ActiveModel::Serializer.root = false
|
|
|
35
35
|
module CloudCrowd
|
|
36
36
|
|
|
37
37
|
# Autoload all the CloudCrowd internals.
|
|
38
|
-
autoload :Action,
|
|
39
|
-
autoload :AssetStore,
|
|
40
|
-
autoload :CommandLine,
|
|
41
|
-
autoload :Helpers,
|
|
42
|
-
autoload :Inflector,
|
|
43
|
-
autoload :
|
|
44
|
-
autoload :
|
|
45
|
-
autoload :
|
|
46
|
-
autoload :
|
|
47
|
-
autoload :
|
|
48
|
-
autoload :
|
|
49
|
-
autoload :
|
|
38
|
+
autoload :Action, 'cloud_crowd/action'
|
|
39
|
+
autoload :AssetStore, 'cloud_crowd/asset_store'
|
|
40
|
+
autoload :CommandLine, 'cloud_crowd/command_line'
|
|
41
|
+
autoload :Helpers, 'cloud_crowd/helpers'
|
|
42
|
+
autoload :Inflector, 'cloud_crowd/inflector'
|
|
43
|
+
autoload :MODELS, 'cloud_crowd/models'
|
|
44
|
+
autoload :Job, 'cloud_crowd/models'
|
|
45
|
+
autoload :BlackListedAction, 'cloud_crowd/models'
|
|
46
|
+
autoload :Node, 'cloud_crowd/node'
|
|
47
|
+
autoload :NodeRecord, 'cloud_crowd/models'
|
|
48
|
+
autoload :Server, 'cloud_crowd/server'
|
|
49
|
+
autoload :Worker, 'cloud_crowd/worker'
|
|
50
|
+
autoload :WorkUnit, 'cloud_crowd/models'
|
|
51
|
+
autoload :Dispatcher, 'cloud_crowd/dispatcher'
|
|
50
52
|
|
|
51
53
|
# Increment the schema version when there's a backwards incompatible change.
|
|
52
|
-
SCHEMA_VERSION =
|
|
54
|
+
SCHEMA_VERSION = 5
|
|
53
55
|
|
|
54
56
|
# Root directory of the CloudCrowd gem.
|
|
55
57
|
ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
|
data/lib/cloud_crowd/models.rb
CHANGED
|
@@ -38,3 +38,8 @@ end
|
|
|
38
38
|
require 'cloud_crowd/models/job'
|
|
39
39
|
require 'cloud_crowd/models/node_record'
|
|
40
40
|
require 'cloud_crowd/models/work_unit'
|
|
41
|
+
require 'cloud_crowd/models/black_listed_action'
|
|
42
|
+
|
|
43
|
+
module CloudCrowd
|
|
44
|
+
MODELS = [Job, NodeRecord, WorkUnit, BlackListedAction]
|
|
45
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module CloudCrowd
|
|
2
|
+
|
|
3
|
+
# A Black Listed Action is an action that has been disabled from running. For example, we may
|
|
4
|
+
# want to disable calls to a particular API once we have reached a rate limit.
|
|
5
|
+
# When a Node exits, it destroys this record.
|
|
6
|
+
class BlackListedAction < ActiveRecord::Base
|
|
7
|
+
|
|
8
|
+
validates_presence_of :action
|
|
9
|
+
validates :action, uniqueness: true
|
|
10
|
+
validates :action, format: { with: /\A[a-z_]+\z/, message: "action names must be alphabetic snakecase" }
|
|
11
|
+
|
|
12
|
+
# Update items on our blacklist that have expired and can now be run
|
|
13
|
+
# def self.update_black_list
|
|
14
|
+
# black_list = BlackListedAction.where.not(:duration_in_seconds => [nil,'',0])
|
|
15
|
+
# black_list.each do |item|
|
|
16
|
+
# target_time = item.created_at.to_i + item.duration_in_seconds
|
|
17
|
+
# item.delete if target_time < Time.now.to_i
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
|
|
21
|
+
# Returns the time the blacklisting will be removed
|
|
22
|
+
# def finish_time
|
|
23
|
+
# return nil if self.duration_in_seconds.nil?
|
|
24
|
+
# Time.at(self.created_at.to_i + self.duration_in_seconds)
|
|
25
|
+
# end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -40,6 +40,10 @@ module CloudCrowd
|
|
|
40
40
|
create!(attrs.merge(host_attr))
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
def self.available_actions
|
|
45
|
+
available.map(&:actions).flatten.uniq - BlackListedAction.all.pluck(:action)
|
|
46
|
+
end
|
|
43
47
|
|
|
44
48
|
# Dispatch a WorkUnit to this node. Places the node at back at the end of
|
|
45
49
|
# the rotation. If we fail to send the WorkUnit, we consider the node to be
|
|
@@ -42,7 +42,8 @@ module CloudCrowd
|
|
|
42
42
|
# Find the available nodes, and determine what actions we're capable
|
|
43
43
|
# of running at the moment.
|
|
44
44
|
available_nodes = NodeRecord.available.to_a
|
|
45
|
-
available_actions =
|
|
45
|
+
available_actions = NodeRecord.available_actions
|
|
46
|
+
|
|
46
47
|
filter = "action in (#{available_actions.map{|a| "'#{a}'"}.join(',')})"
|
|
47
48
|
|
|
48
49
|
# If there aren't any available nodes or actions don't bother doing anything.
|
data/lib/cloud_crowd/schema.rb
CHANGED
|
@@ -26,6 +26,11 @@ ActiveRecord::Schema.define(:version => CloudCrowd::SCHEMA_VERSION) do
|
|
|
26
26
|
t.datetime "updated_at"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
create_table "black_listed_actions", :force => true do |t|
|
|
30
|
+
t.string "action", :null => false
|
|
31
|
+
t.datetime "created_at"
|
|
32
|
+
end
|
|
33
|
+
|
|
29
34
|
create_table "work_units", :force => true do |t|
|
|
30
35
|
t.integer "status", :null => false
|
|
31
36
|
t.integer "job_id", :null => false
|
data/lib/cloud_crowd/server.rb
CHANGED
|
@@ -81,6 +81,31 @@ module CloudCrowd
|
|
|
81
81
|
json current_job
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
# Create a new blacklist item.
|
|
85
|
+
post '/blacklist' do
|
|
86
|
+
banned_action = BlackListedAction.new({:action=> params[:action]})
|
|
87
|
+
CloudCrowd.log("Blacklist ##{banned_action.id} (#{banned_action.action}) created.") unless ENV['RACK_ENV'] == 'test'
|
|
88
|
+
if banned_action.save
|
|
89
|
+
json banned_action
|
|
90
|
+
else
|
|
91
|
+
json banned_action.errors
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Delete a blacklist by action name
|
|
96
|
+
delete '/blacklist/:action' do
|
|
97
|
+
if action_ban = BlackListedAction.where(:action => params[:action]).first
|
|
98
|
+
json action_ban.destroy
|
|
99
|
+
else
|
|
100
|
+
raise not_found
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Retrieve a list of blacklisted actions and information about them.
|
|
105
|
+
get '/blacklist' do
|
|
106
|
+
json BlackListedAction.all
|
|
107
|
+
end
|
|
108
|
+
|
|
84
109
|
# Cleans up a Job's saved S3 files. Delete a Job after you're done
|
|
85
110
|
# downloading the results.
|
|
86
111
|
delete '/jobs/:job_id' do
|
data/lib/cloud_crowd/version.rb
CHANGED
|
@@ -204,4 +204,22 @@ body {
|
|
|
204
204
|
}
|
|
205
205
|
.graph {
|
|
206
206
|
height: 150px;
|
|
207
|
-
}
|
|
207
|
+
}
|
|
208
|
+
.info_table {
|
|
209
|
+
width: 300px;
|
|
210
|
+
outline: #555555 solid 2px;
|
|
211
|
+
text-align: center;
|
|
212
|
+
margin-left: 15px;
|
|
213
|
+
}
|
|
214
|
+
.info_table thead tr {
|
|
215
|
+
font-size: 16px;
|
|
216
|
+
color: #454545;
|
|
217
|
+
height: 50px;
|
|
218
|
+
background-color: white;
|
|
219
|
+
}
|
|
220
|
+
.info_table tbody tr {
|
|
221
|
+
height: 30px;
|
|
222
|
+
background-color: white;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
data/public/js/admin_console.js
CHANGED
|
@@ -44,6 +44,7 @@ window.Console = {
|
|
|
44
44
|
this._workUnitCountEl = $('#work_unit_count');
|
|
45
45
|
this._nodeCountEl = $('#node_count');
|
|
46
46
|
this._workerCountEl = $('#worker_count');
|
|
47
|
+
this._blacklistEl = $('#blacklist');
|
|
47
48
|
this._disconnected = $('#disconnected');
|
|
48
49
|
$(window).bind('resize', Console.renderGraphs);
|
|
49
50
|
$('#nodes .worker').live('click', Console.getWorkerInfo);
|
|
@@ -51,6 +52,7 @@ window.Console = {
|
|
|
51
52
|
$('#workers_legend').css({background : this.WORKERS_COLOR});
|
|
52
53
|
$('#nodes_legend').css({background : this.NODES_COLOR});
|
|
53
54
|
this.getStatus();
|
|
55
|
+
this.getBlacklist();
|
|
54
56
|
$.each(this.PRELOAD_IMAGES, function(){ var i = new Image(); i.src = this; });
|
|
55
57
|
},
|
|
56
58
|
|
|
@@ -74,6 +76,27 @@ window.Console = {
|
|
|
74
76
|
}});
|
|
75
77
|
},
|
|
76
78
|
|
|
79
|
+
// Request the blacklisted actions from our server
|
|
80
|
+
getBlacklist : function () {
|
|
81
|
+
$.ajax({url : 'blacklist', dataType: 'json', success : function(resp) {
|
|
82
|
+
Console._blacklist = resp;
|
|
83
|
+
if (Console._disconnected.is(':visible')) Console._disconnected.fadeOut(Console.ANIMATION_SPEED);
|
|
84
|
+
Console.renderBlacklist();
|
|
85
|
+
setTimeout(Console.getBlacklist, Console.POLL_INTERVAL);
|
|
86
|
+
}, error : function(request, status, errorThrown) {
|
|
87
|
+
if (!Console._disconnected.is(':visible')) Console._disconnected.fadeIn(Console.ANIMATION_SPEED);
|
|
88
|
+
setTimeout(Console.getBlacklist, Console.POLL_INTERVAL);
|
|
89
|
+
}});
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// Render the blacklisted actions
|
|
93
|
+
renderBlacklist : function() {
|
|
94
|
+
Console._blacklistEl.empty()
|
|
95
|
+
this._blacklist.forEach(function(d){
|
|
96
|
+
Console._blacklistEl.append("<tr><td>" + d.action + "</td><td>" + d.created_at + "</td></tr>")
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
|
|
77
100
|
// Fetch the last 100 lines of log from the server.
|
|
78
101
|
tailLog : function() {
|
|
79
102
|
$.ajax({url : 'log', success : function(resp) {
|
data/test/test_helper.rb
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class BlackListedActionTest < Minitest::Test
|
|
4
|
+
|
|
5
|
+
context "A CloudCrowd::BlackListedAction" do
|
|
6
|
+
|
|
7
|
+
setup do
|
|
8
|
+
BlackListedAction.destroy_all
|
|
9
|
+
@black_listed_action = BlackListedAction.create(action: 'word_count')
|
|
10
|
+
@node = NodeRecord.make!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
teardown do
|
|
14
|
+
BlackListedAction.destroy_all
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
should "fail if trying to create a duplicate blacklist entry" do
|
|
18
|
+
duplicate = BlackListedAction.create(action: 'word_count')
|
|
19
|
+
assert duplicate.errors.first[1] == "has already been taken"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "create valid black listed action object" do
|
|
23
|
+
assert @black_listed_action.present?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
should "not execute job because it is blacklisted" do
|
|
27
|
+
assert NodeRecord.all.map(&:actions).flatten.uniq.include? @black_listed_action.action
|
|
28
|
+
refute NodeRecord.available_actions.include? @black_listed_action.action
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
data/views/operations_center.erb
CHANGED
|
@@ -75,6 +75,22 @@
|
|
|
75
75
|
</div>
|
|
76
76
|
<div id="workers_graph" class="graph"></div>
|
|
77
77
|
</div>
|
|
78
|
+
<div class="graph_container">
|
|
79
|
+
<div class="graph_title">
|
|
80
|
+
Blacklisted Actions
|
|
81
|
+
</div>
|
|
82
|
+
<table class="info_table">
|
|
83
|
+
<thead>
|
|
84
|
+
<tr class="heading">
|
|
85
|
+
<th>Name</th>
|
|
86
|
+
<th>Disabled Time</th>
|
|
87
|
+
</tr>
|
|
88
|
+
</thead>
|
|
89
|
+
<tbody id="blacklist">
|
|
90
|
+
</tbody>
|
|
91
|
+
</table>
|
|
92
|
+
<div id="actions_table" class="table"></div>
|
|
93
|
+
</div>
|
|
78
94
|
</div>
|
|
79
95
|
|
|
80
96
|
<div id="worker_info" style="display:none;">
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cloud-crowd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Ashkenas
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2015-
|
|
13
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: activerecord
|
|
@@ -221,6 +221,7 @@ files:
|
|
|
221
221
|
- lib/cloud_crowd/helpers/resources.rb
|
|
222
222
|
- lib/cloud_crowd/inflector.rb
|
|
223
223
|
- lib/cloud_crowd/models.rb
|
|
224
|
+
- lib/cloud_crowd/models/black_listed_action.rb
|
|
224
225
|
- lib/cloud_crowd/models/job.rb
|
|
225
226
|
- lib/cloud_crowd/models/node_record.rb
|
|
226
227
|
- lib/cloud_crowd/models/work_unit.rb
|
|
@@ -261,6 +262,7 @@ files:
|
|
|
261
262
|
- test/config/database.yml
|
|
262
263
|
- test/test_helper.rb
|
|
263
264
|
- test/unit/test_action.rb
|
|
265
|
+
- test/unit/test_black_listed_action.rb
|
|
264
266
|
- test/unit/test_command_line.rb
|
|
265
267
|
- test/unit/test_configuration.rb
|
|
266
268
|
- test/unit/test_job.rb
|
|
@@ -296,8 +298,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
296
298
|
version: '0'
|
|
297
299
|
requirements: []
|
|
298
300
|
rubyforge_project: cloud-crowd
|
|
299
|
-
rubygems_version: 2.
|
|
301
|
+
rubygems_version: 2.4.5
|
|
300
302
|
signing_key:
|
|
301
303
|
specification_version: 4
|
|
302
304
|
summary: Parallel Processing for the Rest of Us
|
|
303
305
|
test_files: []
|
|
306
|
+
has_rdoc:
|