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