Sha256: f9d021a846a4b262e94a4020a9b5702ffb09d215ef5ecd6ec4ad4828bac88332

Contents?: true

Size: 1.71 KB

Versions: 31

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

31 entries across 31 versions & 1 rubygems

Version Path
routemaster-drain-3.7.1 lib/routemaster/dirty/map.rb
routemaster-drain-3.7.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.8 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.7 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.6 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.5 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.4 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.3 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.2 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.1 lib/routemaster/dirty/map.rb
routemaster-drain-3.6.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.5.1 lib/routemaster/dirty/map.rb
routemaster-drain-3.5.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.4.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.3.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.2.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.1.0 lib/routemaster/dirty/map.rb
routemaster-drain-3.0.3 lib/routemaster/dirty/map.rb
routemaster-drain-3.0.2 lib/routemaster/dirty/map.rb
routemaster-drain-3.0.1 lib/routemaster/dirty/map.rb