ably 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +7 -4
- data/SPEC.md +141 -59
- data/ably.gemspec +1 -1
- data/lib/ably/models/stat.rb +161 -0
- data/lib/ably/modules/ably.rb +1 -1
- data/lib/ably/realtime/client.rb +7 -3
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +1 -1
- data/lib/ably/realtime/connection.rb +25 -9
- data/lib/ably/realtime/connection/connection_manager.rb +2 -2
- data/lib/ably/rest/client.rb +21 -8
- data/lib/ably/rest/middleware/logger.rb +1 -1
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +2 -2
- data/spec/acceptance/realtime/connection_failures_spec.rb +2 -2
- data/spec/acceptance/realtime/connection_spec.rb +68 -3
- data/spec/acceptance/realtime/stats_spec.rb +2 -2
- data/spec/acceptance/rest/auth_spec.rb +8 -6
- data/spec/acceptance/rest/encoders_spec.rb +9 -9
- data/spec/acceptance/rest/presence_spec.rb +2 -4
- data/spec/acceptance/rest/stats_spec.rb +148 -39
- data/spec/support/api_helper.rb +2 -1
- data/spec/support/rest_testapp_before_retry.rb +1 -1
- data/spec/support/test_app.rb +13 -5
- data/spec/unit/models/stat_spec.rb +113 -0
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +1 -1
- metadata +42 -75
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b651a5ed9326c5950e3aec0232ef8b96b548021b
|
4
|
+
data.tar.gz: 1b6db9eb56d925b901e8e26e6e15863820562234
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 80518f8fb55cef422fe8da8c96c314bc63e95ece705b9851dcf4613862d6b5b804285535bb0303750636b7db55529301c1c00a32bf50f9e13332c9c4c828c709
|
7
|
+
data.tar.gz: 19619184eb6ebe32608e5f642b158b5e9a1bae3e9d713422174ec5082aadcbcc15845e5351ee395bd3c5f978f8d8c6ea88461eb944b509fab914d97c06ff3b27
|
data/.travis.yml
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
env: RSPEC_RETRY=true
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
- 2.2.0
|
7
|
+
script: bundle exec rspec
|
8
|
+
notifications:
|
9
|
+
slack:
|
10
|
+
secure: Xe8MwDcV2C8XLGk6O6Co31LpQiRSxsmS7Toy5vM7rHds5fnVRBNn5iX6Q5mXMdLOlnsMhjKLt7zl4fsBOZv+siQ+Us0omZSIYpXCYSCIj8nofReF0Lj8M4oa6lFSL5OuygO7PH+wLKTRxQURGZ6Pi1nHU+RE5izRmsewQHkhtY0=
|
data/SPEC.md
CHANGED
@@ -209,84 +209,90 @@ _(see [spec/acceptance/realtime/connection_spec.rb](./spec/acceptance/realtime/c
|
|
209
209
|
* [uses the primary host for subsequent connection and auth requests](./spec/acceptance/realtime/connection_spec.rb#L117)
|
210
210
|
* when connected with a valid non-expired token
|
211
211
|
* that then expires following the connection being opened
|
212
|
-
* PENDING: *[retains connection state](./spec/acceptance/realtime/connection_spec.rb#
|
213
|
-
* PENDING: *[changes state to failed if a new token cannot be issued](./spec/acceptance/realtime/connection_spec.rb#
|
212
|
+
* PENDING: *[retains connection state](./spec/acceptance/realtime/connection_spec.rb#L167)*
|
213
|
+
* PENDING: *[changes state to failed if a new token cannot be issued](./spec/acceptance/realtime/connection_spec.rb#L168)*
|
214
214
|
* the server
|
215
|
-
* [disconnects the client, and the client automatically renews the token and then reconnects](./spec/acceptance/realtime/connection_spec.rb#
|
215
|
+
* [disconnects the client, and the client automatically renews the token and then reconnects](./spec/acceptance/realtime/connection_spec.rb#L144)
|
216
216
|
* for non-renewable tokens
|
217
217
|
* that are expired
|
218
218
|
* opening a new connection
|
219
|
-
* [transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#
|
219
|
+
* [transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L183)
|
220
220
|
* when connected
|
221
|
-
* PENDING: *[transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#
|
221
|
+
* PENDING: *[transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L196)*
|
222
222
|
* initialization state changes
|
223
223
|
* with implicit #connect
|
224
|
-
* [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#
|
224
|
+
* [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L223)
|
225
225
|
* with explicit #connect
|
226
|
-
* [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#
|
226
|
+
* [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L229)
|
227
227
|
* #connect
|
228
|
-
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#
|
229
|
-
* [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#
|
228
|
+
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L237)
|
229
|
+
* [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L242)
|
230
230
|
* when already connected
|
231
|
-
* [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#
|
231
|
+
* [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L251)
|
232
232
|
* once connected
|
233
233
|
* connection#id
|
234
|
-
* [is a string](./spec/acceptance/realtime/connection_spec.rb#
|
235
|
-
* [is unique from the connection#key](./spec/acceptance/realtime/connection_spec.rb#
|
236
|
-
* [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#
|
234
|
+
* [is a string](./spec/acceptance/realtime/connection_spec.rb#L268)
|
235
|
+
* [is unique from the connection#key](./spec/acceptance/realtime/connection_spec.rb#L275)
|
236
|
+
* [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L282)
|
237
237
|
* connection#key
|
238
|
-
* [is a string](./spec/acceptance/realtime/connection_spec.rb#
|
239
|
-
* [is unique from the connection#id](./spec/acceptance/realtime/connection_spec.rb#
|
240
|
-
* [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#
|
238
|
+
* [is a string](./spec/acceptance/realtime/connection_spec.rb#L291)
|
239
|
+
* [is unique from the connection#id](./spec/acceptance/realtime/connection_spec.rb#L298)
|
240
|
+
* [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L305)
|
241
241
|
* following a previous connection being opened and closed
|
242
|
-
* [reconnects and is provided with a new connection ID and connection key from the server](./spec/acceptance/realtime/connection_spec.rb#
|
242
|
+
* [reconnects and is provided with a new connection ID and connection key from the server](./spec/acceptance/realtime/connection_spec.rb#L315)
|
243
|
+
* #serial connection serial
|
244
|
+
* [is set to -1 when a new connection is opened](./spec/acceptance/realtime/connection_spec.rb#L335)
|
245
|
+
* [is set to 0 when a message sent ACK is received](./spec/acceptance/realtime/connection_spec.rb#L357)
|
246
|
+
* [is set to 1 when the second message sent ACK is received](./spec/acceptance/realtime/connection_spec.rb#L364)
|
247
|
+
* when a message is sent but the ACK has not yet been received
|
248
|
+
* [the sent message msgSerial is 0 but the connection serial remains at -1](./spec/acceptance/realtime/connection_spec.rb#L344)
|
243
249
|
* #close
|
244
|
-
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#
|
245
|
-
* [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#
|
250
|
+
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L375)
|
251
|
+
* [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L382)
|
246
252
|
* when already closed
|
247
|
-
* [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#
|
253
|
+
* [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L393)
|
248
254
|
* when connection state is
|
249
255
|
* :initialized
|
250
|
-
* [changes the connection state to :closing and then immediately :closed without sending a ProtocolMessage CLOSE](./spec/acceptance/realtime/connection_spec.rb#
|
256
|
+
* [changes the connection state to :closing and then immediately :closed without sending a ProtocolMessage CLOSE](./spec/acceptance/realtime/connection_spec.rb#L421)
|
251
257
|
* :connected
|
252
|
-
* [changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage](./spec/acceptance/realtime/connection_spec.rb#
|
258
|
+
* [changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage](./spec/acceptance/realtime/connection_spec.rb#L439)
|
253
259
|
* with an unresponsive connection
|
254
|
-
* [force closes the connection when a :closed ProtocolMessage response is not received](./spec/acceptance/realtime/connection_spec.rb#
|
260
|
+
* [force closes the connection when a :closed ProtocolMessage response is not received](./spec/acceptance/realtime/connection_spec.rb#L469)
|
255
261
|
* #ping
|
256
|
-
* [echoes a heart beat](./spec/acceptance/realtime/connection_spec.rb#
|
262
|
+
* [echoes a heart beat](./spec/acceptance/realtime/connection_spec.rb#L492)
|
257
263
|
* when not connected
|
258
|
-
* [raises an exception](./spec/acceptance/realtime/connection_spec.rb#
|
264
|
+
* [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L502)
|
259
265
|
* recovery
|
260
266
|
* #recovery_key
|
261
|
-
* [is composed of connection id and serial that is kept up to date with each message
|
262
|
-
* [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#
|
263
|
-
* [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#
|
267
|
+
* [is composed of connection id and serial that is kept up to date with each message ACK received](./spec/acceptance/realtime/connection_spec.rb#L535)
|
268
|
+
* [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#L556)
|
269
|
+
* [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#L580)
|
264
270
|
* opening a new connection using a recently disconnected connection's #recovery_key
|
265
271
|
* connection#id and connection#key after recovery
|
266
|
-
* [remain the same](./spec/acceptance/realtime/connection_spec.rb#
|
272
|
+
* [remain the same](./spec/acceptance/realtime/connection_spec.rb#L594)
|
267
273
|
* when messages have been sent whilst the old connection is disconnected
|
268
274
|
* the new connection
|
269
|
-
* [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#
|
275
|
+
* [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#L619)
|
270
276
|
* with :recover option
|
271
277
|
* with invalid syntax
|
272
|
-
* [raises an exception](./spec/acceptance/realtime/connection_spec.rb#
|
278
|
+
* [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L644)
|
273
279
|
* with invalid formatted value sent to server
|
274
|
-
* [triggers a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#
|
280
|
+
* [triggers a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#L653)
|
275
281
|
* with expired (missing) value sent to server
|
276
|
-
* [triggers an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#
|
282
|
+
* [triggers an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#L667)
|
277
283
|
* with many connections simultaneously
|
278
|
-
* [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#
|
284
|
+
* [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#L685)
|
279
285
|
* when a state transition is unsupported
|
280
|
-
* [emits a StateChangeError](./spec/acceptance/realtime/connection_spec.rb#
|
286
|
+
* [emits a StateChangeError](./spec/acceptance/realtime/connection_spec.rb#L705)
|
281
287
|
* undocumented method
|
282
288
|
* #internet_up?
|
283
|
-
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#
|
289
|
+
* [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L720)
|
284
290
|
* when the Internet is up
|
285
|
-
* [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#
|
286
|
-
* [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#
|
291
|
+
* [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#L726)
|
292
|
+
* [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L733)
|
287
293
|
* when the Internet is down
|
288
|
-
* [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#
|
289
|
-
* [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#
|
294
|
+
* [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#L745)
|
295
|
+
* [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L752)
|
290
296
|
|
291
297
|
### Ably::Realtime::Channel Message
|
292
298
|
_(see [spec/acceptance/realtime/message_spec.rb](./spec/acceptance/realtime/message_spec.rb))_
|
@@ -506,7 +512,7 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
|
|
506
512
|
_(see [spec/acceptance/realtime/stats_spec.rb](./spec/acceptance/realtime/stats_spec.rb))_
|
507
513
|
* using JSON and MsgPack protocol
|
508
514
|
* fetching stats
|
509
|
-
* [should return a
|
515
|
+
* [should return a PaginatedResource](./spec/acceptance/realtime/stats_spec.rb#L10)
|
510
516
|
* [should return a Deferrable object](./spec/acceptance/realtime/stats_spec.rb#L17)
|
511
517
|
|
512
518
|
### Ably::Realtime::Client#time
|
@@ -738,29 +744,29 @@ _(see [spec/acceptance/rest/encoders_spec.rb](./spec/acceptance/rest/encoders_sp
|
|
738
744
|
* with binary data
|
739
745
|
* [does not apply any encoding](./spec/acceptance/rest/encoders_spec.rb#L52)
|
740
746
|
* with JSON data
|
741
|
-
* [stringifies the JSON and sets the
|
747
|
+
* [stringifies the JSON and sets the encoding attribute to "json"](./spec/acceptance/rest/encoders_spec.rb#L63)
|
742
748
|
* with encryption
|
743
749
|
* with UTF-8 data
|
744
|
-
* [applies utf-8 and cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L78)
|
750
|
+
* [applies utf-8 and cipher encoding and sets the encoding attribute to "utf-8/cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L78)
|
745
751
|
* with binary data
|
746
|
-
* [applies cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L89)
|
752
|
+
* [applies cipher encoding and sets the encoding attribute to "cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L89)
|
747
753
|
* with JSON data
|
748
|
-
* [applies json, utf-8 and cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L100)
|
754
|
+
* [applies json, utf-8 and cipher encoding and sets the encoding attribute to "json/utf-8/cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L100)
|
749
755
|
* with text transport protocol
|
750
756
|
* without encryption
|
751
757
|
* with UTF-8 data
|
752
758
|
* [does not apply any encoding](./spec/acceptance/rest/encoders_spec.rb#L117)
|
753
759
|
* with binary data
|
754
|
-
* [applies a base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L128)
|
760
|
+
* [applies a base64 encoding and sets the encoding attribute to "base64"](./spec/acceptance/rest/encoders_spec.rb#L128)
|
755
761
|
* with JSON data
|
756
|
-
* [stringifies the JSON and sets the
|
762
|
+
* [stringifies the JSON and sets the encoding attribute to "json"](./spec/acceptance/rest/encoders_spec.rb#L139)
|
757
763
|
* with encryption
|
758
764
|
* with UTF-8 data
|
759
|
-
* [applies utf-8, cipher and base64 encodings](./spec/acceptance/rest/encoders_spec.rb#L154)
|
765
|
+
* [applies utf-8, cipher and base64 encodings and sets the encoding attribute to "utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L154)
|
760
766
|
* with binary data
|
761
|
-
* [applies cipher and base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L165)
|
767
|
+
* [applies cipher and base64 encoding and sets the encoding attribute to "utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L165)
|
762
768
|
* with JSON data
|
763
|
-
* [applies json, utf-8, cipher and base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L176)
|
769
|
+
* [applies json, utf-8, cipher and base64 encoding and sets the encoding attribute to "json/utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L176)
|
764
770
|
|
765
771
|
### Ably::Rest::Channel messages
|
766
772
|
_(see [spec/acceptance/rest/message_spec.rb](./spec/acceptance/rest/message_spec.rb))_
|
@@ -867,13 +873,32 @@ _(see [spec/acceptance/rest/stats_spec.rb](./spec/acceptance/rest/stats_spec.rb)
|
|
867
873
|
* using JSON and MsgPack protocol
|
868
874
|
* fetching application stats
|
869
875
|
* by minute
|
870
|
-
*
|
876
|
+
* with :from set to last interval and :limit set to 1
|
877
|
+
* [retrieves only one stat](./spec/acceptance/rest/stats_spec.rb#L51)
|
878
|
+
* [returns accurate all aggregated message data](./spec/acceptance/rest/stats_spec.rb#L55)
|
879
|
+
* [returns accurate inbound realtime all data](./spec/acceptance/rest/stats_spec.rb#L60)
|
880
|
+
* [returns accurate inbound realtime message data](./spec/acceptance/rest/stats_spec.rb#L65)
|
881
|
+
* [returns accurate outbound realtime all data](./spec/acceptance/rest/stats_spec.rb#L70)
|
882
|
+
* [returns accurate persisted presence all data](./spec/acceptance/rest/stats_spec.rb#L75)
|
883
|
+
* [returns accurate connections all data](./spec/acceptance/rest/stats_spec.rb#L80)
|
884
|
+
* [returns accurate channels all data](./spec/acceptance/rest/stats_spec.rb#L85)
|
885
|
+
* [returns accurate api_requests data](./spec/acceptance/rest/stats_spec.rb#L90)
|
886
|
+
* [returns accurate token_requests data](./spec/acceptance/rest/stats_spec.rb#L95)
|
887
|
+
* [returns stat objects with #interval_granularity equal to :minute](./spec/acceptance/rest/stats_spec.rb#L100)
|
888
|
+
* [returns stat objects with #interval_id matching :start](./spec/acceptance/rest/stats_spec.rb#L104)
|
889
|
+
* [returns stat objects with #interval_time matching :start Time](./spec/acceptance/rest/stats_spec.rb#L108)
|
890
|
+
* with :start set to first interval, :limit set to 1 and direction :forwards
|
891
|
+
* [returns the first interval stats as stats are provided forwards from :start](./spec/acceptance/rest/stats_spec.rb#L118)
|
892
|
+
* [returns 3 pages of stats](./spec/acceptance/rest/stats_spec.rb#L122)
|
893
|
+
* with :end set to last interval, :limit set to 1 and direction :backwards
|
894
|
+
* [returns the 3rd interval stats first as stats are provided backwards from :end](./spec/acceptance/rest/stats_spec.rb#L135)
|
895
|
+
* [returns 3 pages of stats](./spec/acceptance/rest/stats_spec.rb#L139)
|
871
896
|
* by hour
|
872
|
-
* [should
|
897
|
+
* [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
|
873
898
|
* by day
|
874
|
-
* [should
|
899
|
+
* [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
|
875
900
|
* by month
|
876
|
-
* [should
|
901
|
+
* [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
|
877
902
|
|
878
903
|
### Ably::Rest::Client#time
|
879
904
|
_(see [spec/acceptance/rest/time_spec.rb](./spec/acceptance/rest/time_spec.rb))_
|
@@ -1337,6 +1362,63 @@ _(see [spec/unit/models/protocol_message_spec.rb](./spec/unit/models/protocol_me
|
|
1337
1362
|
* with error
|
1338
1363
|
* [returns a valid ErrorInfo object](./spec/unit/models/protocol_message_spec.rb#L261)
|
1339
1364
|
|
1365
|
+
### Ably::Models::Stat
|
1366
|
+
_(see [spec/unit/models/stat_spec.rb](./spec/unit/models/stat_spec.rb))_
|
1367
|
+
* behaves like a model
|
1368
|
+
* attributes
|
1369
|
+
* #interval_id
|
1370
|
+
* [retrieves attribute :interval_id](./spec/shared/model_behaviour.rb#L15)
|
1371
|
+
* #all
|
1372
|
+
* [retrieves attribute :all](./spec/shared/model_behaviour.rb#L15)
|
1373
|
+
* #inbound
|
1374
|
+
* [retrieves attribute :inbound](./spec/shared/model_behaviour.rb#L15)
|
1375
|
+
* #outbound
|
1376
|
+
* [retrieves attribute :outbound](./spec/shared/model_behaviour.rb#L15)
|
1377
|
+
* #persisted
|
1378
|
+
* [retrieves attribute :persisted](./spec/shared/model_behaviour.rb#L15)
|
1379
|
+
* #connections
|
1380
|
+
* [retrieves attribute :connections](./spec/shared/model_behaviour.rb#L15)
|
1381
|
+
* #channels
|
1382
|
+
* [retrieves attribute :channels](./spec/shared/model_behaviour.rb#L15)
|
1383
|
+
* #api_requests
|
1384
|
+
* [retrieves attribute :api_requests](./spec/shared/model_behaviour.rb#L15)
|
1385
|
+
* #token_requests
|
1386
|
+
* [retrieves attribute :token_requests](./spec/shared/model_behaviour.rb#L15)
|
1387
|
+
* #==
|
1388
|
+
* [is true when attributes are the same](./spec/shared/model_behaviour.rb#L41)
|
1389
|
+
* [is false when attributes are not the same](./spec/shared/model_behaviour.rb#L46)
|
1390
|
+
* [is false when class type differs](./spec/shared/model_behaviour.rb#L50)
|
1391
|
+
* is immutable
|
1392
|
+
* [prevents changes](./spec/shared/model_behaviour.rb#L76)
|
1393
|
+
* [dups options](./spec/shared/model_behaviour.rb#L80)
|
1394
|
+
* #interval_granularity
|
1395
|
+
* [returns the granularity of the interval_id](./spec/unit/models/stat_spec.rb#L17)
|
1396
|
+
* #interval_time
|
1397
|
+
* [returns a Time object representing the start of the interval](./spec/unit/models/stat_spec.rb#L25)
|
1398
|
+
* class methods
|
1399
|
+
* #to_interval_id
|
1400
|
+
* when time zone of time argument is UTC
|
1401
|
+
* [converts time 2014-02-03:05:06 with granularity :month into 2014-02](./spec/unit/models/stat_spec.rb#L33)
|
1402
|
+
* [converts time 2014-02-03:05:06 with granularity :day into 2014-02-03](./spec/unit/models/stat_spec.rb#L37)
|
1403
|
+
* [converts time 2014-02-03:05:06 with granularity :hour into 2014-02-03:05](./spec/unit/models/stat_spec.rb#L41)
|
1404
|
+
* [converts time 2014-02-03:05:06 with granularity :minute into 2014-02-03:05:06](./spec/unit/models/stat_spec.rb#L45)
|
1405
|
+
* [fails with invalid granularity](./spec/unit/models/stat_spec.rb#L49)
|
1406
|
+
* [fails with invalid time](./spec/unit/models/stat_spec.rb#L53)
|
1407
|
+
* when time zone of time argument is +02:00
|
1408
|
+
* [converts time 2014-02-03:06 with granularity :hour into 2014-02-03:04 at UTC +00:00](./spec/unit/models/stat_spec.rb#L59)
|
1409
|
+
* #from_interval_id
|
1410
|
+
* [converts a month interval_id 2014-02 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L66)
|
1411
|
+
* [converts a day interval_id 2014-02-03 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L71)
|
1412
|
+
* [converts an hour interval_id 2014-02-03:05 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L76)
|
1413
|
+
* [converts a minute interval_id 2014-02-03:05:06 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L81)
|
1414
|
+
* [fails with an invalid interval_id 14-20](./spec/unit/models/stat_spec.rb#L86)
|
1415
|
+
* #granularity_from_interval_id
|
1416
|
+
* [returns a :month interval_id for 2014-02](./spec/unit/models/stat_spec.rb#L92)
|
1417
|
+
* [returns a :day interval_id for 2014-02-03](./spec/unit/models/stat_spec.rb#L96)
|
1418
|
+
* [returns a :hour interval_id for 2014-02-03:05](./spec/unit/models/stat_spec.rb#L100)
|
1419
|
+
* [returns a :minute interval_id for 2014-02-03:05:06](./spec/unit/models/stat_spec.rb#L104)
|
1420
|
+
* [fails with an invalid interval_id 14-20](./spec/unit/models/stat_spec.rb#L108)
|
1421
|
+
|
1340
1422
|
### Ably::Models::Token
|
1341
1423
|
_(see [spec/unit/models/token_spec.rb](./spec/unit/models/token_spec.rb))_
|
1342
1424
|
* behaves like a model
|
@@ -1703,10 +1785,10 @@ _(see [spec/unit/util/pub_sub_spec.rb](./spec/unit/util/pub_sub_spec.rb))_
|
|
1703
1785
|
* [deletes all callbacks if not block given](./spec/unit/util/pub_sub_spec.rb#L76)
|
1704
1786
|
* [continues if the block does not exist](./spec/unit/util/pub_sub_spec.rb#L81)
|
1705
1787
|
|
1706
|
-
-------
|
1788
|
+
-------
|
1707
1789
|
|
1708
|
-
## Test summary
|
1790
|
+
## Test summary
|
1709
1791
|
|
1710
|
-
* Passing tests:
|
1711
|
-
* Pending tests: 11
|
1712
|
-
* Failing tests: 0
|
1792
|
+
* Passing tests: 864
|
1793
|
+
* Pending tests: 11
|
1794
|
+
* Failing tests: 0
|
data/ably.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
30
|
spec.add_development_dependency 'rake'
|
31
31
|
spec.add_development_dependency 'redcarpet'
|
32
|
-
spec.add_development_dependency 'rspec', '~> 3.1.0' # version lock, see event_machine_helper.rb
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.1.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
|
33
33
|
spec.add_development_dependency 'rspec-retry'
|
34
34
|
spec.add_development_dependency 'yard'
|
35
35
|
spec.add_development_dependency 'webmock'
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module Ably::Models
|
2
|
+
# Convert stat argument to a {Stat} object
|
3
|
+
#
|
4
|
+
# @param stat [Stat,Hash] A Stat object or Hash of stat properties
|
5
|
+
#
|
6
|
+
# @return [Stat]
|
7
|
+
def self.Stat(stat)
|
8
|
+
case stat
|
9
|
+
when Stat
|
10
|
+
stat
|
11
|
+
else
|
12
|
+
Stat.new(stat)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# A class representing an individual statistic for a specified {#interval_id}
|
17
|
+
#
|
18
|
+
# @!attribute [r] all
|
19
|
+
# @return [Hash] Breakdown of summary stats for all message types
|
20
|
+
# @!attribute [r] inbound
|
21
|
+
# @return [Hash] Breakdown of summary stats for traffic over various transport types for all inbound messages
|
22
|
+
# @!attribute [r] outbound
|
23
|
+
# @return [Hash] Breakdown of summary stats for traffic over various transport types for all outbound messages
|
24
|
+
# @!attribute [r] persisted
|
25
|
+
# @return [Hash] Breakdown of summary stats for all persisted messages
|
26
|
+
# @!attribute [r] connections
|
27
|
+
# @return [Hash] A breakdown of summary stats data for different (TLS vs non-TLS) connection types.
|
28
|
+
# @!attribute [r] channels
|
29
|
+
# @return [Hash] Aggregate data for usage of Channels
|
30
|
+
# @!attribute [r] api_requests
|
31
|
+
# @return [Hash] Aggregate data for numbers of API requests
|
32
|
+
# @!attribute [r] token_requests
|
33
|
+
# @return [Hash] Aggregate data for numbers of Token requests
|
34
|
+
#
|
35
|
+
class Stat
|
36
|
+
include Ably::Modules::ModelCommon
|
37
|
+
extend Ably::Modules::Enum
|
38
|
+
|
39
|
+
GRANULARITY = ruby_enum('GRANULARITY',
|
40
|
+
:minute,
|
41
|
+
:hour,
|
42
|
+
:day,
|
43
|
+
:month
|
44
|
+
)
|
45
|
+
|
46
|
+
INTERVAL_FORMAT_STRING = [
|
47
|
+
'%Y-%m-%d:%H:%M',
|
48
|
+
'%Y-%m-%d:%H',
|
49
|
+
'%Y-%m-%d',
|
50
|
+
'%Y-%m'
|
51
|
+
]
|
52
|
+
|
53
|
+
class << self
|
54
|
+
# Convert a Time with the specified Granularity into an interval ID based on UTC 0 time
|
55
|
+
# @example
|
56
|
+
# Stat.to_interval_id(Time.now, :hour) # => '2015-01-01:10'
|
57
|
+
#
|
58
|
+
# @param time [Time] Time used to determine the interval
|
59
|
+
# @param granularity [GRANULARITY] Granularity of the metrics such as :hour, :day
|
60
|
+
#
|
61
|
+
# @return [String] interval ID used for stats
|
62
|
+
#
|
63
|
+
def to_interval_id(time, granularity)
|
64
|
+
raise ArgumentError, 'Time object required as first argument' unless time.kind_of?(Time)
|
65
|
+
|
66
|
+
granularity = GRANULARITY(granularity)
|
67
|
+
format = INTERVAL_FORMAT_STRING[granularity.to_i]
|
68
|
+
|
69
|
+
time.utc.strftime(format)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the UTC 0 start Time of an interval_id
|
73
|
+
# @example
|
74
|
+
# Stat.from_interval_id('2015-01-01:10') # => 2015-01-01 10:00:00 +0000
|
75
|
+
#
|
76
|
+
# @param interval_id [String]
|
77
|
+
#
|
78
|
+
# @return [Time] start time of the provided interval_id
|
79
|
+
#
|
80
|
+
def from_interval_id(interval_id)
|
81
|
+
raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
|
82
|
+
|
83
|
+
format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
|
84
|
+
raise ArgumentError, 'Interval ID is an invalid length' unless format
|
85
|
+
|
86
|
+
Time.strptime("#{interval_id} +0000", "#{format} %z").utc
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the {GRANULARITY} determined from the interval_id
|
90
|
+
# @example
|
91
|
+
# Stat.granularity_from_interval_id('2015-01-01:10') # => :hour
|
92
|
+
#
|
93
|
+
# @param interval_id [String]
|
94
|
+
#
|
95
|
+
# @return [GRANULARITY] Granularity Enum for the interval_id
|
96
|
+
#
|
97
|
+
def granularity_from_interval_id(interval_id)
|
98
|
+
raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
|
99
|
+
|
100
|
+
format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
|
101
|
+
raise ArgumentError, 'Interval ID is an invalid length' unless format
|
102
|
+
|
103
|
+
GRANULARITY[INTERVAL_FORMAT_STRING.index(format)]
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def expected_length(format)
|
108
|
+
format.gsub('%Y', 'YYYY').length
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# {Stat} initializer
|
113
|
+
#
|
114
|
+
# @param hash_object [Hash] object with the underlying stat details
|
115
|
+
#
|
116
|
+
def initialize(hash_object)
|
117
|
+
@raw_hash_object = hash_object
|
118
|
+
|
119
|
+
set_hash_object hash_object
|
120
|
+
end
|
121
|
+
|
122
|
+
%w( all inbound outbound persisted connections channels api_requests token_requests ).each do |attribute|
|
123
|
+
define_method attribute do
|
124
|
+
hash[attribute.to_sym]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @!attribute [r] interval_id
|
129
|
+
# @return [String] The interval that this statistic applies to, see {GRANULARITY} and {INTERVAL_FORMAT_STRING}
|
130
|
+
def interval_id
|
131
|
+
hash.fetch(:interval_id)
|
132
|
+
end
|
133
|
+
|
134
|
+
# @!attribute [r] interval_time
|
135
|
+
# @return [Time] A Time object representing the start of the interval
|
136
|
+
def interval_time
|
137
|
+
self.class.from_interval_id(interval_id)
|
138
|
+
end
|
139
|
+
|
140
|
+
# @!attribute [r] interval_granularity
|
141
|
+
# @return [GRANULARITY] The granularity of the interval for the stat such as :day, :hour, :minute, see {GRANULARITY}
|
142
|
+
def interval_granularity
|
143
|
+
self.class.granularity_from_interval_id(interval_id)
|
144
|
+
end
|
145
|
+
|
146
|
+
def hash
|
147
|
+
@hash_object
|
148
|
+
end
|
149
|
+
|
150
|
+
def as_json(*args)
|
151
|
+
hash.as_json(*args)
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
attr_reader :raw_hash_object
|
156
|
+
|
157
|
+
def set_hash_object(hash)
|
158
|
+
@hash_object = IdiomaticRubyWrapper(hash.clone.freeze)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|