Class: Ably::Realtime::Presence::MembersMap Private

Inherits:
Object
  • Object
show all
Extended by:
Modules::Enum
Includes:
Modules::EventEmitter, Modules::SafeYield, Modules::StateEmitter, Enumerable
Defined in:
lib/ably/realtime/presence/members_map.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

A class encapsulating a map of the members of this presence channel, indexed by the unique Models::PresenceMessage#member_key

This map synchronises the membership of the presence set by handling SYNC messages from the service. Since sync messages can be out-of-order - e.g. a PRESENT sync event being received after that member has in fact left - this map keeps “witness” entries, with ABSENT Action, to remember the fact that a LEAVE event has been seen for a member. These entries are cleared once the last set of updates of a sync sequence have been received.

Constant Summary collapse

STATE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

ruby_enum('STATE',
  :initialized,
  :sync_starting,
  :in_sync,
  :failed
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Modules::StateEmitter

#once_or_if, #once_state_changed, #state, #state=, #state?, #unsafe_once_or_if, #unsafe_once_state_changed

Methods included from Modules::EventEmitter

#emit, #off, #on, #once, #unsafe_on, #unsafe_once

Constructor Details

#initialize(presence) ⇒ MembersMap

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of MembersMap.



29
30
31
32
33
34
35
36
37
# File 'lib/ably/realtime/presence/members_map.rb', line 29

def initialize(presence)
  @presence = presence

  @state    = STATE(:initialized)
  @members  = Hash.new
  @absent_member_cleanup_queue = []

  setup_event_handlers
end

Instance Attribute Details

#lengthInteger (readonly) Also known as: count, size

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns number of present members known at this point in time, will not wait for sync operation to complete.

Returns:

  • (Integer)

    number of present members known at this point in time, will not wait for sync operation to complete



120
121
122
# File 'lib/ably/realtime/presence/members_map.rb', line 120

def length
  present_members.length
end

Instance Method Details

#each(&block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

this method will not wait for the sync operation to complete so may return an incomplete set of members. Use #get instead.

Method to allow Ably::Realtime::Presence::MembersMap to be Enumerable



128
129
130
131
# File 'lib/ably/realtime/presence/members_map.rb', line 128

def each(&block)
  return to_enum(:each) unless block_given?
  present_members.each(&block)
end

#get(options = {}) {|Array<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the list of presence members

Parameters:

  • options (Hash, String) (defaults to: {})

    an options Hash to filter members

Options Hash (options):

  • :client_id (String)

    optional client_id filter for the member

  • :connection_id (String)

    optional connection_id filter for the member

  • :wait_for_sync (String)

    defaults to false, if true the get method waits for the initial presence sync following channel attachment to complete before returning the members present

Yields:

Returns:



71
72
73
74
75
76
77
78
79
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
# File 'lib/ably/realtime/presence/members_map.rb', line 71

def get(options = {}, &block)
  wait_for_sync = options.fetch(:wait_for_sync, false)
  deferrable    = Ably::Util::SafeDeferrable.new(logger)

  result_block = proc do
    present_members.tap do |members|
      members.keep_if { |member| member.connection_id == options[:connection_id] } if options[:connection_id]
      members.keep_if { |member| member.client_id == options[:client_id] } if options[:client_id]
    end.tap do |members|
      safe_yield block, members if block_given?
      deferrable.succeed members
    end
  end

  if !wait_for_sync || sync_complete?
    result_block.call
  else
    # Must be defined before subsequent procs reference this callback
    reset_callbacks = nil

    in_sync_callback = proc do
      reset_callbacks
      result_block.call
    end

    failed_callback = proc do |error|
      reset_callbacks
      deferrable.fail error
    end

    reset_callbacks = proc do
      off(&in_sync_callback)
      off(&failed_callback)
      channel.off(&failed_callback)
    end

    once(:in_sync, &in_sync_callback)

    once(:failed, &failed_callback)
    channel.unsafe_once(:detaching, :detached, :failed) do |error_reason|
      failed_callback.call error_reason
    end
  end

  deferrable
end

#sync_complete?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

When attaching to a channel that has members present, the server initiates a sync automatically so that the client has a complete list of members.

Until this sync is complete, this method returns false

Returns:

  • (Boolean)


45
46
47
# File 'lib/ably/realtime/presence/members_map.rb', line 45

def sync_complete?
  in_sync?
end

#update_sync_serial(serial) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Update the SYNC serial from the ProtocolMessage so that SYNC can be resumed. If the serial is nil, or the part after the first : is empty, then the SYNC is complete



55
56
57
58
# File 'lib/ably/realtime/presence/members_map.rb', line 55

def update_sync_serial(serial)
  @sync_serial = serial
  change_state :in_sync if sync_serial_cursor_at_end?
end