Class: WhereIsWaldo::PresenceService

Inherits:
Object
  • Object
show all
Defined in:
app/services/where_is_waldo/presence_service.rb

Class Method Summary collapse

Class Method Details

.all_online_ids(timeout: nil) ⇒ Array<Integer>

Get all online subject IDs (no scope filtering)

Parameters:

  • timeout (Integer) (defaults to: nil)

    Seconds threshold

Returns:

  • (Array<Integer>)


74
75
76
# File 'app/services/where_is_waldo/presence_service.rb', line 74

def all_online_ids(timeout: nil)
  adapter.online_subject_ids(timeout: timeout)
end

.cleanup(timeout: nil) ⇒ Integer

Cleanup stale records

Parameters:

  • timeout (Integer) (defaults to: nil)

    Seconds threshold (defaults to config.timeout)

Returns:

  • (Integer)

    Number of records removed



109
110
111
# File 'app/services/where_is_waldo/presence_service.rb', line 109

def cleanup(timeout: nil)
  adapter.cleanup(timeout: timeout)
end

.connect(session_id:, subject_id:, metadata: {}) ⇒ Boolean

Register a new presence

Parameters:

  • session_id (String)

    Unique session identifier

  • subject_id (Integer/String)

    Subject identifier (user, member, etc.)

  • metadata (Hash) (defaults to: {})

    Additional data

Returns:

  • (Boolean)

    success



11
12
13
14
15
16
17
# File 'app/services/where_is_waldo/presence_service.rb', line 11

def connect(session_id:, subject_id:, metadata: {})
  adapter.connect(
    session_id: session_id,
    subject_id: subject_id,
    metadata: 
  )
end

.disconnect(session_id: nil, subject_id: nil) ⇒ Boolean

Remove a presence by session, or all presences for a subject

Parameters:

  • session_id (String) (defaults to: nil)

    Session identifier (optional)

  • subject_id (Integer/String) (defaults to: nil)

    Subject identifier (optional)

Returns:

  • (Boolean)

    success



23
24
25
26
27
28
# File 'app/services/where_is_waldo/presence_service.rb', line 23

def disconnect(session_id: nil, subject_id: nil)
  adapter.disconnect(
    session_id: session_id,
    subject_id: subject_id
  )
end

.heartbeat(session_id:, subject_id:, tab_visible: true, subject_active: true, last_activity_at: nil, metadata: {}) ⇒ Boolean

Update heartbeat for a session rubocop:disable Metrics/ParameterLists, Layout/LineLength

Parameters:

  • session_id (String)

    Session identifier

  • subject_id (Integer/String)

    Subject identifier (required — pairs with session_id to disambiguate colliding session ids across subjects)

  • tab_visible (Boolean) (defaults to: true)

    Is tab in foreground

  • subject_active (Boolean) (defaults to: true)

    Recent activity

  • last_activity_at (Integer) (defaults to: nil)

    Unix timestamp (ms) of last user activity

  • metadata (Hash) (defaults to: {})

    Additional data to merge

Returns:

  • (Boolean)

    success



41
42
43
44
45
46
47
48
49
50
51
# File 'app/services/where_is_waldo/presence_service.rb', line 41

def heartbeat(session_id:, subject_id:, tab_visible: true, subject_active: true, last_activity_at: nil, metadata: {})
  # rubocop:enable Metrics/ParameterLists, Layout/LineLength
  adapter.heartbeat(
    session_id: session_id,
    subject_id: subject_id,
    tab_visible: tab_visible,
    subject_active: subject_active,
    last_activity_at: last_activity_at,
    metadata: 
  )
end

.online(scope, timeout: nil) ⇒ ActiveRecord::Relation

Get online subjects from an AR scope

Parameters:

  • scope (ActiveRecord::Relation)

    Scope to filter

  • timeout (Integer) (defaults to: nil)

    Seconds threshold (defaults to config.timeout)

Returns:

  • (ActiveRecord::Relation)

    Online subjects from the scope



57
58
59
60
# File 'app/services/where_is_waldo/presence_service.rb', line 57

def online(scope, timeout: nil)
  online_ids = adapter.online_subject_ids(timeout: timeout)
  scope.where(id: online_ids)
end

.online_ids(scope, timeout: nil) ⇒ Array<Integer>

Get online subject IDs from an AR scope

Parameters:

  • scope (ActiveRecord::Relation)

    Scope to filter

  • timeout (Integer) (defaults to: nil)

    Seconds threshold (defaults to config.timeout)

Returns:

  • (Array<Integer>)

    Online subject IDs



66
67
68
69
# File 'app/services/where_is_waldo/presence_service.rb', line 66

def online_ids(scope, timeout: nil)
  online_ids = adapter.online_subject_ids(timeout: timeout)
  scope.where(id: online_ids).pluck(:id)
end

.session_statusHash?

Get status of a specific session

Parameters:

  • session_id (String)

    Session identifier

  • subject_id (Integer/String)

    Subject identifier — required for the same reason as heartbeat

Returns:

  • (Hash, nil)

    Presence record or nil



97
# File 'app/services/where_is_waldo/presence_service.rb', line 97

delegate :session_status, to: :adapter

.sessions_for_subjectArray<Hash>

Get all sessions for a subject

Parameters:

  • subject_id (Integer/String)

    Subject identifier

Returns:

  • (Array<Hash>)

    Presence records



81
# File 'app/services/where_is_waldo/presence_service.rb', line 81

delegate :sessions_for_subject, to: :adapter

.sessions_for_subjectsHash{Integer/String => Array<Hash>}

Get live sessions for many subjects in one call, grouped by subject id. Preferred over calling sessions_for_subject per id when the caller already has an id list (e.g. roster aggregation) — adapters can (and do) implement this as a bulk read.

Parameters:

  • subject_ids (Array<Integer/String>)

    Subject identifiers

  • timeout (Integer, nil)

    Seconds threshold (defaults to config.timeout)

Returns:

  • (Hash{Integer/String => Array<Hash>})

    subject_id => sessions



90
# File 'app/services/where_is_waldo/presence_service.rb', line 90

delegate :sessions_for_subjects, to: :adapter

.subject_online?(subject_id) ⇒ Boolean

Check if a subject is online

Parameters:

  • subject_id (Integer/String)

    Subject identifier

Returns:

  • (Boolean)


102
103
104
# File 'app/services/where_is_waldo/presence_service.rb', line 102

def subject_online?(subject_id)
  sessions_for_subject(subject_id).any?
end