acts_as_executor 1.0.0.beta2 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/acts_as_executor.gemspec +8 -1
- data/lib/acts_as_executor.rb +18 -31
- data/lib/acts_as_executor/common/future_task.rb +2 -2
- data/lib/acts_as_executor/common/instance_support_methods.rb +15 -0
- data/lib/acts_as_executor/executor/factory.rb +18 -22
- data/lib/acts_as_executor/executor/model/class_methods.rb +33 -0
- data/lib/acts_as_executor/executor/model/instance_methods.rb +87 -0
- data/lib/acts_as_executor/executor/model/instance_support_methods.rb +36 -0
- data/lib/acts_as_executor/task/clazz.rb +26 -0
- data/lib/acts_as_executor/task/model/class_methods.rb +13 -0
- data/lib/acts_as_executor/task/model/instance_methods.rb +64 -0
- data/lib/acts_as_executor/task/model/instance_support_methods.rb +32 -0
- data/lib/acts_as_executor/validators/class_exists_validator.rb +1 -1
- data/lib/acts_as_executor/validators/class_includes_validator.rb +10 -0
- data/lib/acts_as_executor/version.rb +1 -1
- data/lib/generators/{executor_generator.rb → acts_as_executor_generator.rb} +1 -5
- data/lib/generators/templates/migration/create_executors.rb +2 -2
- data/spec/acts_as_executor_spec.rb +22 -0
- data/spec/common/future_task_spec.rb +21 -0
- data/spec/common/instance_support_methods_spec.rb +25 -0
- data/spec/common/units_spec.rb +19 -0
- data/spec/executor/factory_spec.rb +31 -0
- data/spec/executor/model/class_methods_spec.rb +49 -0
- data/spec/executor/model/instance_methods_spec.rb +150 -0
- data/spec/executor/model/instance_support_methods_spec.rb +70 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/blueprints.rb +20 -0
- data/spec/support/classes.rb +55 -0
- data/spec/support/custom_matchers.rb +26 -0
- data/spec/support/database_connection.rb +4 -0
- data/spec/task/clazz_spec.rb +42 -0
- data/spec/task/model/class_methods_spec.rb +13 -0
- data/spec/task/model/instance_methods_spec.rb +80 -0
- data/spec/task/model/instance_support_methods_spec.rb +56 -0
- data/spec/task/schedules_spec.rb +11 -0
- data/spec/validators/class_exists_validator_spec.rb +21 -0
- data/spec/validators/class_includes_validator_spec.rb +21 -0
- metadata +88 -21
- data/README.rdoc +0 -67
- data/lib/acts_as_executor/executor/kinds.rb +0 -16
- data/lib/acts_as_executor/executor/model/actions.rb +0 -65
- data/lib/acts_as_executor/executor/model/associations.rb +0 -11
- data/lib/acts_as_executor/executor/model/attributes.rb +0 -16
- data/lib/acts_as_executor/executor/model/base.rb +0 -24
- data/lib/acts_as_executor/executor/model/helpers.rb +0 -25
- data/lib/acts_as_executor/executor/model/validations.rb +0 -13
- data/lib/acts_as_executor/task/model/actions.rb +0 -34
- data/lib/acts_as_executor/task/model/associations.rb +0 -11
- data/lib/acts_as_executor/task/model/attributes.rb +0 -16
- data/lib/acts_as_executor/task/model/base.rb +0 -15
- data/lib/acts_as_executor/task/model/helpers.rb +0 -14
- data/lib/acts_as_executor/task/model/validations.rb +0 -16
- data/lib/generators/templates/initializer/acts_as_executor.rb +0 -4
data/README.rdoc
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
=acts_as_executor
|
2
|
-
acts_as_executor seamlessly integrates Java's Executor framework with JRuby on Rails, giving an application the ability to interact with executors in a familiar Rails'eque way.
|
3
|
-
|
4
|
-
==Features
|
5
|
-
* Database persisted, executor and task configurations
|
6
|
-
* Create and delete both executors and tasks dynamically at runtime
|
7
|
-
* Automatic management of completed tasks
|
8
|
-
|
9
|
-
==Getting Started
|
10
|
-
Rails 3 Gemfile
|
11
|
-
gem "acts_as_executor"
|
12
|
-
Install via
|
13
|
-
gem install acts_as_executor --pre
|
14
|
-
# or
|
15
|
-
bundle install
|
16
|
-
|
17
|
-
====Generate & Migrate
|
18
|
-
rails generate executor <ModelName>
|
19
|
-
|
20
|
-
e.g.
|
21
|
-
rails generate executor Executor
|
22
|
-
create config/initializers/acts_as_executor.rb
|
23
|
-
create app/models/executor.rb
|
24
|
-
create app/models/executor_task.rb
|
25
|
-
create db/migrate/20110601230311_create_executors.rb
|
26
|
-
rake db:migrate
|
27
|
-
|
28
|
-
====Create Executor
|
29
|
-
Executor.create(:name => "cached_executor",
|
30
|
-
:kind => ActsAsExecutor::Executor::Kinds::CACHED)
|
31
|
-
====Create Scheduled Executor
|
32
|
-
Executor.create(:name => "scheduled_executor",
|
33
|
-
:kind => ActsAsExecutor::Executor::Kinds::SCHEDULED,
|
34
|
-
:size => 3)
|
35
|
-
====Create Task
|
36
|
-
e = Executor.find_by_name("cached_executor")
|
37
|
-
e.tasks.create(:clazz => "HelloWorldTask",
|
38
|
-
:arguments => { :message => "This is my message")
|
39
|
-
====Create Scheduled Task
|
40
|
-
e = Executor.find_by_name("scheduled_executor")
|
41
|
-
e.tasks.create(:clazz => "HelloWorldTask",
|
42
|
-
:arguments => { :message => "This is my scheduled message" },
|
43
|
-
:schedule => ActsAsExecutor::Task::Schedules::FIXED_DELAY,
|
44
|
-
:start => 1,
|
45
|
-
:every => 5,
|
46
|
-
:units => ActsAsExecutor::Common::Units::MINUTES)
|
47
|
-
|
48
|
-
====Example Task
|
49
|
-
class HelloWorldTask
|
50
|
-
include Java::java.lang.Runnable
|
51
|
-
|
52
|
-
attr_accessor :message
|
53
|
-
|
54
|
-
def run
|
55
|
-
p "Hello World. " + message
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
==Notes
|
60
|
-
Upon a task completing its execution on a non-scheduled executor, the task will be delete from the database. Due to the possiblity that multiple threads may be attempting to delete records simultaneously, it is recommended NOT to use SQLite as a database provider. In this scenario, database locking may occur causing records to fail deletion and thus exist for tasks that have actually completed thier execution.
|
61
|
-
|
62
|
-
==What's New in Release 1.0.0.beta2
|
63
|
-
* Support for all executor types, scheduled and non-scheduled
|
64
|
-
* Executors can be created and deleted at runtime
|
65
|
-
* Tasks can be created and added to executors at runtime
|
66
|
-
* Automatic management of completed tasks on non-scheduled executors
|
67
|
-
* Custom logger can now be set via initializer
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Executor
|
3
|
-
class Kinds
|
4
|
-
CACHED = "cached"
|
5
|
-
FIXED = "fixed"
|
6
|
-
SINGLE = "single"
|
7
|
-
|
8
|
-
SCHEDULED = "scheduled"
|
9
|
-
SINGLE_SCHEDULED = "single_scheduled"
|
10
|
-
|
11
|
-
ALL = [ CACHED, FIXED, SINGLE, SCHEDULED, SINGLE_SCHEDULED ]
|
12
|
-
ALL_SCHEDULED = [ SCHEDULED, SINGLE_SCHEDULED ]
|
13
|
-
REQUIRING_SIZE = [ FIXED, SCHEDULED ]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Executor
|
3
|
-
module Model
|
4
|
-
module Actions
|
5
|
-
def self.included base
|
6
|
-
base.after_find :startup, :if => :startup_now?
|
7
|
-
base.after_save :startup, :if => :startup_now?
|
8
|
-
|
9
|
-
base.after_destroy :shutdown, :if => :shutdown_now?
|
10
|
-
end
|
11
|
-
|
12
|
-
def startup
|
13
|
-
ActsAsExecutor.log.debug "Executor \"" + name + "\" starting up..."
|
14
|
-
self.executor = ActsAsExecutor::Executor::Factory.create kind, size
|
15
|
-
ActsAsExecutor.log.info "Executor \"" + name + "\" has completed startup"
|
16
|
-
|
17
|
-
tasks.all
|
18
|
-
end
|
19
|
-
|
20
|
-
def shutdown
|
21
|
-
ActsAsExecutor.log.debug "Executor \"" + name + "\" shutting down..."
|
22
|
-
begin
|
23
|
-
self.executor.shutdown
|
24
|
-
rescue Java::java.lang.RuntimePermission
|
25
|
-
ActsAsExecutor.log.error "Executor \"" + name + "\" has experienced a RuntimePermission error"
|
26
|
-
rescue Java::java.lang.SecurityException
|
27
|
-
ActsAsExecutor.log.error "Executor \"" + name + "\" has experienced a SecurityException error"
|
28
|
-
end
|
29
|
-
ActsAsExecutor.log.info "Executor \"" + name + "\" has completed shutdown"
|
30
|
-
end
|
31
|
-
|
32
|
-
def execute clazz, schedule, start, every, units
|
33
|
-
begin
|
34
|
-
if schedulable?
|
35
|
-
units = Java::java.util.concurrent.TimeUnit.value_of(units.upcase)
|
36
|
-
case schedule
|
37
|
-
when ActsAsExecutor::Task::Schedules::ONE_SHOT
|
38
|
-
future = self.executor.schedule clazz, start, units
|
39
|
-
when ActsAsExecutor::Task::Schedules::FIXED_DELAY
|
40
|
-
future = self.executor.schedule_with_fixed_delay clazz, start, every, units
|
41
|
-
when ActsAsExecutor::Task::Schedules::FIXED_RATE
|
42
|
-
future = self.executor.schedule_at_fixed_rate clazz, start, every, units
|
43
|
-
end
|
44
|
-
else
|
45
|
-
case clazz
|
46
|
-
when Java::java.util.concurrent.Callable
|
47
|
-
future = ActsAsExecutor::Common::FutureTask.new clazz
|
48
|
-
when Java::java.lang.Runnable
|
49
|
-
future = ActsAsExecutor::Common::FutureTask.new clazz, nil
|
50
|
-
end
|
51
|
-
self.executor.execute future
|
52
|
-
end
|
53
|
-
return future
|
54
|
-
rescue Java::java.lang.NullPointerException => e
|
55
|
-
ActsAsExecutor.log.error "Executor \"" + name + "\" attaching task threw a NullPointerException. " + e.to_s
|
56
|
-
rescue Java::java.lang.IllegalArgumentException => e
|
57
|
-
ActsAsExecutor.log.error "Executor \"" + name + "\" attaching task threw a IllegalArgumentException. " + e.to_s
|
58
|
-
rescue Java::java.util.concurrent.RejectedExecutionException => e
|
59
|
-
ActsAsExecutor.log.error "Executor \"" + name + "\" attaching task threw a RejectedExecutionException. " + e.to_s
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Executor
|
3
|
-
module Model
|
4
|
-
module Base
|
5
|
-
def acts_as_executor
|
6
|
-
send :include, ActsAsExecutor::Executor::Model::Actions
|
7
|
-
send :include, ActsAsExecutor::Executor::Model::Associations
|
8
|
-
send :include, ActsAsExecutor::Executor::Model::Attributes
|
9
|
-
send :include, ActsAsExecutor::Executor::Model::Helpers
|
10
|
-
send :include, ActsAsExecutor::Executor::Model::Validations
|
11
|
-
|
12
|
-
if ActsAsExecutor.rails_startup?
|
13
|
-
all
|
14
|
-
at_exit do
|
15
|
-
all.each do |e|
|
16
|
-
e.shutdown
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Executor
|
3
|
-
module Model
|
4
|
-
module Helpers
|
5
|
-
def startup_now?
|
6
|
-
if self.executor == nil && ActsAsExecutor.rails_startup?
|
7
|
-
return true
|
8
|
-
end
|
9
|
-
return false
|
10
|
-
end
|
11
|
-
|
12
|
-
def shutdown_now?
|
13
|
-
if self.executor != nill && ActsAsExecutor.rails_startup?
|
14
|
-
return true
|
15
|
-
end
|
16
|
-
return false
|
17
|
-
end
|
18
|
-
|
19
|
-
def schedulable?
|
20
|
-
ActsAsExecutor::Executor::Kinds::ALL_SCHEDULED.include? kind
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Executor
|
3
|
-
module Model
|
4
|
-
module Validations
|
5
|
-
def self.included base
|
6
|
-
base.validates :name, :presence => true, :uniqueness => true
|
7
|
-
base.validates :kind, :inclusion => { :in => ActsAsExecutor::Executor::Kinds::ALL }
|
8
|
-
base.validates :size, :numericality => { :only_integer => true, :greater_than_or_equal_to => 1 }, :if => "ActsAsExecutor::Executor::Kinds::REQUIRING_SIZE.include? kind"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Task
|
3
|
-
module Model
|
4
|
-
module Actions
|
5
|
-
def self.included base
|
6
|
-
base.serialize :arguments, Hash
|
7
|
-
|
8
|
-
base.after_find :execute, :if => :execute_now?
|
9
|
-
base.after_save :execute, :if => :execute_now?
|
10
|
-
end
|
11
|
-
|
12
|
-
def execute
|
13
|
-
begin
|
14
|
-
instance = clazz.constantize.new
|
15
|
-
rescue NameError
|
16
|
-
ActsAsExecutor.log.error "Task creating task could not create class"
|
17
|
-
end
|
18
|
-
|
19
|
-
if arguments
|
20
|
-
arguments.each_pair do |k, v|
|
21
|
-
attribute = "#{k}="
|
22
|
-
instance.send attribute, v if instance.respond_to? attribute
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
self.future = executor.execute instance, schedule, start, every, units
|
27
|
-
if !executor.schedulable?
|
28
|
-
self.future.task = self
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Task
|
3
|
-
module Model
|
4
|
-
module Base
|
5
|
-
def acts_as_executor_task
|
6
|
-
send :include, ActsAsExecutor::Task::Model::Actions
|
7
|
-
send :include, ActsAsExecutor::Task::Model::Associations
|
8
|
-
send :include, ActsAsExecutor::Task::Model::Attributes
|
9
|
-
send :include, ActsAsExecutor::Task::Model::Helpers
|
10
|
-
send :include, ActsAsExecutor::Task::Model::Validations
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module ActsAsExecutor
|
2
|
-
module Task
|
3
|
-
module Model
|
4
|
-
module Validations
|
5
|
-
def self.included base
|
6
|
-
base.validates :executor_id, :presence => true
|
7
|
-
base.validates :clazz, :presence => true, :class_exists => true
|
8
|
-
base.validates :schedule, :inclusion => { :in => ActsAsExecutor::Task::Schedules::ALL }, :if => "executor and executor.schedulable?"
|
9
|
-
base.validates :start, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }, :if => "executor and executor.schedulable?"
|
10
|
-
base.validates :every, :numericality => { :only_integer => true, :greater_than_or_equal_to => 1 }, :if => "executor and executor.schedulable? and schedule != ActsAsExecutor::Task::Schedules::ONE_SHOT"
|
11
|
-
base.validates :units, :inclusion => { :in => ActsAsExecutor::Common::Units::ALL }, :if => "executor and executor.schedulable?"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|