Sha256: 837f649ac6c9a2e4a75a639d3c7ffae00149ef0ef5571265fe6049388d9ead00

Contents?: true

Size: 1.71 KB

Versions: 6

Compression:

Stored size: 1.71 KB

Contents

require 'delegate'
require 'set'
require 'wisper'

module Routemaster
  module Dirty
    # Collects information about entities whose state has changed and need to be
    # refreshed.
    # Typically +mark+ is called when notified state has changed (e.g. from the
    # bus) and +sweep+ when one wants to know what has changed.
    # 
    # Use case: when some entites are very volatile, the map will hold a "dirty"
    # state for multiple updates until the client is ready to update.
    #
    class Map
      include Wisper::Publisher
      KEY = 'dirtymap:items'

      def initialize(redis: nil)
        @redis = redis || Config.drain_redis
      end

      # Marks an entity as dirty.
      # Return true if newly marked, false if re-marking.
      def mark(url)
        @redis.sadd(KEY, url).tap do |marked|
          publish(:dirty_entity, url) if marked
        end
      end

      # Runs the block.
      # The entity will only be marked as clean if the block returns truthy.
      def sweep_one(url, &block)
        return unless block.call(url)
        @redis.srem(KEY, url)
      end

      def all
        @redis.smembers(KEY)
      end

      # Yields URLs for dirty entitities.
      # The entity will only be marked as clean if the block returns truthy.
      # It is possible to call +next+ or +break+ from the block.
      def sweep(limit = 0)
        unswept = []
        while url = @redis.spop(KEY)
          unswept.push url
          is_swept = !! yield(url)
          unswept.pop if is_swept
          break if (limit -=1).zero?
        end
      ensure
        @redis.sadd(KEY, unswept) if unswept.any?
      end

      # Number of currently dirty entities.
      def count
        @redis.scard(KEY)
      end
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
routemaster-drain-1.0.5 lib/routemaster/dirty/map.rb
routemaster-drain-1.0.4 lib/routemaster/dirty/map.rb
routemaster-drain-1.0.3 lib/routemaster/dirty/map.rb
routemaster-drain-1.0.2 lib/routemaster/dirty/map.rb
routemaster-drain-1.0.1 lib/routemaster/dirty/map.rb
routemaster-drain-1.0.0 lib/routemaster/dirty/map.rb