lib/openwfe/expool/expstorage.rb in openwferu-0.9.4 vs lib/openwfe/expool/expstorage.rb in openwferu-0.9.5

- old
+ new

@@ -38,147 +38,188 @@ # # Nicolas Modrzyk at openwfe.org # John Mettraux at openwfe.org # +#require 'monitor' require 'fileutils' require 'openwfe/service' -require 'openwfe/util/lru_cache' +require 'openwfe/util/lru' require 'openwfe/flowexpressionid' module OpenWFE # - # Create a composite expression storage. - # This will take parameters from the application context to create - # the resulting composite storage - class CompositeExpressionStorage - include ServiceMixin - - attr_accessor \ - :persistence, \ - :cache, \ - :journal - - def initialize (serviceName, applicationContext) - - service_init(serviceName, applicationContext) - - @cache = @application_context[:cached_expression_storage] - @journal = @application_context[:journalized_expression_storage] - @persistence = @application_context[:file_expression_storage] - end - - # - # call the add method for each registered storage - # - def []= (fei, flowExpression) - @journal[fei] = flowExpression if @journal - @cache[fei] = flowExpression if @cache - @persistence[fei] = flowExpression - end - - # - # remove the expressionid from each registered storage - # - def delete (fei) - @journal.delete(fei) if @journal - @cache.delete(fei) if @cache - @persistence.delete(fei) - end - - # - # slightly different method. Try to get the value from the cache storage if one - # if not retrieve it, and then add it to the cache. - def [] (fei) - return @cache[fei] if @cache - flow_expression = @persistence[fei] - @cache[fei] = flow_expression if @cache - return flow_expression - end - end - - # - # implementation of a LRU caching storage. - class LruCachedExpressionStorage - include ServiceMixin - - DEFAULT_LRU_SIZE = 10 - + # This cache uses a LruHash (Least Recently Used) to store expressions. + # If an expression is not cached, the 'real storage' is consulted. + # The real storage is supposed to be the service named + # "expressionStorage.1" + # + class CacheExpressionStorage + include ServiceMixin, OwfeServiceLocator + + DEFAULT_SIZE = 5000 + def initialize (service_name, application_context) + + super() + service_init(service_name, application_context) - size = if (@application_context) - @application_context[:lru_storage_size] - else - DEFAULT_LRU_SIZE + + size = @application_context[:expression_cache_size] + size = DEFAULT_SIZE unless size + + linfo { "new() size is #{size}" } + + @cache = LruHash.new(size) + + @real_storage = nil + + # + # expstorage observes expool : + + get_expression_pool.add_observer(:update) do |channel, fei, fe| + ldebug { ":update for #{fei}" } + self[fei] = fe end - @cache = LRUCache.new(size) + get_expression_pool.add_observer(:remove) do |channel, fei| + ldebug { ":delete for #{fei}" } + self.delete(fei) + end end - - def []= (fei, flowExpression) - @cache[fei]=flowExpression + + def [] (fei) + + #ldebug { "[] size is #{@cache.size}" } + ldebug { "[] (sz #{@cache.size}) for #{fei.to_debug_s}" } + + fe = @cache[fei] + return fe if fe + + ldebug { "[] (reload) for #{fei.to_debug_s}" } + + fe = get_real_storage[fei] + + return nil unless fe + + @cache[fei] = fe + + return fe end - - # - # interface method to remove an entry for the given expression_id - # + + def []= (fei, fe) + @cache[fei] = fe + end + def delete (fei) @cache.delete(fei) end - - # - # check if the value is in the cache - def is_in_cache?(fei) - @cache.include?(fei) + + def length + @cache.length end - alias has_key? is_in_cache? - + + alias :size :length + + def clear + @cache.clear + end + + alias :purge :clear + # - # interface method, return the value associated with the given id, - # or nil if not in cache. - def [] (fei) - if(@cache.include?(fei)) - return @cache[fei] - else - return nil + # Simply redirects the call to the each_of_kind() method of + # the 'real storage'. + # + def each_of_kind (kind, &block) + + get_real_storage.each_of_kind(kind, &block) + end + + def each (&block) + @cache.each do |k, v| + block.call(k, v) end end - + + def to_s + expstorage_to_s(self) + end + + protected + + def get_real_storage + + return @real_storage if @real_storage + + @real_storage = + @application_context[S_EXPRESSION_STORAGE + ".1"] + + return @real_storage + end end # # Memory consuming in-memory storage. # No memory limit, puts everything in a Hash # class InMemoryExpressionStorage < Hash - include ServiceMixin + include ServiceMixin, OwfeServiceLocator def initialize (service_name, application_context) + service_init(service_name, application_context) + + # + # expstorage observes expool : + + get_expression_pool.add_observer(:update) do |channel, fei, fe| + #ldebug { ":update for #{fei}" } + self[fei] = fe + end + get_expression_pool.add_observer(:remove) do |channel, fei| + #ldebug { ":delete for #{fei}" } + self.delete(fei) + end end alias :purge :clear - def each_of_kind (kind) - # TODO : implement with a filter + def each_of_kind (kind, &block) + + return unless block + + self.each_value do |fexp| + block.call(fexp) if fexp.kind_of? kind + end end - + def to_s - s = "\n\n==== #{self.class} ====" - each do |k, v| - s << "\n" - if v.kind_of?(RawExpression) - s << "*raw" - else - s << " " - end - s << v.to_s - s << " key/value mismatch !" if k != v.fei - end - s << "\n==== . ====\n" - return s + expstorage_to_s(self) end + end + + # + # a small help method for expression storages... + # + def expstorage_to_s (expstorage) + + s = "\n\n==== #{expstorage.class} ====" + + expstorage.each do |k, v| + s << "\n" + if v.kind_of?(RawExpression) + s << "*raw" + else + s << " " + end + s << v.to_s + s << " key/value mismatch !" if k != v.fei + end + s << "\n==== . ====\n" + + return s end end