Class: WhereIsWaldo::Configuration
- Inherits:
-
Object
- Object
- WhereIsWaldo::Configuration
- Defined in:
- lib/where_is_waldo/configuration.rb
Instance Attribute Summary collapse
-
#adapter ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups).
-
#authenticate_proc ⇒ Object
ActionCable settings :channel_name - defaults to 'WhereIsWaldo::PresenceChannel' :authenticate_proc - proc to authenticate connection, receives request.
-
#broadcast_audience ⇒ Object
Default audience resolver for the Broadcastable concern.
-
#channel_name ⇒ Object
ActionCable settings :channel_name - defaults to 'WhereIsWaldo::PresenceChannel' :authenticate_proc - proc to authenticate connection, receives request.
-
#heartbeat_interval ⇒ Object
Timing :timeout - seconds until considered offline (default: 90) :heartbeat_interval - expected heartbeat frequency (default: 30).
-
#redis_client ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups).
-
#redis_prefix ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups).
-
#roster_cache_ttl ⇒ Object
Tuning (pull/nudge).
-
#roster_members ⇒ Object
Live presence roster ("who's around in my org/account") ===.
-
#roster_members_association ⇒ Object
Live presence roster ("who's around in my org/account") ===.
-
#roster_mode ⇒ Object
roster_mode: delivery strategy, per account.
-
#roster_nudge_jitter ⇒ Object
Tuning (pull/nudge).
-
#roster_org ⇒ Object
Live presence roster ("who's around in my org/account") ===.
-
#roster_poll_interval ⇒ Object
Tuning (pull/nudge).
-
#roster_viewers_of ⇒ Object
roster_visible_to: given a VIEWER, return the AR scope of subjects that viewer may see (for :poll/:nudge snapshots + diffs).
-
#roster_visible_to ⇒ Object
roster_visible_to: given a VIEWER, return the AR scope of subjects that viewer may see (for :poll/:nudge snapshots + diffs).
-
#session_column ⇒ Object
Column names - fully configurable :session_column - unique identifier per connection/tab (e.g., :session_id, :jti) :subject_column - who is present (e.g., :user_id, :member_id, :student_id).
-
#subject_class ⇒ Object
Subject model (e.g., 'User', 'Member', 'Student') Required for scope-based broadcasting and queries.
-
#subject_column ⇒ Object
Column names - fully configurable :session_column - unique identifier per connection/tab (e.g., :session_id, :jti) :subject_column - who is present (e.g., :user_id, :member_id, :student_id).
-
#subject_data_proc ⇒ Object
Optional: proc that returns hash of subject info for presence data Called with the subject record to build presence hash.
-
#table_name ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups).
-
#timeout ⇒ Object
Timing :timeout - seconds until considered offline (default: 90) :heartbeat_interval - expected heartbeat frequency (default: 30).
Instance Method Summary collapse
-
#build_subject_data(subject) ⇒ Object
Build subject data hash from a subject record.
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
-
#members_association ⇒ Object
Association name used to derive the default roster from an org when roster_members is not configured (e.g. subject_class "User" => :users).
-
#resolve_members(org) ⇒ Object
Resolve the AR scope of member subjects for an org (nil if not resolvable).
-
#resolve_mode(account) ⇒ Object
Resolve the delivery mode for an account.
-
#resolve_roster_org(subject) ⇒ Object
Resolve the org/container record for a subject (nil if unset/absent).
-
#resolve_viewers_of(subject) ⇒ Object
Resolve the AR scope of viewers allowed to see a SUBJECT (:fanout only).
-
#resolve_visible_to(viewer) ⇒ Object
Resolve the AR scope of subjects a VIEWER may see.
-
#roster_enabled? ⇒ Boolean
True when the live-presence roster feature is configured.
-
#subject_class_constant ⇒ Object
Helper to get subject class constant.
-
#timeout_duration ⇒ Object
Helper to get timeout as duration.
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
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 120 121 122 123 |
# File 'lib/where_is_waldo/configuration.rb', line 87 def initialize # Storage defaults @adapter = :database @table_name = "presences" @redis_client = nil @redis_prefix = "where_is_waldo" # Column defaults @session_column = :session_id @subject_column = :subject_id # Subject model (required) @subject_class = nil @subject_data_proc = nil # Timing defaults @timeout = 90 @heartbeat_interval = 30 # ActionCable defaults @channel_name = "WhereIsWaldo::PresenceChannel" @authenticate_proc = nil # Broadcastable default audience (set per app) @broadcast_audience = nil # Presence roster (set per app to enable) @roster_org = nil @roster_members = nil @roster_members_association = nil @roster_visible_to = nil @roster_viewers_of = nil @roster_mode = :poll @roster_poll_interval = 15 @roster_cache_ttl = 90 @roster_nudge_jitter = 0.5 end |
Instance Attribute Details
#adapter ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups)
10 11 12 |
# File 'lib/where_is_waldo/configuration.rb', line 10 def adapter @adapter end |
#authenticate_proc ⇒ Object
ActionCable settings :channel_name - defaults to 'WhereIsWaldo::PresenceChannel' :authenticate_proc - proc to authenticate connection, receives request
33 34 35 |
# File 'lib/where_is_waldo/configuration.rb', line 33 def authenticate_proc @authenticate_proc end |
#broadcast_audience ⇒ Object
Default audience resolver for the Broadcastable concern. A lambda that, given a record, returns the AR scope to broadcast to (e.g. that record's account members). Set once per app to match its container, e.g.:
config.broadcast_audience = ->(rec) { rec.account.users }
Models may override per-model via broadcasts_realtime(scope: ...).
40 41 42 |
# File 'lib/where_is_waldo/configuration.rb', line 40 def broadcast_audience @broadcast_audience end |
#channel_name ⇒ Object
ActionCable settings :channel_name - defaults to 'WhereIsWaldo::PresenceChannel' :authenticate_proc - proc to authenticate connection, receives request
33 34 35 |
# File 'lib/where_is_waldo/configuration.rb', line 33 def channel_name @channel_name end |
#heartbeat_interval ⇒ Object
Timing :timeout - seconds until considered offline (default: 90) :heartbeat_interval - expected heartbeat frequency (default: 30)
28 29 30 |
# File 'lib/where_is_waldo/configuration.rb', line 28 def heartbeat_interval @heartbeat_interval end |
#redis_client ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups)
10 11 12 |
# File 'lib/where_is_waldo/configuration.rb', line 10 def redis_client @redis_client end |
#redis_prefix ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups)
10 11 12 |
# File 'lib/where_is_waldo/configuration.rb', line 10 def redis_prefix @redis_prefix end |
#roster_cache_ttl ⇒ Object
Tuning (pull/nudge). roster_nudge_jitter (seconds) spreads clients' re-poll after a nudge so a change doesn't stampede every viewer at once.
85 86 87 |
# File 'lib/where_is_waldo/configuration.rb', line 85 def roster_cache_ttl @roster_cache_ttl end |
#roster_members ⇒ Object
Live presence roster ("who's around in my org/account") ===
roster_org: given a subject, return the org/container record that defines the roster boundary. Its class + id key the single shared roster ActionCable stream, so every member of the same org subscribes to ONE stream and a presence change is a single O(1) broadcast (not per-member fan-out). Required to enable the roster feature — nil leaves it inert. config.roster_org = ->(subject) { subject.account }
roster_members: given that org, return the AR scope of member subjects
shown in the roster. Optional — defaults to org.public_send(
roster_members_association: association used to build the default roster from the org when roster_members is unset (defaults to the pluralized subject_class, e.g. :users).
60 61 62 |
# File 'lib/where_is_waldo/configuration.rb', line 60 def roster_members @roster_members end |
#roster_members_association ⇒ Object
Live presence roster ("who's around in my org/account") ===
roster_org: given a subject, return the org/container record that defines the roster boundary. Its class + id key the single shared roster ActionCable stream, so every member of the same org subscribes to ONE stream and a presence change is a single O(1) broadcast (not per-member fan-out). Required to enable the roster feature — nil leaves it inert. config.roster_org = ->(subject) { subject.account }
roster_members: given that org, return the AR scope of member subjects
shown in the roster. Optional — defaults to org.public_send(
roster_members_association: association used to build the default roster from the org when roster_members is unset (defaults to the pluralized subject_class, e.g. :users).
60 61 62 |
# File 'lib/where_is_waldo/configuration.rb', line 60 def roster_members_association @roster_members_association end |
#roster_mode ⇒ Object
roster_mode: delivery strategy, per account. A symbol, or a callable resolving an account -> mode. MUST be a function of the account (uniform for all its members). Default :poll (safe: server-side filtered). :poll - heartbeat/poll, server-filtered, ~interval latency :broadcast - instant shared-stream push, NO filtering (open account) :nudge - :poll + content-free trigger (Phase 2) :fanout - per-viewer push (Phase 3) config.roster_mode = ->(account) { account.everyone_admin? ? :broadcast : :poll }
81 82 83 |
# File 'lib/where_is_waldo/configuration.rb', line 81 def roster_mode @roster_mode end |
#roster_nudge_jitter ⇒ Object
Tuning (pull/nudge). roster_nudge_jitter (seconds) spreads clients' re-poll after a nudge so a change doesn't stampede every viewer at once.
85 86 87 |
# File 'lib/where_is_waldo/configuration.rb', line 85 def roster_nudge_jitter @roster_nudge_jitter end |
#roster_org ⇒ Object
Live presence roster ("who's around in my org/account") ===
roster_org: given a subject, return the org/container record that defines the roster boundary. Its class + id key the single shared roster ActionCable stream, so every member of the same org subscribes to ONE stream and a presence change is a single O(1) broadcast (not per-member fan-out). Required to enable the roster feature — nil leaves it inert. config.roster_org = ->(subject) { subject.account }
roster_members: given that org, return the AR scope of member subjects
shown in the roster. Optional — defaults to org.public_send(
roster_members_association: association used to build the default roster from the org when roster_members is unset (defaults to the pluralized subject_class, e.g. :users).
60 61 62 |
# File 'lib/where_is_waldo/configuration.rb', line 60 def roster_org @roster_org end |
#roster_poll_interval ⇒ Object
Tuning (pull/nudge). roster_nudge_jitter (seconds) spreads clients' re-poll after a nudge so a change doesn't stampede every viewer at once.
85 86 87 |
# File 'lib/where_is_waldo/configuration.rb', line 85 def roster_poll_interval @roster_poll_interval end |
#roster_viewers_of ⇒ Object
roster_visible_to: given a VIEWER, return the AR scope of subjects that viewer may see (for :poll/:nudge snapshots + diffs). Handles any visibility rule server-side. Defaults to the viewer's whole org roster (everyone-sees-everyone) when unset. config.roster_visible_to = ->(viewer) { viewer.visible_users }
roster_viewers_of: given a SUBJECT, return the AR scope of viewers allowed to see it (ONLY used by :fanout, Phase 3). Must be the exact inverse of roster_visible_to.
71 72 73 |
# File 'lib/where_is_waldo/configuration.rb', line 71 def roster_viewers_of @roster_viewers_of end |
#roster_visible_to ⇒ Object
roster_visible_to: given a VIEWER, return the AR scope of subjects that viewer may see (for :poll/:nudge snapshots + diffs). Handles any visibility rule server-side. Defaults to the viewer's whole org roster (everyone-sees-everyone) when unset. config.roster_visible_to = ->(viewer) { viewer.visible_users }
roster_viewers_of: given a SUBJECT, return the AR scope of viewers allowed to see it (ONLY used by :fanout, Phase 3). Must be the exact inverse of roster_visible_to.
71 72 73 |
# File 'lib/where_is_waldo/configuration.rb', line 71 def roster_visible_to @roster_visible_to end |
#session_column ⇒ Object
Column names - fully configurable :session_column - unique identifier per connection/tab (e.g., :session_id, :jti) :subject_column - who is present (e.g., :user_id, :member_id, :student_id)
15 16 17 |
# File 'lib/where_is_waldo/configuration.rb', line 15 def session_column @session_column end |
#subject_class ⇒ Object
Subject model (e.g., 'User', 'Member', 'Student') Required for scope-based broadcasting and queries
19 20 21 |
# File 'lib/where_is_waldo/configuration.rb', line 19 def subject_class @subject_class end |
#subject_column ⇒ Object
Column names - fully configurable :session_column - unique identifier per connection/tab (e.g., :session_id, :jti) :subject_column - who is present (e.g., :user_id, :member_id, :student_id)
15 16 17 |
# File 'lib/where_is_waldo/configuration.rb', line 15 def subject_column @subject_column end |
#subject_data_proc ⇒ Object
Optional: proc that returns hash of subject info for presence data Called with the subject record to build presence hash
23 24 25 |
# File 'lib/where_is_waldo/configuration.rb', line 23 def subject_data_proc @subject_data_proc end |
#table_name ⇒ Object
Storage settings :adapter - :database or :redis :table_name - defaults to 'presences' :redis_client - custom Redis instance (optional) :redis_prefix - key prefix for Redis (for multi-app setups)
10 11 12 |
# File 'lib/where_is_waldo/configuration.rb', line 10 def table_name @table_name end |
#timeout ⇒ Object
Timing :timeout - seconds until considered offline (default: 90) :heartbeat_interval - expected heartbeat frequency (default: 30)
28 29 30 |
# File 'lib/where_is_waldo/configuration.rb', line 28 def timeout @timeout end |
Instance Method Details
#build_subject_data(subject) ⇒ Object
Build subject data hash from a subject record
197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/where_is_waldo/configuration.rb', line 197 def build_subject_data(subject) return {} unless subject if subject_data_proc subject_data_proc.call(subject) elsif subject.respond_to?(:id) { id: subject.id } else {} end end |
#members_association ⇒ Object
Association name used to derive the default roster from an org when roster_members is not configured (e.g. subject_class "User" => :users).
146 147 148 149 150 151 |
# File 'lib/where_is_waldo/configuration.rb', line 146 def members_association return roster_members_association if roster_members_association return nil if subject_class.blank? subject_class.to_s.demodulize.underscore.pluralize.to_sym end |
#resolve_members(org) ⇒ Object
Resolve the AR scope of member subjects for an org (nil if not resolvable).
154 155 156 157 158 159 160 161 162 |
# File 'lib/where_is_waldo/configuration.rb', line 154 def resolve_members(org) return nil unless org if roster_members roster_members.call(org) elsif (assoc = members_association) && org.respond_to?(assoc) org.public_send(assoc) end end |
#resolve_mode(account) ⇒ Object
Resolve the delivery mode for an account. Callable roster_mode is invoked with the account; a bare symbol is returned as-is. Defaults to :poll.
190 191 192 193 194 |
# File 'lib/where_is_waldo/configuration.rb', line 190 def resolve_mode(account) mode = roster_mode mode = mode.call(account) if mode.respond_to?(:call) (mode || :poll).to_sym end |
#resolve_roster_org(subject) ⇒ Object
Resolve the org/container record for a subject (nil if unset/absent).
138 139 140 141 142 |
# File 'lib/where_is_waldo/configuration.rb', line 138 def resolve_roster_org(subject) return nil unless roster_org && subject roster_org.call(subject) end |
#resolve_viewers_of(subject) ⇒ Object
Resolve the AR scope of viewers allowed to see a SUBJECT (:fanout only).
182 183 184 185 186 |
# File 'lib/where_is_waldo/configuration.rb', line 182 def resolve_viewers_of(subject) return nil unless roster_viewers_of && subject roster_viewers_of.call(subject) end |
#resolve_visible_to(viewer) ⇒ Object
Resolve the AR scope of subjects a VIEWER may see. Defaults to the viewer's whole org roster (everyone-sees-everyone) when unset.
171 172 173 174 175 176 177 178 179 |
# File 'lib/where_is_waldo/configuration.rb', line 171 def resolve_visible_to(viewer) return nil unless viewer if roster_visible_to roster_visible_to.call(viewer) else resolve_members(resolve_roster_org(viewer)) end end |
#roster_enabled? ⇒ Boolean
True when the live-presence roster feature is configured.
165 166 167 |
# File 'lib/where_is_waldo/configuration.rb', line 165 def roster_enabled? !roster_org.nil? end |
#subject_class_constant ⇒ Object
Helper to get subject class constant
131 132 133 134 135 |
# File 'lib/where_is_waldo/configuration.rb', line 131 def subject_class_constant return nil if subject_class.blank? subject_class.is_a?(String) ? subject_class.safe_constantize : subject_class end |
#timeout_duration ⇒ Object
Helper to get timeout as duration
126 127 128 |
# File 'lib/where_is_waldo/configuration.rb', line 126 def timeout_duration timeout.is_a?(ActiveSupport::Duration) ? timeout : timeout.seconds end |