trinidad_scheduler_extension 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ == TrinidadScheduler Extension
2
+
3
+ Copyright (c) 2011 Brandon Dewitt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ == Additional Bundled Software
25
+
26
+ Quartz Scheduler is licensed according to the terms of Apache License, Version 2.0 (current). See http://www.apache.org/licenses/LICENSE-2.0 for details.
data/README ADDED
@@ -0,0 +1,127 @@
1
+ Trinidad Scheduler Extension
2
+ ===
3
+ Trinidad Scheduler uses Quartz to schedule processes for execution. It can be run as a server extension to Trinidad and/or a Web Application extension
4
+ for Trinidad. If run as a Server extension all schedulers will get the server configuration options each option that is defined at the Web Application
5
+ level will override the Server option.
6
+
7
+ Trinidad Scheduler creates a unique scheduler for each web application.
8
+
9
+ Most processes we schedule are scheduled using the *Cron* Trigger and *run_later*
10
+
11
+ Install Gem
12
+ ---
13
+ gem install trinidad_scheduler_extension
14
+
15
+ Configure Trinidad
16
+ ---
17
+ In either the Server *extensions* block or the Web Application *extentions* block add "scheduler"
18
+
19
+ extensions:
20
+ scheduler:
21
+
22
+ Example Usage
23
+ ---
24
+ It is valid to use the top level scheduling methods and run_later together
25
+
26
+ class ScheduledLog < TrinidadScheduler.Cron "0/5 * * * * ?"
27
+ def run
28
+ _logger.info "Executed every 5 seconds"
29
+
30
+ TrinidadScheduler.run_later do
31
+ _logger.info "Executed after a 3 second delay"
32
+ end
33
+ end
34
+ end
35
+
36
+ Laziness
37
+ ---
38
+ Trinidad Scheduler is very lazy. Schedulers will only be instantiated when they are needed to execute a job or to setup a schedule for execution.
39
+ This laziness extends to even runtime definition of classes and use of run_later in conditional statements. When a run_later block is encountered or
40
+ a class is defined at runtime that inherits from a TrinidadScheduler base method the scheduler will be created and started (if it does not exist)
41
+
42
+ If schedules are defined during application initialization then the scheduler will not be started until after the application is started by Tomcat.
43
+
44
+ (The lazy nature of TrinidadScheduler also gives the user time to define a logger outstide of the default configured log4j StdOut logger that
45
+ is included with TrinidadScheduler)
46
+
47
+ Usage
48
+ ===
49
+ The extension defines several methods that return classes based on the configuration options provided. These methods map to the scheduler trigger type
50
+ that Quartz provides. The implemented triggers are CronTrigger, SimpleTrigger, and DateIntervalTrigger.
51
+
52
+ Cron Trigger
53
+ ---
54
+ To define a process to be run based on a [cron expression] (http://en.wikipedia.org/wiki/CRON_expression#CRON_expression)
55
+
56
+ class ScheduledClass < TrinidadScheduler.Cron "0/5 * * * * ?"
57
+ def run
58
+ _logger.info "I am printed every 5 seconds"
59
+ end
60
+ end
61
+
62
+ The method *TrinidadScheduler.Cron* takes a cron expression as it's only argument and returns a class. This anonymous class is the parent of
63
+ ScheduledClass and does the work to wrap ScheduledClass for use as a CronTrigger in Quartz.
64
+
65
+ The instance method "run" must be defined because it is called when the scheduled process is triggered. *_logger* is an instance variable available
66
+ in ScheduledClass which gives the class access to the Quartz logger that is configured.
67
+
68
+ Simple Trigger
69
+ ---
70
+ Schedule an INFO log message every 5 seconds starting now, setting the end is not necessary in this context, but is done
71
+
72
+ class TestJob < TrinidadScheduler.Simple :start => Time.now, :end => Time.now + 240, :repeat 3, :interval => 5000
73
+ def run
74
+ _logger.info "I am inside this block" #=> prints "I am inside this block" every 5 seconds
75
+ end
76
+ end
77
+
78
+ The Simple Trigger will execute based on options passed to the method *TrinidadScheduler.Simple*, the options available are outlined
79
+ above in the example, none of them are necessary if you only want to trigger the process once. You can define a start and end time as well as how many
80
+ times to fire the trigger along with an interval to be observed between trigger execution.
81
+
82
+ DateInterval Trigger
83
+ ---
84
+ Schedule an INFO log message every 5 seconds starting now and ending after 4 minutes
85
+
86
+ class TestJob < TrinidadScheduler.DateInterval :start => Time.now, :end => Time.now + 240, :unit => :second, :interval => 5
87
+ def run
88
+ _logger.info "I am inside this block" #=> prints "I am inside this block" every 5 seconds
89
+ end
90
+ end
91
+
92
+ The DateInterval Trigger will execute a triggered process based on the configuration options passed. For more information on using the DateInterval
93
+ trigger consult the source.
94
+
95
+ run_later
96
+ ---
97
+ Schedules a block of code to run in another Thread after execution proceeds in the current Thread
98
+ *after the job runs it removes itself from the job scheduler
99
+
100
+ Using run_later with default 3 second delay
101
+
102
+ TrinidadScheduler.run_later do
103
+ _logger.info "I am inside this block" #=> prints "I am inside this block"
104
+ end
105
+
106
+ Using run_later with 20 second delay
107
+
108
+ TrinidadScheduler.run_later(:delay => 20) do
109
+ _logger.info "I am inside this block" #=> prints "I am inside this block"
110
+ end
111
+
112
+ Behind the scemes *run_later* is actually implemented using an anonymous class that inherits from TrinidadScheduler.Simple to schedule the run.
113
+
114
+
115
+ Inspiration
116
+ ---
117
+ Open Source software is a community effort - thanks to all, but the following were instrumental in the inspiration for TrinidadScheduler.
118
+
119
+ [techwhizbang] (https://github.com/techwhizbang/jruby-quartz) for handling of Quartz JobFactory
120
+ [why_metaid] (https://github.com/evaryont/why_metaid) for metaid extension
121
+ [TERRACOTTA] (http://www.terracotta.org/) for continued support Quartz Scheduler
122
+ [calavera] (https://github.com/calavera/trinidad) for Trinidad Server
123
+
124
+
125
+ Copyright
126
+ ---
127
+ Copyright (c) 2011 Brandon Dewitt<brandon+trinidad_scheduler@myjibe.com>. See LICENSE for details.
@@ -0,0 +1,22 @@
1
+ require 'java'
2
+
3
+ require 'trinidad'
4
+ require 'trinidad/jars'
5
+
6
+ # Jar files that are needed
7
+ require 'trinidad_scheduler_extension/jars/log4j-1.2.16'
8
+ require "trinidad_scheduler_extension/jars/slf4j-api-1.6.1"
9
+ require "trinidad_scheduler_extension/jars/slf4j-log4j12-1.6.1"
10
+ require "trinidad_scheduler_extension/jars/quartz-1.8.4"
11
+
12
+ # Trinidad Scheduler Extension files
13
+ require 'trinidad_scheduler_extension/version.rb'
14
+ require 'trinidad_scheduler_extension/trinidad_scheduler'
15
+ require 'trinidad_scheduler_extension/extensions/object'
16
+ require 'trinidad_scheduler_extension/scheduler_listener'
17
+ require 'trinidad_scheduler_extension/job_detail'
18
+ require 'trinidad_scheduler_extension/job_factory'
19
+ require 'trinidad_scheduler_extension/scheduled_job'
20
+ require 'trinidad_scheduler_extension/app_job'
21
+ require 'trinidad_scheduler_extension/scheduler_extension'
22
+
@@ -0,0 +1,152 @@
1
+ module TrinidadScheduler
2
+ module AppJob
3
+ include org.quartz.Job
4
+ include TrinidadScheduler::ScheduledJob
5
+
6
+ def self.included(other_obj)
7
+ new_job = TrinidadScheduler::JobDetail.new("#{ other_obj.job_detail_name rescue other_obj }", "#{other_obj}", other_obj)
8
+ begin
9
+ TrinidadScheduler[$servlet_context].schedule_job(new_job, other_obj.trigger)
10
+ rescue Exception => ex
11
+ raise JobError.new(ex)
12
+ end
13
+ end
14
+ end
15
+
16
+ # Method to schedule a block of code to run in another Thread after execution proceeds in the current Thread
17
+ # after the job runs it removes itself from the job scheduler
18
+ #
19
+ # @example Running run_later with default 3 second delay
20
+ # TrinidadScheduler.run_later do
21
+ # _logger.info "I am inside this block" #=> prints "I am inside this block"
22
+ # end
23
+ #
24
+ # @example Running run_later with 20 second delay
25
+ # TrinidadScheduler.run_later(:delay => 20) do
26
+ # _logger.info "I am inside this block" #=> prints "I am inside this block"
27
+ # end
28
+ #
29
+ # @param [Hash] opts the options for the process to be run
30
+ # @option opts [Integer] :delay the number of seconds delay before the block is triggered
31
+ # @param [Block] the block that will be run in a separate Thread after the delay
32
+ def self.run_later(opts={:delay=>3}, &blk)
33
+ Class.new(TrinidadScheduler.Simple :start => (Time.now + opts[:delay])) do
34
+ meta_def(:job_detail_name){ Time.now.to_i.to_s << Time.now.usec.to_s }
35
+ meta_def(:run_proc){ blk }
36
+
37
+ def run
38
+ self.class.run_proc.call
39
+ end
40
+ end
41
+ end
42
+
43
+ # Method to return an inheritable class for scheduling a CronTrigger Job
44
+ # the class that inherits from this method will have it's instance run method executed based on the cron_expression
45
+ #
46
+ # @example Schedule an INFO log message every 5 seconds
47
+ # class TestJob < TrinidadScheduler.Cron "0/5 * * * * ?"
48
+ # def run
49
+ # _logger.info "I am inside this block" #=> prints "I am inside this block" every 5 seconds
50
+ # end
51
+ # end
52
+ #
53
+ # @param [String] cron_expression the Cron Expression that defines the CronTrigger for the job class
54
+ # @return [Class] a new Class that is run by the CronTrigger that is defined
55
+ def self.Cron(cron_expression)
56
+ Class.new do
57
+ meta_def(:cron){ cron_expression }
58
+
59
+ def self.inherited(subclass)
60
+ meta_def :trigger do
61
+ org.quartz.CronTrigger.new("#{subclass}" + ".trigger", "#{subclass}", self.cron)
62
+ end
63
+
64
+ subclass.send(:include, TrinidadScheduler::AppJob)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Method to return an inheritable class for scheduling a SimpleTrigger Job
70
+ # the class that inherits from this method will have it's instance run method executed based on the options passed
71
+ #
72
+ # @example Schedule an INFO log message every 5 seconds starting now, setting the end is not necessary in this context, but it done
73
+ # class TestJob < TrinidadScheduler.Simple :start => Time.now, :end => Time.now + 240, :repeat 3, :interval => 5000
74
+ # def run
75
+ # _logger.info "I am inside this block" #=> prints "I am inside this block" every 5 seconds
76
+ # end
77
+ # end
78
+ #
79
+ # @param [Hash] opts the options for the SimpleTrigger
80
+ # @option opts [java.util.Date, Time] :start the starting time of the trigger
81
+ # @option opts [java.util.Date, Time] :end the ending time of the trigger
82
+ # @option opts [Integer] :repeat the number of times to repeat the job (defaults to 0)
83
+ # @option opts [Integer] :interval the number of milliseconds between runs
84
+ # @return [Class] a new anonymous Class that is the parent of the Class run by the SimpleTrigger that is defined
85
+ def self.Simple(opts={})
86
+ opts[:start] ||= java.util.Date.new(Time.now.to_i*1000)
87
+ opts[:start] = java.util.Date.new(opts[:start].to_i*1000) if opts[:start].class == Time
88
+
89
+ opts[:end] ||= java.util.Date.new((Time.now + 10.years).to_i*1000)
90
+ opts[:end] = java.util.Date.new(opts[:end].to_i*1000) if opts[:end].class == Time
91
+
92
+ opts[:repeat] ||= 0
93
+ opts[:interval] ||= 0
94
+
95
+ Class.new do
96
+ meta_def(:opts){ opts }
97
+
98
+ def self.inherited(subclass)
99
+ meta_def :trigger do
100
+ org.quartz.SimpleTrigger.new("#{subclass}" + ".trigger", "#{subclass}",
101
+ self.opts[:start], self.opts[:end],
102
+ self.opts[:repeat], self.opts[:interval])
103
+ end
104
+
105
+ subclass.send(:include, TrinidadScheduler::AppJob)
106
+ end
107
+ end
108
+ end
109
+
110
+ # Method to return an inheritable class for scheduling a DateIntervalTrigger Job
111
+ # the class that inherits from this method will have it's instance run method executed based on the options passed
112
+ #
113
+ # @example Schedule an INFO log message every 5 seconds starting now and ending after 4 minutes
114
+ # class TestJob < TrinidadScheduler.DateInterval :start => Time.now, :end => Time.now + 240, :unit => :second, :interval => 5
115
+ # def run
116
+ # _logger.info "I am inside this block" #=> prints "I am inside this block" every 5 seconds
117
+ # end
118
+ # end
119
+ #
120
+ # @param [Hash] opts the options for the DateIntervalTrigger
121
+ # @option opts [java.util.Date, Time] :start the starting time of the trigger
122
+ # @option opts [java.util.Date, Time] :end the ending time of the trigger
123
+ # @option opts [Symbol, String] :unit the defined unit (:day, :second, :year, :month, :week)
124
+ # @option opts [Integer] :interval the number of units between runs
125
+ # @return [Class] a new anonymous Class that is the parent of the Class run by the SimpleTrigger that is defined
126
+ def self.DateInterval(opts={})
127
+ opts[:start] ||= java.util.Date.new(Time.now.to_i*1000)
128
+ opts[:start] = java.util.Date.new(opts[:start].to_i*1000) if opts[:start].class == Time
129
+
130
+ opts[:end] ||= java.util.Date.new((Time.now + 10.years).to_i*1000)
131
+ opts[:end] = java.util.Date.new(opts[:end].to_i*1000) if opts[:end].class == Time
132
+
133
+ opts[:unit] ||= :day
134
+ opts[:unit] = org.quartz.DateIntervalTrigger::IntervalUnit.value_of(opts[:unit].to_s.upcase)
135
+
136
+ opts[:interval] ||= 1
137
+
138
+ Class.new do
139
+ meta_def(:opts){ opts }
140
+
141
+ def self.inherited(subclass)
142
+ meta_def :trigger do
143
+ org.quartz.DateIntervalTrigger.new("#{subclass}" + ".trigger", "#{subclass}",
144
+ self.opts[:start], self.opts[:end],
145
+ self.opts[:unit], self.opts[:interval])
146
+ end
147
+
148
+ subclass.send(:include, TrinidadScheduler::AppJob)
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,11 @@
1
+ #
2
+ # our log4j properties / configuration file
3
+ #
4
+ # STDOUT appender
5
+ log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
6
+ log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
7
+ log4j.appender.STDOUT.layout.ConversionPattern=%d %p [%t] %C{1} - %m\n
8
+
9
+ # use the STDOUT appender. set the level to INFO.
10
+ log4j.rootLogger=INFO, STDOUT
11
+
@@ -0,0 +1,12 @@
1
+ # Metaid == a few simple metaclass helper
2
+ # (See http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html.)
3
+ class Object
4
+ # The hidden singleton lurks behind everyone
5
+ def metaclass; class << self; self; end; end
6
+ def meta_eval &blk; metaclass.instance_eval &blk; end
7
+
8
+ # Adds methods to a metaclass
9
+ def meta_def name, &blk
10
+ meta_eval { define_method name, &blk }
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module TrinidadScheduler
2
+ class JobDetail < org.quartz.JobDetail
3
+
4
+ attr_accessor :job
5
+
6
+ def initialize(name, group, job_class)
7
+ super()
8
+ set_name name
9
+ set_group group
10
+ @job = job_class.new
11
+ end
12
+
13
+ def validate()
14
+ raise org.quartz.SchedulerException.new("Job's name cannot be null",
15
+ org.quartz.SchedulerException.ERR_CLIENT_ERROR) if get_name == nil
16
+ raise org.quartz.SchedulerException.new("Job's group cannot be null",
17
+ org.quartz.SchedulerException.ERR_CLIENT_ERROR) if get_group == nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module TrinidadScheduler
2
+ class JobFactory
3
+ include org.quartz.spi.JobFactory
4
+
5
+ def new_job bundle
6
+ bundle.get_job_detail.job
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ module TrinidadScheduler
2
+ module ScheduledJob
3
+ class JobError < StandardError; end
4
+
5
+ attr_accessor :_context
6
+ attr_accessor :_logger
7
+
8
+ def run
9
+ raise "Implement a [run] method if you are going to use #{self.class} as a job class"
10
+ end
11
+
12
+ def execute(context)
13
+ begin
14
+ @_context = context
15
+ @_logger = org.apache.log4j.Logger.getLogger("#{self.class}")
16
+ run()
17
+ rescue Exception => ex
18
+ raise JobError.new(ex)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ module Trinidad
2
+ module Extensions
3
+
4
+ class SchedulerWebAppExtension < WebAppExtension
5
+
6
+ def configure(tomcat, app_context)
7
+ app_context.add_lifecycle_listener(TrinidadScheduler::WebAppListener.new(app_context.servlet_context, @options))
8
+ end
9
+ end
10
+
11
+ class SchedulerServerExtension < ServerExtension
12
+
13
+ def configure(tomcat)
14
+ tomcat.get_host.add_container_listener(TrinidadScheduler::GlobalListener.new(@options))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module TrinidadScheduler
2
+ class WebAppListener
3
+ include org.apache.catalina.LifecycleListener
4
+
5
+ def initialize(servlet_context, options)
6
+ @servlet_context = servlet_context
7
+ @options = options
8
+ TrinidadScheduler.store_scheduler_options(@servlet_context, @options)
9
+ end
10
+
11
+ def needs_started?
12
+ TrinidadScheduler.scheduler_exists?(@servlet_context) && !TrinidadScheduler[@servlet_context].is_started
13
+ end
14
+
15
+ def lifecycle_event(event)
16
+ case event.type
17
+ when org.apache.catalina.Lifecycle::START_EVENT then
18
+ if needs_started?
19
+ TrinidadScheduler[@servlet_context].start
20
+ TrinidadScheduler[@servlet_context].resume_all
21
+ end
22
+
23
+ TrinidadScheduler.set_servlet_started(@servlet_context)
24
+ end
25
+ end
26
+ end
27
+
28
+ class GlobalListener
29
+ include org.apache.catalina.ContainerListener
30
+
31
+ def initialize(options)
32
+ @options = options
33
+ end
34
+
35
+ def container_event(event)
36
+ case event.type
37
+ when org.apache.catalina.Container::ADD_CHILD_EVENT then
38
+ event.data.add_lifecycle_listener(TrinidadScheduler::WebAppListener.new(event.data.servlet_context, @options))
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,131 @@
1
+ module TrinidadScheduler
2
+ CONFIG_HOME = File.expand_path(File.dirname(__FILE__) + "/trinidad_scheduler_extension/config")
3
+ JAR_HOME = File.expand_path(File.dirname(__FILE__) + "/trinidad_scheduler_extension/jars")
4
+
5
+ # Sets log4j properties if not established by Application Servers
6
+ # TrinidadScheduler is really lazy so this is only set when a scheduler is needed
7
+ def self.trinidad_scheduler_init_log4j
8
+ if java.lang.System.get_property('log4j.configuration').nil?
9
+ java.lang.System.set_property('log4j.configuration', java.io.File.new("#{CONFIG_HOME}/log4j.properties").to_url.to_s)
10
+ end
11
+ end
12
+
13
+ # Standardizing the naming of the variables that are stored on the context
14
+ def self.context_path(path)
15
+ path.gsub("/", "") == "" ? "Default" : path.gsub("/", "").capitalize
16
+ end
17
+
18
+ # Assists in lazily evaluating if a scheduler is needed for a context
19
+ #
20
+ # @param [ServletContext] context
21
+ # @return [Boolean]
22
+ def self.scheduler_exists?(context)
23
+ !!context.get_attribute(scheduler_name(context))
24
+ end
25
+
26
+ # Tomcat event callbacks are good for static systems but JRuby allows dynamic definition of classes and function
27
+ # so I am storing a variable on the servlet context that allow the extension to check if the servlet has been started
28
+ # during lazy evaluation of the need for a scheduler and/or starting the scheduler
29
+ #
30
+ # @param [ServletContext] context
31
+ # @return [Boolean]
32
+ def self.servlet_started?(context)
33
+ !!context.get_attribute(started_name(context))
34
+ end
35
+
36
+ # Helper to centralize the operations on the servlet contexts, sets the servlet started variable when the context is started, reguardless of whether
37
+ # a scheduler exists or not
38
+ #
39
+ # @param [ServletContext] context
40
+ def self.set_servlet_started(context)
41
+ context.set_attribute(started_name(context), true)
42
+ end
43
+
44
+ # Helper method that attaches the configuration options from the Trinidad config file to the ServletContext
45
+ #
46
+ # @param [ServletContext] context
47
+ # @param [Hash] options
48
+ def self.store_scheduler_options(context, options)
49
+ context.set_attribute(options_name(context), options)
50
+ end
51
+
52
+ # Centralized definition of where variables will be stored on the ServletContext
53
+ def self.started_name(context)
54
+ "TrinidadScheduler::#{context_path(context.context_path)}::ServletStarted"
55
+ end
56
+
57
+ def self.options_name(context)
58
+ "TrinidadScheduler::#{context_path(context.context_path)}::SchedulerOptions"
59
+ end
60
+
61
+ def self.scheduler_name(context)
62
+ "TrinidadScheduler::#{context_path(context.context_path)}::Scheduler"
63
+ end
64
+
65
+ # Bracket accessor defined to retreive the scheduler for a context
66
+ # if no scheduler is attached to the context then one is created and attached at time of access and returned
67
+ #
68
+ # @param [ServletContext] context
69
+ # @return [org.quartz.impl.StdScheduler]
70
+ def self.[](context)
71
+ if !scheduler_exists?(context)
72
+ self.trinidad_scheduler_init_log4j
73
+ self[context] = self.quartz_scheduler(context, context.get_attribute(options_name(context)))
74
+ end
75
+
76
+ scheduler = context.get_attribute(scheduler_name(context))
77
+
78
+ if !scheduler.is_started && servlet_started?(context)
79
+ scheduler.start
80
+ scheduler.resume_all
81
+ end
82
+
83
+ return scheduler
84
+ end
85
+
86
+ # Bracket assignment operator, will attach the scheduler passed to the context in the brackets
87
+ #
88
+ # @param [ServletContext] context
89
+ # @param [org.quartz.impl.StdScheduler] scheduler
90
+ def self.[]=(context, scheduler)
91
+ context.set_attribute(scheduler_name(context), scheduler)
92
+ end
93
+
94
+ # Method to build and return Quartz schedulers
95
+ #
96
+ # @param [ServletContext] context
97
+ # @param [Hash] opts, the options to configure the scheduler with
98
+ def self.quartz_scheduler(context, opts={})
99
+ options = {:wrapped => false, :thread_count => 10, :thread_priority => 5}
100
+ options.merge!(opts)
101
+ options[:name] = context_path(context.context_path)
102
+
103
+ scheduler_factory = org.quartz.impl.StdSchedulerFactory.new
104
+ scheduler_factory.initialize(quartz_properties(options))
105
+ scheduler = scheduler_factory.get_scheduler
106
+ scheduler.set_job_factory(TrinidadScheduler::JobFactory.new)
107
+ scheduler.pause_all
108
+ return scheduler
109
+ end
110
+
111
+ # Properties stream for initializing a scheduler
112
+ # Currently restricts schedulers to RAMJobStore and SimpleThreadPool
113
+ def self.quartz_properties(opts={})
114
+ prop_string = java.lang.String.new("
115
+ org.quartz.scheduler.rmi.export = false
116
+ org.quartz.scheduler.rmi.proxy = false
117
+ org.quartz.scheduler.wrapJobExecutionInUserTransaction = #{opts[:wrapped]}
118
+ org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
119
+ org.quartz.threadPool.threadCount = #{opts[:thread_count]}
120
+ org.quartz.threadPool.threadPriority = #{opts[:thread_priority]}
121
+ org.quartz.threadPool.threadNamePrefix = WorkerThread::#{opts[:name]}
122
+ org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
123
+ org.quartz.jobStore.misfireThreshold = 60000
124
+ org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore")
125
+
126
+ qp = java.util.Properties.new
127
+ qp.load(java.io.ByteArrayInputStream.new(prop_string.getBytes()))
128
+ qp.set_property("org.quartz.scheduler.instanceName", "Quartz::#{opts[:name]}::Application")
129
+ return qp
130
+ end
131
+ end
@@ -0,0 +1,3 @@
1
+ module TrinidadScheduler
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trinidad_scheduler_extension
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Brandon Dewitt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-06 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: trinidad_jars
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ description: Extension to support scheduled jobs in Trinidad
28
+ email: brandon+trinidad_scheduler@myjibe.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files:
34
+ - LICENSE
35
+ - README
36
+ files:
37
+ - LICENSE
38
+ - README
39
+ - lib/trinidad_scheduler_extension.rb
40
+ - lib/trinidad_scheduler_extension/app_job.rb
41
+ - lib/trinidad_scheduler_extension/config/log4j.properties
42
+ - lib/trinidad_scheduler_extension/extensions/object.rb
43
+ - lib/trinidad_scheduler_extension/jars/log4j-1.2.16.jar
44
+ - lib/trinidad_scheduler_extension/jars/quartz-1.8.4.jar
45
+ - lib/trinidad_scheduler_extension/jars/slf4j-api-1.6.1.jar
46
+ - lib/trinidad_scheduler_extension/jars/slf4j-log4j12-1.6.1.jar
47
+ - lib/trinidad_scheduler_extension/job_detail.rb
48
+ - lib/trinidad_scheduler_extension/job_factory.rb
49
+ - lib/trinidad_scheduler_extension/scheduled_job.rb
50
+ - lib/trinidad_scheduler_extension/scheduler_extension.rb
51
+ - lib/trinidad_scheduler_extension/scheduler_listener.rb
52
+ - lib/trinidad_scheduler_extension/trinidad_scheduler.rb
53
+ - lib/trinidad_scheduler_extension/version.rb
54
+ has_rdoc: true
55
+ homepage: https://github.com/bdewitt/trinidad_scheduler_extension
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.6.1
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: "Extension to support scheduled jobs in Trinidad: Extension"
82
+ test_files: []
83
+