lib/ably/realtime/presence/members_map.rb in ably-0.8.1 vs lib/ably/realtime/presence/members_map.rb in ably-0.8.2
- old
+ new
@@ -24,14 +24,10 @@
:in_sync,
:failed
)
include Ably::Modules::StateEmitter
- # Number of absent members to cache internally whilst channel is in sync.
- # Cache is unlimited until initial sync is complete ensuring users who have left are never reported as present.
- MAX_ABSENT_MEMBER_CACHE = 100
-
def initialize(presence)
@presence = presence
@state = STATE(:initialized)
@members = Hash.new
@@ -64,18 +60,18 @@
# Get the list of presence members
#
# @param [Hash,String] options an options Hash to filter members
# @option options [String] :client_id optional client_id for the member
# @option options [String] :connection_id optional connection_id for the member
- # @option options [String] :wait_for_sync defaults to true, if false the get method returns the current list of members and does not wait for the presence sync to complete
+ # @option options [String] :wait_for_sync defaults to false, if true the get method waits for the initial presence sync following channel attachment to complete before returning the members present
#
# @yield [Array<Ably::Models::PresenceMessage>] array of present members
#
# @return [Ably::Util::SafeDeferrable] Deferrable that supports both success (callback) and failure (errback) callbacks
#
def get(options = {}, &block)
- wait_for_sync = options.fetch(:wait_for_sync, true)
+ 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]
@@ -162,10 +158,14 @@
resume_sync_proc = method(:resume_sync).to_proc
connection.on_resume &resume_sync_proc
once(:in_sync, :failed) do
connection.off_resume &resume_sync_proc
end
+
+ once(:in_sync) do
+ clean_up_absent_members
+ end
end
# Trigger a manual SYNC operation to resume member synchronisation from last known cursor position
def resume_sync
connection.send_protocol_message(
@@ -196,20 +196,18 @@
when Ably::Models::PresenceMessage::ACTION.Leave
remove_presence_member presence_message
else
Ably::Exceptions::ProtocolError.new("Protocol error, unknown presence action #{presence_message.action}", 400, 80013)
end
-
- clean_up_absent_members
end
def ensure_presence_message_is_valid(presence_message)
return true if presence_message.connection_id
error = Ably::Exceptions::ProtocolError.new("Protocol error, presence message is missing connectionId", 400, 80013)
logger.error "PresenceMap: On channel '#{channel.name}' error: #{error}"
- channel.trigger :error, error
+ channel.emit :error, error
end
# If the message received is older than the last known event for presence
# then skip. This can occur during a SYNC operation. For example:
# - SYNC starts
@@ -232,12 +230,18 @@
presence.emit_message presence_message.action, presence_message
end
def remove_presence_member(presence_message)
logger.debug "#{self.class.name}: Member '#{presence_message.member_key}' removed.\n#{presence_message.to_json}"
- members[presence_message.member_key] = { present: false, message: presence_message }
- absent_member_cleanup_queue << presence_message.member_key
+
+ if in_sync?
+ members.delete presence_message.member_key
+ else
+ members[presence_message.member_key] = { present: false, message: presence_message }
+ absent_member_cleanup_queue << presence_message.member_key
+ end
+
presence.emit_message presence_message.action, presence_message
end
def present_members
members.select do |key, presence|
@@ -254,11 +258,10 @@
presence.fetch(:message)
end
end
def clean_up_absent_members
- return unless sync_complete?
- members.delete absent_member_cleanup_queue.shift until absent_member_cleanup_queue.count <= MAX_ABSENT_MEMBER_CACHE
+ members.delete absent_member_cleanup_queue.shift
end
end
end
end