ably-rest 0.9.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ably-rest.gemspec +2 -1
- data/lib/submodules/ably-ruby/.travis.yml +6 -4
- data/lib/submodules/ably-ruby/CHANGELOG.md +52 -61
- data/lib/submodules/ably-ruby/README.md +10 -0
- data/lib/submodules/ably-ruby/SPEC.md +1473 -852
- data/lib/submodules/ably-ruby/ably.gemspec +2 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +57 -25
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +34 -8
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +10 -1
- data/lib/submodules/ably-ruby/lib/ably/models/auth_details.rb +42 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +18 -4
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +6 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +12 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message_encoders/base.rb +101 -97
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +13 -1
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +20 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/enum.rb +17 -7
- data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +29 -14
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +7 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/uses_state_machine.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +79 -31
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +62 -26
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +154 -65
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +14 -15
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +16 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +38 -29
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +108 -49
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +165 -59
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +22 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +19 -10
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +67 -45
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +198 -36
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +30 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_state_machine.rb +5 -12
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +3 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +21 -8
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/pub_sub.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +26 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +416 -99
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +1011 -160
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +458 -27
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +436 -97
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +52 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +1160 -105
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +151 -22
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +88 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +42 -15
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +4 -4
- data/lib/submodules/ably-ruby/spec/rspec_config.rb +2 -1
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +2 -2
- data/lib/submodules/ably-ruby/spec/shared/safe_deferrable_behaviour.rb +6 -2
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +20 -4
- data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +32 -1
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +4 -11
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +28 -2
- data/lib/submodules/ably-ruby/spec/unit/models/auth_details_spec.rb +49 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_state_change_spec.rb +23 -3
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +12 -1
- data/lib/submodules/ably-ruby/spec/unit/models/connection_state_change_spec.rb +15 -4
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +34 -2
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +73 -2
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +64 -6
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/token_request_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +2 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +69 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +149 -22
- data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +9 -3
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +8 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +4 -3
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +3 -3
- metadata +7 -5
|
@@ -11,7 +11,7 @@ module Ably::Models
|
|
|
11
11
|
# @!attribute [r] attributes
|
|
12
12
|
# @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
|
|
13
13
|
#
|
|
14
|
-
class ErrorInfo
|
|
14
|
+
class ErrorInfo < Ably::Exceptions::BaseAblyException
|
|
15
15
|
include Ably::Modules::ModelCommon
|
|
16
16
|
|
|
17
17
|
def initialize(hash_object)
|
|
@@ -124,6 +124,17 @@ module Ably::Models
|
|
|
124
124
|
@protocol_message
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
+
# Contains any arbitrary key value pairs which may also contain other primitive JSON types, JSON-encodable objects or JSON-encodable arrays.
|
|
128
|
+
# The extras field is provided to contain message metadata and/or ancillary payloads in support of specific functionality, e.g. push
|
|
129
|
+
# @api private
|
|
130
|
+
def extras
|
|
131
|
+
attributes[:extras].tap do |val|
|
|
132
|
+
unless val.kind_of?(IdiomaticRubyWrapper) || val.kind_of?(Array) || val.kind_of?(Hash) || val.nil?
|
|
133
|
+
raise ArgumentError, "extras contains an unsupported type #{val.class}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
127
138
|
private
|
|
128
139
|
def raw_hash_object
|
|
129
140
|
@raw_hash_object
|
|
@@ -134,7 +145,7 @@ module Ably::Models
|
|
|
134
145
|
end
|
|
135
146
|
|
|
136
147
|
def set_attributes_object(new_attributes)
|
|
137
|
-
@attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
|
|
148
|
+
@attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data, :extras])
|
|
138
149
|
end
|
|
139
150
|
|
|
140
151
|
def logger
|
|
@@ -7,115 +7,119 @@ require 'ably/modules/conversions'
|
|
|
7
7
|
# of the message is defined as 'json'.
|
|
8
8
|
# Encrypted messages are encoded & decoded by the Cipher encoder.
|
|
9
9
|
#
|
|
10
|
-
module Ably
|
|
11
|
-
|
|
10
|
+
module Ably
|
|
11
|
+
module Models
|
|
12
|
+
module MessageEncoders
|
|
13
|
+
extend Ably::Modules::Conversions
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
# Base interface for an Ably Encoder
|
|
16
|
+
#
|
|
17
|
+
class Base
|
|
18
|
+
attr_reader :client, :options
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
def initialize(client, options = {})
|
|
21
|
+
@client = client
|
|
22
|
+
@options = options
|
|
23
|
+
end
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
# #encode is called once before a message is sent to Ably
|
|
26
|
+
#
|
|
27
|
+
# It is the responsibility of the #encode method to detect the intended encoding and modify the :data & :encoding properties of the message object.
|
|
28
|
+
#
|
|
29
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
|
30
|
+
# The message contains properties :name, :data, :encoding, :timestamp, and optionally :id and :client_id.
|
|
31
|
+
# This #encode method should modify the message Hash if any encoding action is to be taken
|
|
32
|
+
# @param [Hash] channel_options the options used to initialize the channel that this message was received on
|
|
33
|
+
#
|
|
34
|
+
# @return [void]
|
|
35
|
+
def encode(message, channel_options)
|
|
36
|
+
raise "Not yet implemented"
|
|
37
|
+
end
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
# #decode is called once for every encoding step
|
|
40
|
+
# i.e. if message encoding arrives with 'utf-8/cipher+aes-128-cbc/base64'
|
|
41
|
+
# the decoder will call #decode once for each encoding part such as 'base64', then 'cipher+aes-128-cbc', and finally 'utf-8'
|
|
42
|
+
#
|
|
43
|
+
# It is the responsibility of the #decode method to detect the current encoding part and modify the :data & :encoding properties of the message object.
|
|
44
|
+
#
|
|
45
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
|
46
|
+
# The message contains properties :name, :data, :encoding, :timestamp, and optionally :id and :client_id.
|
|
47
|
+
# This #encode method should modify the message Hash if any decoding action is to be taken
|
|
48
|
+
# @param [Hash] channel_options the options used to initialize the channel that this message was received on
|
|
49
|
+
#
|
|
50
|
+
# @return [void]
|
|
51
|
+
def decode(message, channel_options)
|
|
52
|
+
raise "Not yet implemented"
|
|
53
|
+
end
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
# Add encoding to the message Hash.
|
|
56
|
+
# Ensures that encoding delimeter is used where required i.e utf-8/cipher+aes-128-cbc/base64
|
|
57
|
+
#
|
|
58
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
|
59
|
+
# @param [String] encoding encoding to add to the current encoding
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
62
|
+
def add_encoding_to_message(encoding, message)
|
|
63
|
+
message[:encoding] = [message[:encoding], encoding].compact.join('/')
|
|
64
|
+
end
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
# Returns the right most encoding form a meessage encoding, and nil if none exists
|
|
67
|
+
# i.e. current_encoding_part('utf-8/cipher+aes-128-cbc/base64') => 'base64'
|
|
68
|
+
#
|
|
69
|
+
# @return [String,nil]
|
|
70
|
+
def current_encoding_part(message)
|
|
71
|
+
if message[:encoding]
|
|
72
|
+
message[:encoding].split('/')[-1]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
# Strip the current encoding part within the message Hash.
|
|
77
|
+
#
|
|
78
|
+
# For example, calling this method on an :encoding value of 'utf-8/cipher+aes-128-cbc/base64' would update the attribute
|
|
79
|
+
# :encoding to 'utf-8/cipher+aes-128-cbc'
|
|
80
|
+
#
|
|
81
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
|
82
|
+
#
|
|
83
|
+
# @return [void]
|
|
84
|
+
def strip_current_encoding_part(message)
|
|
85
|
+
raise "Cannot strip encoding when there is no encoding for this message" unless message[:encoding]
|
|
86
|
+
message[:encoding] = message[:encoding].split('/')[0...-1].join('/')
|
|
87
|
+
message[:encoding] = nil if message[:encoding].empty?
|
|
88
|
+
end
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
# True of the message data payload is empty
|
|
91
|
+
#
|
|
92
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean]
|
|
95
|
+
def is_empty?(message)
|
|
96
|
+
message[:data].nil? || message[:data] == ''
|
|
97
|
+
end
|
|
98
|
+
end
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
# @api private
|
|
101
|
+
def self.register_default_encoders(client, options = {})
|
|
102
|
+
binary_protocol = !!options[:binary_protocol]
|
|
103
|
+
client.register_encoder Ably::Models::MessageEncoders::Utf8
|
|
104
|
+
client.register_encoder Ably::Models::MessageEncoders::Json
|
|
105
|
+
client.register_encoder Ably::Models::MessageEncoders::Cipher
|
|
106
|
+
client.register_encoder Ably::Models::MessageEncoders::Base64, binary_protocol: binary_protocol
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @api private
|
|
110
|
+
def self.encoder_from(encoder, options)
|
|
111
|
+
encoder_klass = if encoder.kind_of?(String)
|
|
112
|
+
encoder.split('::').inject(Kernel) do |base, klass_name|
|
|
113
|
+
base.public_send(:const_get, klass_name)
|
|
114
|
+
end
|
|
115
|
+
else
|
|
116
|
+
encoder
|
|
117
|
+
end
|
|
106
118
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
encoder_klass = if encoder.kind_of?(String)
|
|
110
|
-
encoder.split('::').inject(Kernel) do |base, klass_name|
|
|
111
|
-
base.public_send(:const_get, klass_name)
|
|
119
|
+
raise "Encoder must inherit from `Ably::Models::MessageEncoders::Base`" unless encoder_klass.ancestors.include?(Ably::Models::MessageEncoders::Base)
|
|
120
|
+
encoder_klass.new(self, options)
|
|
112
121
|
end
|
|
113
|
-
else
|
|
114
|
-
encoder
|
|
115
122
|
end
|
|
116
|
-
|
|
117
|
-
raise "Encoder must inherit from `Ably::Models::MessageEncoders::Base`" unless encoder_klass.ancestors.include?(Ably::Models::MessageEncoders::Base)
|
|
118
|
-
encoder_klass.new(self, options)
|
|
119
123
|
end
|
|
120
124
|
end
|
|
121
125
|
|
|
@@ -123,7 +123,6 @@ module Ably::Models
|
|
|
123
123
|
end.to_json
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
-
|
|
127
126
|
# Assign this presence message to a ProtocolMessage before delivery to the Ably system
|
|
128
127
|
# @api private
|
|
129
128
|
def assign_to_protocol_message(protocol_message)
|
|
@@ -145,6 +144,19 @@ module Ably::Models
|
|
|
145
144
|
@protocol_message
|
|
146
145
|
end
|
|
147
146
|
|
|
147
|
+
# Create a static shallow clone of this object with the optional attributes to overide existing values
|
|
148
|
+
# Shallow clones have no dependency on the originating ProtocolMessage as all field values are stored as opposed to calculated
|
|
149
|
+
# Clones are useful when the original PresenceMessage needs to be mutated, such as storing in a PresenceMap with action :present
|
|
150
|
+
def shallow_clone(new_attributes = {})
|
|
151
|
+
new_attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
|
|
152
|
+
|
|
153
|
+
self.class.new(attributes.to_hash.merge(
|
|
154
|
+
id: new_attributes[:id] || id,
|
|
155
|
+
connection_id: new_attributes[:connection_id] || connection_id,
|
|
156
|
+
timestamp: new_attributes[:timestamp] || as_since_epoch(timestamp)
|
|
157
|
+
).merge(new_attributes.to_hash))
|
|
158
|
+
end
|
|
159
|
+
|
|
148
160
|
private
|
|
149
161
|
def raw_hash_object
|
|
150
162
|
@raw_hash_object
|
|
@@ -8,6 +8,8 @@ module Ably::Models
|
|
|
8
8
|
#
|
|
9
9
|
# @!attribute [r] action
|
|
10
10
|
# @return [ACTION] Protocol Message action {Ably::Modules::Enum} from list of {ACTION}. Returns nil if action is unsupported by protocol
|
|
11
|
+
# @!attribute [r] auth
|
|
12
|
+
# @return [Ably::Models::AuthDetails] Authentication details used to perform authentication upgrades over an existing transport
|
|
11
13
|
# @!attribute [r] count
|
|
12
14
|
# @return [Integer] The count field is used for ACK and NACK actions. See {http://docs.ably.io/client-lib-development-guide/protocol/#message-acknowledgement message acknowledgement protocol}
|
|
13
15
|
# @!attribute [r] error
|
|
@@ -15,7 +17,7 @@ module Ably::Models
|
|
|
15
17
|
# @!attribute [r] channel
|
|
16
18
|
# @return [String] Channel name for messages
|
|
17
19
|
# @!attribute [r] channel_serial
|
|
18
|
-
# @return [String] Contains a serial number for a message on the current
|
|
20
|
+
# @return [String] Contains a serial number for a message on the current channel
|
|
19
21
|
# @!attribute [r] connection_id
|
|
20
22
|
# @return [String] Contains a string public identifier for the connection
|
|
21
23
|
# @!attribute [r] connection_key
|
|
@@ -62,13 +64,14 @@ module Ably::Models
|
|
|
62
64
|
detached: 13,
|
|
63
65
|
presence: 14,
|
|
64
66
|
message: 15,
|
|
65
|
-
sync: 16
|
|
67
|
+
sync: 16,
|
|
68
|
+
auth: 17
|
|
66
69
|
)
|
|
67
70
|
|
|
68
71
|
# Indicates this protocol message action will generate an ACK response such as :message or :presence
|
|
69
72
|
# @api private
|
|
70
73
|
def self.ack_required?(for_action)
|
|
71
|
-
|
|
74
|
+
ACTION(for_action).match_any?(ACTION.Presence, ACTION.Message)
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
# {ProtocolMessage} initializer
|
|
@@ -193,10 +196,24 @@ module Ably::Models
|
|
|
193
196
|
flags & 1 == 1
|
|
194
197
|
end
|
|
195
198
|
|
|
199
|
+
# @api private
|
|
200
|
+
def has_backlog_flag?
|
|
201
|
+
flags & 2 == 2
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# @api private
|
|
205
|
+
def has_channel_resumed_flag?
|
|
206
|
+
flags & 4 == 4
|
|
207
|
+
end
|
|
208
|
+
|
|
196
209
|
def connection_details
|
|
197
210
|
@connection_details ||= Ably::Models::ConnectionDetails(attributes[:connection_details])
|
|
198
211
|
end
|
|
199
212
|
|
|
213
|
+
def auth
|
|
214
|
+
@auth ||= Ably::Models::AuthDetails(attributes[:auth])
|
|
215
|
+
end
|
|
216
|
+
|
|
200
217
|
# Indicates this protocol message will generate an ACK response when sent
|
|
201
218
|
# Examples of protocol messages required ACK include :message and :presence
|
|
202
219
|
# @api private
|
|
@@ -38,7 +38,7 @@ module Ably::Modules
|
|
|
38
38
|
# @yield [Object] operation block that is run in a thread
|
|
39
39
|
# @return [Ably::Util::SafeDeferrable]
|
|
40
40
|
#
|
|
41
|
-
def async_wrap(success_callback = nil)
|
|
41
|
+
def async_wrap(success_callback = nil, custom_error_handling = nil)
|
|
42
42
|
raise ArgumentError, 'Block required' unless block_given?
|
|
43
43
|
|
|
44
44
|
Ably::Util::SafeDeferrable.new(logger).tap do |deferrable|
|
|
@@ -48,8 +48,12 @@ module Ably::Modules
|
|
|
48
48
|
begin
|
|
49
49
|
yield
|
|
50
50
|
rescue StandardError => err
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
if custom_error_handling
|
|
52
|
+
custom_error_handling.call err, deferrable
|
|
53
|
+
else
|
|
54
|
+
logger.error { "An exception in an AsyncWrapper block was caught. #{err.class}: #{err.message}\n#{err.backtrace.join("\n")}" }
|
|
55
|
+
deferrable.fail err
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
end
|
|
55
59
|
|
|
@@ -49,11 +49,11 @@ module Ably::Modules
|
|
|
49
49
|
def get(identifier)
|
|
50
50
|
case identifier
|
|
51
51
|
when Symbol
|
|
52
|
-
by_symbol.fetch(identifier)
|
|
52
|
+
by_symbol.fetch(identifier) { raise KeyError, "#{name} key not found: :#{identifier}" }
|
|
53
53
|
when String
|
|
54
|
-
by_symbol.fetch(convert_to_snake_case_symbol(identifier))
|
|
54
|
+
by_symbol.fetch(convert_to_snake_case_symbol(identifier)) { raise KeyError, "#{name} key not found: '#{identifier}'" }
|
|
55
55
|
when Numeric
|
|
56
|
-
by_index.fetch(identifier)
|
|
56
|
+
by_index.fetch(identifier) { raise KeyError, "#{name} key not found: #{identifier}" }
|
|
57
57
|
when ancestors.first
|
|
58
58
|
identifier
|
|
59
59
|
else
|
|
@@ -89,6 +89,12 @@ module Ably::Modules
|
|
|
89
89
|
@enum_name
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
# Array of Enum values as symbols
|
|
93
|
+
# @return [Array<Symbol>]
|
|
94
|
+
def to_sym_arr
|
|
95
|
+
@by_symbol.keys
|
|
96
|
+
end
|
|
97
|
+
|
|
92
98
|
private
|
|
93
99
|
def by_index
|
|
94
100
|
@by_index
|
|
@@ -158,7 +164,7 @@ module Ably::Modules
|
|
|
158
164
|
|
|
159
165
|
# Allow comparison of Enum objects based on:
|
|
160
166
|
#
|
|
161
|
-
# * Other equivalent Enum objects
|
|
167
|
+
# * Other equivalent Enum objects compared by Symbol (not Integer value)
|
|
162
168
|
# * Symbol
|
|
163
169
|
# * String
|
|
164
170
|
# * Integer index of Enum
|
|
@@ -171,13 +177,17 @@ module Ably::Modules
|
|
|
171
177
|
self.to_sym == convert_to_snake_case_symbol(other)
|
|
172
178
|
when Numeric
|
|
173
179
|
self.to_i == other.to_i
|
|
174
|
-
when self.class
|
|
175
|
-
self.to_i == other.to_i
|
|
176
180
|
else
|
|
177
|
-
|
|
181
|
+
if other.kind_of?(Ably::Modules::Enum::Base)
|
|
182
|
+
self.to_sym == other.to_sym
|
|
183
|
+
end
|
|
178
184
|
end
|
|
179
185
|
end
|
|
180
186
|
|
|
187
|
+
def match_any?(*enums)
|
|
188
|
+
enums.any? { |enum| self.==(enum) }
|
|
189
|
+
end
|
|
190
|
+
|
|
181
191
|
private
|
|
182
192
|
def name
|
|
183
193
|
@name
|
|
@@ -54,7 +54,7 @@ module Ably
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Equivalent of {#on} but any exception raised in a block will bubble up and cause this client library to fail.
|
|
57
|
-
# This method
|
|
57
|
+
# This method is designed to be used internally by the client library.
|
|
58
58
|
# @api private
|
|
59
59
|
def unsafe_on(*event_names, &block)
|
|
60
60
|
add_callback event_names, proc_for_block(block, unsafe: true)
|
|
@@ -70,7 +70,7 @@ module Ably
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
# Equivalent of {#once} but any exception raised in a block will bubble up and cause this client library to fail.
|
|
73
|
-
# This method
|
|
73
|
+
# This method is designed to be used internally by the client library.
|
|
74
74
|
# @api private
|
|
75
75
|
def unsafe_once(*event_names, &block)
|
|
76
76
|
add_callback event_names, proc_for_block(block, delete_once_run: true, unsafe: true)
|
|
@@ -101,30 +101,45 @@ module Ably
|
|
|
101
101
|
#
|
|
102
102
|
# @return [void]
|
|
103
103
|
def off(*event_names, &block)
|
|
104
|
+
off_internal(false, *event_names, &block)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Equivalent of {#off} but only unsafe listeners are removed.
|
|
108
|
+
# This method is designed to be used internally by the client library.
|
|
109
|
+
# @api private
|
|
110
|
+
def unsafe_off(*event_names, &block)
|
|
111
|
+
off_internal(true, *event_names, &block)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
def off_internal(unsafe, *event_names, &block)
|
|
104
116
|
keys = if event_names.empty?
|
|
105
117
|
callbacks.keys
|
|
106
118
|
else
|
|
107
119
|
event_names
|
|
108
120
|
end
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
if event_names.empty?
|
|
123
|
+
callbacks_any.delete_if do |proc_hash|
|
|
124
|
+
if block_given?
|
|
125
|
+
(proc_hash[:unsafe] == unsafe) && (proc_hash[:block] == block)
|
|
126
|
+
else
|
|
127
|
+
proc_hash[:unsafe] == unsafe
|
|
128
|
+
end
|
|
115
129
|
end
|
|
116
130
|
end
|
|
117
131
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
132
|
+
keys.each do |event_name|
|
|
133
|
+
callbacks[callbacks_event_coerced(event_name)].delete_if do |proc_hash|
|
|
134
|
+
if block_given?
|
|
135
|
+
(proc_hash[:unsafe] == unsafe) && (proc_hash[:block] == block)
|
|
136
|
+
else
|
|
137
|
+
proc_hash[:unsafe] == unsafe
|
|
138
|
+
end
|
|
123
139
|
end
|
|
124
140
|
end
|
|
125
141
|
end
|
|
126
142
|
|
|
127
|
-
private
|
|
128
143
|
def self.included(klass)
|
|
129
144
|
klass.extend ClassMethods
|
|
130
145
|
end
|
|
@@ -148,7 +163,7 @@ module Ably
|
|
|
148
163
|
true if options[:delete_once_run]
|
|
149
164
|
end,
|
|
150
165
|
block: block,
|
|
151
|
-
unsafe: options[:unsafe]
|
|
166
|
+
unsafe: options[:unsafe] || false
|
|
152
167
|
}
|
|
153
168
|
end
|
|
154
169
|
|