lib/openwfe/expool/expstorage.rb in openwferu-0.9.16 vs lib/openwfe/expool/expstorage.rb in openwferu-0.9.17

- old
+ new

@@ -1,8 +1,8 @@ # #-- -# Copyright (c) 2006-2007, Nicolas Modryzk and John Mettraux, OpenWFE.org +# Copyright (c) 2006-2008, Nicolas Modryzk and John Mettraux, OpenWFE.org # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # @@ -38,13 +38,15 @@ # John Mettraux at openwfe.org # require 'fileutils' +#require 'rufus/lru' + require 'openwfe/service' -require 'openwfe/util/lru' require 'openwfe/flowexpressionid' +require 'openwfe/rudefinitions' module OpenWFE # @@ -61,33 +63,111 @@ ldebug { ":update for #{fei}" } self[fei] = fe end get_expression_pool.add_observer(:remove) do |channel, fei| ldebug { ":delete for #{fei}" } - self.delete(fei) + self.delete fei end end + # + # a human readable representation of the content of the expression + # storage. + # + # Warning : this will display the content of the real storage, + # (especially when called against a cache). + # def to_s s = "\n\n==== #{self.class} ====" - self.each do |k, v| + find_expressions.each do |fexp| + s << "\n" - if v.kind_of?(RawExpression) + if fexp.kind_of?(RawExpression) s << "*raw" else s << " " end - #s << v.to_s - s << v.fei.to_s - s << " key/value mismatch !" if k != v.fei + s << fexp.fei.to_s end s << "\n==== . ====\n" s end + + # + # This method is used by the various implementations of + # find_expressions() + # + def does_match? (options, fexp_or_fei) + + wfid = options[:wfid] + wfid_prefix = options[:wfid_prefix] + parent_wfid = options[:parent_wfid] + + wfname = options[:wfname] + wfrevision = options[:wfrevision] + + ic = options[:include_classes] + ec = options[:exclude_classes] + ic = Array(ic) if ic + ec = Array(ec) if ec + + cs = options[:consider_subprocesses] + + ap = options[:applied] + + fexp, fei = if fexp_or_fei.is_a?(FlowExpressionId) + [ nil, fexp_or_fei ] + else + [ fexp_or_fei, fexp_or_fei.fei ] + end + + # + # let's make it verbose... + + if fexp + return false if (ap == true and not fexp.apply_time) + return false if (ap == false and fexp.apply_time) + return false unless class_accepted?(fexp, ic, ec) + end + + return false \ + if wfname and fei.wfname != wfname + return false \ + if wfrevision and fei.wfrevision != wfrevision + + return false \ + if cs and fei.sub_instance_id != "" + return false \ + if wfid and fei.wfid != wfid + return false \ + if wfid_prefix and not fei.wfid.match("^#{wfid_prefix}") + return false \ + if parent_wfid and not fei.parent_wfid == parent_wfid + + true + end + + # + # Returns true if the given expression is in the list of included + # classes or false if it's in the list of excluded classes... + # + # include_classes has precedence of exclude_classes. + # + def class_accepted? (fexp, include_classes, exclude_classes) + + return false if include_classes and (not include_classes.find do |klazz| + fexp.is_a?(klazz) + end) + return false if exclude_classes and exclude_classes.find do |klazz| + fexp.is_a?(klazz) + end + + true + end end # # This cache uses a LruHash (Least Recently Used) to store expressions. # If an expression is not cached, the 'real storage' is consulted. @@ -113,12 +193,11 @@ super() service_init(service_name, application_context) - size = @application_context[:expression_cache_size] - size = DEFAULT_SIZE unless size + size = @application_context[:expression_cache_size] || DEFAULT_SIZE size = MIN_SIZE unless size > MIN_SIZE linfo { "new() size is #{size}" } @cache = LruHash.new(size) @@ -150,79 +229,75 @@ fe end def []= (fei, fe) - #linfo { "[]= caching #{fei}" } + ldebug { "[]= caching #{fei}" } @cache[fei.hash] = fe end def delete (fei) + @cache.delete fei.hash end def length + @cache.length end alias :size :length def clear + @cache.clear end alias :purge :clear # - # Simply redirects the call to the each_of_kind() method of - # the 'real storage'. + # This implementations of find_expressions() immediately passes + # the call to the underlying real storage. # - def each_of_kind (kind, &block) + def find_expressions (options={}) - get_real_storage.each_of_kind(kind, &block) + get_real_storage.find_expressions options end # - # Passes a block to the expressions currently in the cache. + # Attempts at fetching the root expression of a given process + # instance. # - def each (wfid_prefix=nil, &block) + def fetch_root (wfid) - #@cache.each(&block) + # + # at first, look in the cache - if wfid_prefix - @cache.each do |fei, fexp| - next unless fei.wfid.match "^#{wfid_prefix}" - block.call fei, fexp - end - else - @cache.each(&block) + @cache.each do |hashed_fei, fexp| + + return fexp \ + if fexp.fei.wfid == wfid and fexp.is_a?(DefineExpression) end - end - # - # This each() just delegates to the real storage each() method. - # - def real_each (wfid_prefix=nil, &block) - - get_real_storage.each(wfid_prefix, &block) + get_real_storage.fetch_root wfid end protected # # Returns the "real storage" i.e. the storage that does the real # persistence behind this "cache storage". # def get_real_storage - return @real_storage if @real_storage + #return @real_storage if @real_storage + #@real_storage = + # @application_context[S_EXPRESSION_STORAGE + ".1"] + #@real_storage - @real_storage = - @application_context[S_EXPRESSION_STORAGE + ".1"] - - @real_storage + @application_context["expressionStorage.1"] end end # # Memory consuming in-memory storage. @@ -233,41 +308,96 @@ include OwfeServiceLocator include ExpressionStorageBase def initialize (service_name, application_context) - service_init(service_name, application_context) + service_init service_name, application_context observe_expool end alias :purge :clear - # + #-- # Allows to pass a block to each expressions of a given kind (type). # - def each_of_kind (kind, &block) + #def each_of_kind (kind, &block) + # self.each_value do |fexp| + # block.call(fexp.fei, fexp) if fexp.kind_of?(kind) + # end + #end + # + # An iterator on the expression stored in here. + # + #def each (wfid_prefix=nil, &block) + # if wfid_prefix + # super() do |fei, fexp| + # next unless fei.wfid.match "^#{wfid_prefix}" + # block.call fei, fexp + # end + # else + # super(&block) + # end + #end + #alias :real_each :each + #++ - self.each_value do |fexp| - block.call(fexp.fei, fexp) if fexp.kind_of?(kind) + # + # Finds expressions matching the given criteria (returns a list + # of expressions). + # + # This methods is called by the expression pool, it's thus not + # very "public" (not used directly by integrators, who should + # just focus on the methods provided by the Engine). + # + # :wfid :: + # will list only one process, + # <tt>:wfid => '20071208-gipijiwozo'</tt> + # :parent_wfid :: + # will list only one process, and its subprocesses, + # <tt>:parent_wfid => '20071208-gipijiwozo'</tt> + # :consider_subprocesses :: + # if true, "process-definition" expressions + # of subprocesses will be returned as well. + # :wfid_prefix :: + # allows your to query for specific workflow instance + # id prefixes. for example : + # <tt>:wfid_prefix => "200712"</tt> + # for the processes started in December. + # :include_classes :: + # excepts a class or an array of classes, only instances of these + # classes will be returned. Parent classes or mixins can be + # given. + # <tt>:includes_classes => OpenWFE::SequenceExpression</tt> + # :exclude_classes :: + # works as expected. + # :wfname :: + # will return only the expressions who belongs to the given + # workflow [name]. + # :wfrevision :: + # usued in conjuction with :wfname, returns only the expressions + # with a given workflow revision. + # :applied :: + # if this option is set to true, will only return the expressions + # that have been applied (exp.apply_time != nil). + # + def find_expressions (options={}) + + values.find_all do |fexp| + does_match? options, fexp end end - def each (wfid_prefix=nil, &block) + # + # Attempts at fetching the root expression of a given process + # instance. + # + def fetch_root (wfid) - if wfid_prefix - - super() do |fei, fexp| - next unless fei.wfid.match "^#{wfid_prefix}" - block.call fei, fexp - end - else - - super(&block) - end + find_expressions( + :wfid => wfid, + :include_classes => DefineExpression)[0] end - - alias :real_each :each end end