Class: Ably::Realtime::Presence::MembersMap Private
- Inherits:
-
Object
- Object
- Ably::Realtime::Presence::MembersMap
- 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, # Indicates the client is waiting for SYNC ProtocolMessages from Ably :sync_none, # Indicates the ATTACHED ProtocolMessage had no presence flag and thus no members on the channel :finalizing_sync, :sync_complete, # Indicates completion of server initiated sync :failed )
Instance Attribute Summary collapse
-
#length ⇒ Integer
(also: #count, #size)
readonly
private
Number of present members known at this point in time, will not wait for sync operation to complete.
Instance Method Summary collapse
-
#each(&block) ⇒ Object
private
Method to allow MembersMap to be Enumerable.
- #enter_local_members ⇒ Object private
-
#get(options = {}) {|Array<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable
private
Get the list of presence members.
-
#initialize(presence) ⇒ MembersMap
constructor
private
A new instance of MembersMap.
-
#local_members ⇒ Hash<String, PresenceMessage>
private
A copy of the local members present i.e.
-
#sync_serial_cursor_at_end? ⇒ Boolean
private
When channel serial in ProtocolMessage SYNC is nil or an empty cursor appears after the ‘:’ such as ‘cf30e75054887:psl_7g:client:189’.
-
#update_sync_serial(serial) ⇒ void
private
Update the SYNC serial from the ProtocolMessage so that SYNC can be resumed.
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_off, #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.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ably/realtime/presence/members_map.rb', line 31 def initialize(presence) @presence = presence @state = STATE(:initialized) # Two sets of members maintained # @members contains all members present on the channel # @local_members contains only this connection's members for the purpose of re-entering the member if channel continuity is lost reset_members reset_local_members @absent_member_cleanup_queue = [] # Each SYNC session has a unique ID so that following SYNC # any members present in the map without this session ID are # not present according to Ably, see #RTP19 @sync_session_id = -1 setup_event_handlers end |
Instance Attribute Details
#length ⇒ Integer (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.
132 133 134 |
# File 'lib/ably/realtime/presence/members_map.rb', line 132 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.
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
140 141 142 143 |
# File 'lib/ably/realtime/presence/members_map.rb', line 140 def each(&block) return to_enum(:each) unless block_given? present_members.each(&block) end |
#enter_local_members ⇒ 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.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/ably/realtime/presence/members_map.rb', line 155 def enter_local_members local_members.values.each do |member| logger.debug { "#{self.class.name}: Manually re-entering local presence member, client ID: #{member.client_id} with data: #{member.data}" } presence.enter_client_with_id(member.id, member.client_id, member.data).tap do |deferrable| deferrable.errback do |error| re_enter_error = Ably::Models::ErrorInfo.new( message: "unable to automatically re-enter presence channel for client_id '#{member.client_id}'. Source error code #{error.code} and message '#{error.}'", code: Ably::Exceptions::Codes::UNABLE_TO_AUTOMATICALLY_REENTER_PRESENCE_CHANNEL ) channel.emit :update, Ably::Models::ChannelStateChange.new( current: channel.state, previous: channel.state, event: Ably::Realtime::Channel::EVENT(:update), reason: re_enter_error, resumed: true ) end end end 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
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 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/ably/realtime/presence/members_map.rb', line 83 def get( = {}, &block) wait_for_sync = .fetch(:wait_for_sync, true) deferrable = Ably::Util::SafeDeferrable.new(logger) result_block = lambda do present_members.tap do |members| members.keep_if { |member| member.connection_id == [:connection_id] } if [:connection_id] members.keep_if { |member| member.client_id == [:client_id] } if [: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 sync_complete_callback = lambda do reset_callbacks.call if reset_callbacks result_block.call end sync_failed_callback = lambda do |error| reset_callbacks.call if reset_callbacks deferrable.fail error end reset_callbacks = lambda do off(&sync_complete_callback) off(&sync_failed_callback) channel.off(&sync_failed_callback) end unsafe_once(:sync_complete, &sync_complete_callback) unsafe_once(:failed, &sync_failed_callback) channel.unsafe_once(:detaching, :detached, :failed) do |error_reason| sync_failed_callback.call error_reason end end deferrable end |
#local_members ⇒ Hash<String, PresenceMessage>
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.
A copy of the local members present i.e. members entered from this connection and thus the responsibility of this library to re-enter on the channel automatically if the channel loses continuity
151 152 153 |
# File 'lib/ably/realtime/presence/members_map.rb', line 151 def local_members @local_members end |
#sync_serial_cursor_at_end? ⇒ 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 channel serial in ProtocolMessage SYNC is nil or an empty cursor appears after the ‘:’ such as ‘cf30e75054887:psl_7g:client:189’. That is an indication that there are no more SYNC messages.
68 69 70 |
# File 'lib/ably/realtime/presence/members_map.rb', line 68 def sync_serial_cursor_at_end? sync_serial.nil? || sync_serial.to_s.match(/^[\w-]+:?$/) 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
58 59 60 |
# File 'lib/ably/realtime/presence/members_map.rb', line 58 def update_sync_serial(serial) @sync_serial = serial end |