Class: Australium::EventCache

Inherits:
Object
  • Object
show all
Includes:
EventFilters
Defined in:
lib/australium/cache/event_cache.rb

Overview

Allows access to events in an Australium database. Unlike a direct Mongo connection, the EventCache will return a fully-formed Event object.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EventFilters

#chat_messages, #connects, #disconnects, #entrances, #kills, #map_loads, #map_starts, #name_changes, #role_changes, #suicides, #team_joins, #triggers

Constructor Details

#initialize(db) ⇒ EventCache

Creates a new instance of EventCache.


20
21
22
# File 'lib/australium/cache/event_cache.rb', line 20

def initialize(db)
  @db = db
end

Instance Attribute Details

#dbObject

Returns the value of attribute db


16
17
18
# File 'lib/australium/cache/event_cache.rb', line 16

def db
  @db
end

Instance Method Details

#has_game?(game_hash) ⇒ TrueClass

Returns true if this game's data has been cached.


27
28
29
30
31
32
33
# File 'lib/australium/cache/event_cache.rb', line 27

def has_game?(game_hash)
  begin
    @db["MapLoad"].find(:game_id => game_hash).to_a.count > 0 && @db["GameEnd"].find(:game_id => game_hash).to_a.count > 0
  rescue
    false
  end
end

#hash_to_obj(hash) ⇒ Object

FIXME: This could be more clever.


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/australium/cache/event_cache.rb', line 51

def hash_to_obj(hash)
  hash.each_pair do |key, value|
    hash[key] = hash_to_obj(value) if value.is_a?(Hash)
    hash[key] = value.map { |x| hash_to_obj(x) if x.is_a?(Hash) } if value.is_a?(Array)
  end

  begin
    obj_class = Australium.const_get(hash[:class])
  rescue
    obj_class = OpenStruct
  end

  obj_class.new(hash)
end

#obj_to_hash(obj) ⇒ Object

FIXME: This could be more clever, and probably combined with hash_to_obj.


67
68
69
70
71
72
73
74
75
76
# File 'lib/australium/cache/event_cache.rb', line 67

def obj_to_hash(obj)
  obj.each_pair do |key, value|
    obj[key] = obj_to_hash(value) if value.is_a?(OpenStruct)
    obj[key] = value.map { |x| obj_to_hash(x) if x.is_a?(OpenStruct) } if value.is_a?(Array)
  end

  obj[:class] = obj.class.to_s.split('::').last

  obj.to_h
end

#query(&block) ⇒ Array<Event>

Passes a block to the database object and returns reconstructed Events.

Raises:


38
39
40
41
42
43
44
45
46
47
48
# File 'lib/australium/cache/event_cache.rb', line 38

def query(&block)
  events = instance_exec(&block)

  # Raise an exception if results are not in the expected format.
  raise CacheReadError unless events.is_a?(Mongo::Cursor)

  events = events.to_a

  # Convert from hashes to objects.
  events.map { |event| hash_to_obj(event) }
end

#store(game) ⇒ Object

Caches a complete Game.


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/australium/cache/event_cache.rb', line 80

def store(game)

  # If a MapLoad event exists with identical parameters for everything except the game hash, delete the previous
  # game data - as this indicates an invalid or incomplete log was stored.
  start_event = game.map_loads.first
  matches = db["MapLoad"].find(
    :server => start_event.server,
    :timestamp => start_event.timestamp,
    :game_id => { "$ne" => start_event.game_id }
  ).to_a
  matches.each do |match|
    invalid_game = match['game_id']
    puts "Removing data from game #{invalid_game} as an incomplete cache."
    @db.collections.each do |collection|
      next if collection.name.start_with?("system.")
      collection.remove(:game_id => invalid_game)
    end
  end

  to_store = game.events.map do |event|

    # Due to the enormous amount of repeated information, saving GameState objects is not a sane proposition at
    # this time. Until GameState objects can be stored more efficiently, they will not be inserted into databases.
    event.delete_field(:state) unless event.is_a?(GameEnd)

    obj_to_hash(event)

  end

  to_store.each do |event|
    db[event[:class]].update(
      {:server => event[:server],
       :game_id => event[:game_id],
       :line_number => event[:line_number]},
      event,
      {:upsert => true}
    )
  end

end