Class: JetstreamBridge::InboxEvent

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/jetstream_bridge/models/inbox_event.rb,
lib/jetstream_bridge/models/inbox_event.rb

Overview

Shim: loud failure if AR isn’t present but someone calls the model.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ar_connected?Boolean

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 26

def ar_connected?
  ActiveRecord::Base.connected? && connection_pool.active_connection?
rescue StandardError
  false
end

.cleanup_processed(older_than: 30.days) ⇒ Integer

Clean up old processed events

Parameters:

  • older_than (ActiveSupport::Duration) (defaults to: 30.days)

    Age threshold

Returns:

  • (Integer)

    Number of records deleted



96
97
98
99
100
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 96

def cleanup_processed(older_than: 30.days)
  return 0 unless has_column?(:status) && has_column?(:processed_at)

  processed.where('processed_at < ?', older_than.ago).delete_all
end

.has_column?(name) ⇒ Boolean

Safe column presence check that never boots a connection during class load.

Returns:

  • (Boolean)


18
19
20
21
22
23
24
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 18

def has_column?(name)
  return false unless ar_connected?

  connection.schema_cache.columns_hash(table_name).key?(name.to_s)
rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::NoDatabaseError
  false
end

.method_missing(method_name, *_args) ⇒ Object



164
165
166
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 164

def method_missing(method_name, *_args, &)
  raise_missing_ar!('Inbox', method_name)
end

.processing_statsHash

Get processing statistics

Uses a single aggregated query to avoid N+1 problem.

Returns:

  • (Hash)

    Statistics hash with counts by status



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 107

def processing_stats
  return {} unless has_column?(:status)

  # Single aggregated query instead of 4 separate queries
  stats_by_status = group(:status).count
  total_count = stats_by_status.values.sum

  {
    total: total_count,
    processed: stats_by_status['processed'] || 0,
    failed: stats_by_status['failed'] || 0,
    pending: stats_by_status['pending'] || stats_by_status[nil] || 0
  }
end

.respond_to_missing?(_method_name, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 168

def respond_to_missing?(_method_name, _include_private = false)
  false
end

Instance Method Details

#mark_failed!(err_msg) ⇒ Object



141
142
143
144
145
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 141

def mark_failed!(err_msg)
  self.status = JetstreamBridge::Config::Status::FAILED if self.class.has_column?(:status)
  self.last_error = err_msg if self.class.has_column?(:last_error)
  save!
end

#mark_processed!Object



134
135
136
137
138
139
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 134

def mark_processed!
  now = Time.now.utc
  self.status = JetstreamBridge::Config::Status::PROCESSED if self.class.has_column?(:status)
  self.processed_at = now if self.class.has_column?(:processed_at)
  save!
end

#payload_hashObject



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 147

def payload_hash
  v = self[:payload]
  case v
  when String then begin
    Oj.load(v, mode: :strict)
  rescue Oj::Error
    {}
  end
  when Hash then v
  else v.respond_to?(:as_json) ? v.as_json : {}
  end
end

#processed?Boolean

—- Instance Methods —-

Returns:

  • (Boolean)


124
125
126
127
128
129
130
131
132
# File 'lib/jetstream_bridge/models/inbox_event.rb', line 124

def processed?
  if self.class.has_column?(:processed_at)
    processed_at.present?
  elsif self.class.has_column?(:status)
    status == JetstreamBridge::Config::Status::PROCESSED
  else
    false
  end
end