Class: Routemaster::Dirty::Map

Inherits:
Object
  • Object
show all
Includes:
Wisper::Publisher
Defined in:
lib/routemaster/dirty/map.rb

Overview

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.

Constant Summary collapse

KEY =
'dirtymap:items'

Instance Method Summary collapse

Constructor Details

#initialize(redis: nil) ⇒ Map

Returns a new instance of Map.



19
20
21
# File 'lib/routemaster/dirty/map.rb', line 19

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

Instance Method Details

#allObject



38
39
40
# File 'lib/routemaster/dirty/map.rb', line 38

def all
  @redis.smembers(KEY)
end

#countObject

Number of currently dirty entities.



58
59
60
# File 'lib/routemaster/dirty/map.rb', line 58

def count
  @redis.scard(KEY)
end

#mark(url) ⇒ Object

Marks an entity as dirty. Return true if newly marked, false if re-marking.



25
26
27
28
29
# File 'lib/routemaster/dirty/map.rb', line 25

def mark(url)
  @redis.sadd(KEY, url).tap do |marked|
    publish(:dirty_entity, url) if marked
  end
end

#sweep(limit = 0) ⇒ Object

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.



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/routemaster/dirty/map.rb', line 45

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

#sweep_one(url, &block) ⇒ Object

Runs the block. The entity will only be marked as clean if the block returns truthy.



33
34
35
36
# File 'lib/routemaster/dirty/map.rb', line 33

def sweep_one(url, &block)
  return unless block.call(url)
  @redis.srem(KEY, url)
end