event.rb 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. require 'json_serialized_field'
  2. # Events are how Huginn Agents communicate and log information about the world. Events can be emitted and received by
  3. # Agents. They contain a serialized `payload` of arbitrary JSON data, as well as optional `lat`, `lng`, and `expires_at`
  4. # fields.
  5. class Event < ActiveRecord::Base
  6. include JSONSerializedField
  7. include LiquidDroppable
  8. attr_accessible :lat, :lng, :payload, :user_id, :user, :expires_at
  9. acts_as_mappable
  10. json_serialize :payload
  11. belongs_to :user
  12. belongs_to :agent, :counter_cache => true
  13. has_many :agent_logs_as_inbound_event, :class_name => "AgentLog", :foreign_key => :inbound_event_id, :dependent => :nullify
  14. has_many :agent_logs_as_outbound_event, :class_name => "AgentLog", :foreign_key => :outbound_event_id, :dependent => :nullify
  15. scope :recent, lambda { |timespan = 12.hours.ago|
  16. where("events.created_at > ?", timespan)
  17. }
  18. after_create :update_agent_last_event_at
  19. after_create :possibly_propagate
  20. # Emit this event again, as a new Event.
  21. def reemit!
  22. agent.create_event :payload => payload, :lat => lat, :lng => lng
  23. end
  24. # Look for Events whose `expires_at` is present and in the past. Remove those events and then update affected Agents'
  25. # `events_counts` cache columns. This method is called by bin/schedule.rb periodically.
  26. def self.cleanup_expired!
  27. affected_agents = Event.where("expires_at IS NOT NULL AND expires_at < ?", Time.now).group("agent_id").pluck(:agent_id)
  28. Event.where("expires_at IS NOT NULL AND expires_at < ?", Time.now).delete_all
  29. Agent.where(:id => affected_agents).update_all "events_count = (select count(*) from events where agent_id = agents.id)"
  30. end
  31. protected
  32. def update_agent_last_event_at
  33. agent.touch :last_event_at
  34. end
  35. def possibly_propagate
  36. #immediately schedule agents that want immediate updates
  37. propagate_ids = agent.receivers.where(:propagate_immediately => true).pluck(:id)
  38. Agent.receive!(:only_receivers => propagate_ids) unless propagate_ids.empty?
  39. end
  40. end
  41. class EventDrop
  42. def initialize(object)
  43. @payload = object.payload
  44. super
  45. end
  46. def before_method(key)
  47. @payload[key]
  48. end
  49. def each(&block)
  50. @payload.each(&block)
  51. end
  52. def agent
  53. @payload.fetch(__method__) {
  54. @object.agent
  55. }
  56. end
  57. def created_at
  58. @payload.fetch(__method__) {
  59. @object.created_at
  60. }
  61. end
  62. end