lib/openwfe/expressions/timeout.rb in ruote-0.9.19 vs lib/openwfe/expressions/timeout.rb in ruote-0.9.20

- old
+ new

@@ -1,78 +1,61 @@ -# #-- -# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org -# All rights reserved. +# Copyright (c) 2007-2009, John Mettraux, jmettraux@gmail.com # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: # -# . Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. # -# . Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. # -# . Neither the name of the "OpenWFE" nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. +# Made in Japan. #++ -# -# -# "made in Japan" -# -# John Mettraux at openwfe.org -# require 'rufus/otime' -# -# Managing timeout for expressions like 'participant' and 'when' -# - module OpenWFE # # The timeout behaviour is implemented here, making it easy # to mix it in into ParticipantExpression and WhenExpression. # module TimeoutMixin include Rufus::Schedulable - attr_accessor \ - :timeout_at, - :timeout_job_id + attr_accessor :timeout_at + attr_accessor :timeout_job_id # # Looks for the "timeout" attribute in its process definition # and then sets the @timeout_at field (if there is a timeout). # - def determine_timeout (timeout_attname=:timeout) + def determine_timeout (workitem, timeout_attname=:timeout) #@timeout_at = nil #@timeout_job_id = nil - timeout = lookup_attribute(timeout_attname, @applied_workitem) - return unless timeout + s_timeout = lookup_attribute(timeout_attname, @applied_workitem) + return unless s_timeout - timeout = Rufus::parse_time_string(timeout) + timeout = Rufus::parse_time_string(s_timeout) @timeout_at = Time.new.to_f + timeout + + stamp_workitem(workitem, s_timeout) end # # Providing a default reschedule() implementation for the expressions # that use this mixin. @@ -83,13 +66,13 @@ end # # Combines a call to determine_timeout and to reschedule. # - def schedule_timeout (timeout_attname=:timeout) + def schedule_timeout (workitem, timeout_attname=:timeout) - determine_timeout(timeout_attname) + determine_timeout(workitem, timeout_attname) to_reschedule(get_scheduler) end #-- # Overrides the parent method to make sure a potential @@ -97,82 +80,105 @@ # # Well... Leave that to classes that mix this in... # No method override in a mixin... # #def reply_to_parent (workitem) - # unschedule_timeout() + # unschedule_timeout(workitem) # super(workitem) #end #++ # # Places a "__timed_out__" field in the workitem. # def set_timedout_flag (workitem) - workitem.attributes["__timed_out__"] = "true" + workitem.attributes['__timed_out__'] = 'true' end # # Removes any "__timed_out__" field in the workitem. # def remove_timedout_flag (workitem) - workitem.attributes.delete("__timed_out__") + workitem.attributes.delete('__timed_out__') end protected - # - # prefixed with "to_" for easy mix in - # - def to_reschedule (scheduler) + def stamp_workitem (wi, timeout) - #return if @timeout_job_id - # - # already rescheduled + return unless wi - return unless @timeout_at - # - # no need for a timeout + key = "#{@fei.wfid}__#{@fei.expid}" - @timeout_job_id = "timeout_#{self.fei.to_s}" + stamp = [ + self.class.name, @fei.expname, Time.now.to_f, timeout, @timeout_at + ] - scheduler.schedule_at( - @timeout_at, - { :schedulable => self, - :job_id => @timeout_job_id, - :do_timeout! => true, - :tags => [ "timeout", self.class.name ] }) + (wi.attributes['__timeouts__'] ||= {})[key] = stamp + end - ldebug do - "to_reschedule() will timeout at " + - "#{Rufus::to_iso8601_date(@timeout_at)}" + - " @timeout_job_id is #{@timeout_job_id}" + - " (oid #{object_id})" - end + def unstamp_workitem (wi) - #store_itself() - # - # done in the including expression - end + return unless wi - # - # Unschedules the timeout - # - def unschedule_timeout () + stamps = wi.attributes['__timeouts__'] + return unless stamps - ldebug do - "unschedule_timeout() " + - "@timeout_job_id is #{@timeout_job_id}" + - " (oid #{object_id})" - end + stamps.delete("#{@fei.wfid}__#{@fei.expid}") + end - #ldebug_callstack "unschedule_timeout()" + # + # prefixed with "to_" for easy mix in + # + def to_reschedule (scheduler) - get_scheduler.unschedule(@timeout_job_id) \ - if @timeout_job_id + #return if @timeout_job_id + # + # already rescheduled + + return unless @timeout_at + # + # no need for a timeout + + @timeout_job_id = "timeout_#{self.fei.to_s}" + + scheduler.schedule_at( + @timeout_at, + { :schedulable => self, + :job_id => @timeout_job_id, + :do_timeout! => true, + :tags => [ "timeout", self.class.name ] }) + + ldebug do + "to_reschedule() will timeout at " + + "#{Rufus::to_iso8601_date(@timeout_at)}" + + " @timeout_job_id is #{@timeout_job_id}" + + " (oid #{object_id})" end + + #store_itself() + # + # done in the including expression + end + + # + # Unschedules the timeout + # + def unschedule_timeout (workitem) + + #ldebug do + # "unschedule_timeout() " + + # "@timeout_job_id is #{@timeout_job_id}" + + # " (oid #{object_id})" + #end + + return unless @timeout_job_id + + get_scheduler.unschedule(@timeout_job_id) + unstamp_workitem(workitem) + end end end