ably-rest 1.1.7 → 1.1.8
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/lib/submodules/ably-ruby/CHANGELOG.md +59 -0
- data/lib/submodules/ably-ruby/COPYRIGHT +1 -1
- data/lib/submodules/ably-ruby/SPEC.md +0 -7
- data/lib/submodules/ably-ruby/ably.gemspec +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +8 -2
- data/lib/submodules/ably-ruby/lib/ably/models/delta_extras.rb +29 -0
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +6 -2
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +11 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +5 -8
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +5 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +13 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +0 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +16 -4
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +212 -7
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +56 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +249 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +18 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +73 -11
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/delta_extras_spec.rb +14 -0
- data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +17 -1
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +24 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +24 -20
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +2 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +3 -3
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +40 -7
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +27 -0
- metadata +4 -2
@@ -750,6 +750,107 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
750
750
|
end
|
751
751
|
end
|
752
752
|
|
753
|
+
describe '#(RTL17)' do
|
754
|
+
context 'when channel is initialized' do
|
755
|
+
it 'sends messages only on attach' do
|
756
|
+
expect(channel).to be_initialized
|
757
|
+
channel.publish('event', payload)
|
758
|
+
|
759
|
+
channel.subscribe do |message|
|
760
|
+
stop_reactor if message.data == payload && channel.attached?
|
761
|
+
end
|
762
|
+
|
763
|
+
channel.attach
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
context 'when channel is attaching' do
|
768
|
+
it 'sends messages only on attach' do
|
769
|
+
channel.publish('event', payload)
|
770
|
+
|
771
|
+
sent_message = nil
|
772
|
+
channel.subscribe do |message|
|
773
|
+
return if message.data != payload
|
774
|
+
sent_message = message
|
775
|
+
|
776
|
+
stop_reactor if channel.attached?
|
777
|
+
end
|
778
|
+
|
779
|
+
channel.on(:attaching) do
|
780
|
+
expect(channel).to be_attaching
|
781
|
+
expect(sent_message).to be_nil
|
782
|
+
end
|
783
|
+
|
784
|
+
channel.attach
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
context 'when channel is detaching' do
|
789
|
+
it 'stops sending message' do
|
790
|
+
sent_message = nil
|
791
|
+
event_published = false
|
792
|
+
channel.subscribe do |message|
|
793
|
+
sent_message = message if message.data == payload
|
794
|
+
end
|
795
|
+
|
796
|
+
channel.on(:detaching) do
|
797
|
+
channel.publish('event', payload)
|
798
|
+
event_published = true
|
799
|
+
end
|
800
|
+
|
801
|
+
channel.on(:detaching) do
|
802
|
+
EventMachine.next_tick do
|
803
|
+
expect(sent_message).to be_nil
|
804
|
+
stop_reactor if event_published
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
channel.attach do
|
809
|
+
channel.detach
|
810
|
+
end
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
context 'when channel is detached' do
|
815
|
+
it 'stops sending message' do
|
816
|
+
sent_message = nil
|
817
|
+
event_published = false
|
818
|
+
channel.subscribe do |message|
|
819
|
+
sent_message = message if message.data == payload
|
820
|
+
end
|
821
|
+
|
822
|
+
channel.on(:detaching) do
|
823
|
+
channel.publish('event', payload)
|
824
|
+
event_published = true
|
825
|
+
end
|
826
|
+
|
827
|
+
channel.on(:detached) do
|
828
|
+
expect(sent_message).to be_nil
|
829
|
+
stop_reactor if event_published
|
830
|
+
end
|
831
|
+
|
832
|
+
channel.attach do
|
833
|
+
channel.detach
|
834
|
+
end
|
835
|
+
end
|
836
|
+
end
|
837
|
+
|
838
|
+
context 'when channel is failed' do
|
839
|
+
it 'errors when trying to send a message' do
|
840
|
+
channel.once(:failed) do
|
841
|
+
channel.publish('event', payload).errback do |error|
|
842
|
+
expect(error).to be_a(Ably::Exceptions::ChannelInactive)
|
843
|
+
stop_reactor
|
844
|
+
end
|
845
|
+
end
|
846
|
+
|
847
|
+
channel.attach do
|
848
|
+
channel.transition_state_machine(:failed)
|
849
|
+
end
|
850
|
+
end
|
851
|
+
end
|
852
|
+
end
|
853
|
+
|
753
854
|
context 'when channel is not attached in state Initializing (#RTL6c1)' do
|
754
855
|
it 'publishes messages immediately and does not implicitly attach (#RTL6c1)' do
|
755
856
|
sub_channel.attach do
|
@@ -1181,7 +1282,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1181
1282
|
end
|
1182
1283
|
|
1183
1284
|
context 'with more than allowed messages in a single publish' do
|
1184
|
-
|
1285
|
+
65536
|
1185
1286
|
|
1186
1287
|
it 'rejects the publish' do
|
1187
1288
|
messages = (Ably::Realtime::Connection::MAX_PROTOCOL_MESSAGE_BATCH_SIZE + 1).times.map do
|
@@ -1405,15 +1506,98 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1405
1506
|
end
|
1406
1507
|
|
1407
1508
|
context 'message size exceeded (#TO3l8)' do
|
1408
|
-
let(:message) { 'x' * 700000 }
|
1409
|
-
|
1410
1509
|
let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
|
1411
1510
|
let(:channel) { client.channels.get(channel_name) }
|
1412
1511
|
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1512
|
+
context 'and max_message_size is default (65536 bytes)' do
|
1513
|
+
let(:channel_name) { random_str }
|
1514
|
+
let(:max_message_size) { 65536 }
|
1515
|
+
|
1516
|
+
it 'should allow to send a message (32 bytes)' do
|
1517
|
+
client.connection.once(:connected) do
|
1518
|
+
channel.subscribe('event') do |msg|
|
1519
|
+
expect(msg.data).to eq('x' * 32)
|
1520
|
+
stop_reactor
|
1521
|
+
end
|
1522
|
+
channel.publish('event', 'x' * 32)
|
1523
|
+
end
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
it 'should not allow to send a message (700000 bytes)' do
|
1527
|
+
client.connection.once(:connected) do
|
1528
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1529
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1530
|
+
)
|
1531
|
+
client.connection.set_connection_details(connection_details)
|
1532
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1533
|
+
channel.publish('event', 'x' * 700000).errback do |error|
|
1534
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1535
|
+
stop_reactor
|
1536
|
+
end
|
1537
|
+
end
|
1538
|
+
end
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
context 'and max_message_size is customized (11 bytes)' do
|
1542
|
+
let(:max_message_size) { 11 }
|
1543
|
+
|
1544
|
+
context 'and the message size is 30 bytes' do
|
1545
|
+
let(:channel_name) { random_str }
|
1546
|
+
|
1547
|
+
it 'should not allow to send a message' do
|
1548
|
+
client.connection.once(:connected) do
|
1549
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1550
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1551
|
+
)
|
1552
|
+
client.connection.set_connection_details(connection_details)
|
1553
|
+
expect(client.connection.details.max_message_size).to eq(11)
|
1554
|
+
channel.publish('event', 'x' * 30).errback do |error|
|
1555
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1556
|
+
stop_reactor
|
1557
|
+
end
|
1558
|
+
end
|
1559
|
+
end
|
1560
|
+
end
|
1561
|
+
end
|
1562
|
+
|
1563
|
+
context 'and max_message_size is nil' do
|
1564
|
+
let(:max_message_size) { nil }
|
1565
|
+
|
1566
|
+
context 'and the message size is 30 bytes' do
|
1567
|
+
let(:channel_name) { random_str }
|
1568
|
+
|
1569
|
+
it 'should allow to send a message' do
|
1570
|
+
client.connection.once(:connected) do
|
1571
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1572
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1573
|
+
)
|
1574
|
+
client.connection.set_connection_details(connection_details)
|
1575
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1576
|
+
channel.subscribe('event') do |msg|
|
1577
|
+
expect(msg.data).to eq('x' * 30)
|
1578
|
+
stop_reactor
|
1579
|
+
end
|
1580
|
+
channel.publish('event', 'x' * 30)
|
1581
|
+
end
|
1582
|
+
end
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
context 'and the message size is 65537 bytes' do
|
1586
|
+
let(:channel_name) { random_str }
|
1587
|
+
|
1588
|
+
it 'should not allow to send a message' do
|
1589
|
+
client.connection.once(:connected) do
|
1590
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1591
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1592
|
+
)
|
1593
|
+
client.connection.set_connection_details(connection_details)
|
1594
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1595
|
+
channel.publish('event', 'x' * 65537).errback do |error|
|
1596
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1597
|
+
stop_reactor
|
1598
|
+
end
|
1599
|
+
end
|
1600
|
+
end
|
1417
1601
|
end
|
1418
1602
|
end
|
1419
1603
|
end
|
@@ -2224,6 +2408,27 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2224
2408
|
channel.transition_state_machine! :suspended
|
2225
2409
|
end
|
2226
2410
|
end
|
2411
|
+
|
2412
|
+
context 'when connection is no longer connected' do
|
2413
|
+
it 'will not attempt to reattach (#RTL13c)' do
|
2414
|
+
channel.attach do
|
2415
|
+
connection.once(:closing) do
|
2416
|
+
channel.once(:attaching) do |state_change|
|
2417
|
+
raise 'Channel should not attempt to reattach'
|
2418
|
+
end
|
2419
|
+
|
2420
|
+
channel.transition_state_machine! :suspended
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
connection.once(:closed) do
|
2424
|
+
expect(channel).to be_suspended
|
2425
|
+
stop_reactor
|
2426
|
+
end
|
2427
|
+
|
2428
|
+
connection.close
|
2429
|
+
end
|
2430
|
+
end
|
2431
|
+
end
|
2227
2432
|
end
|
2228
2433
|
|
2229
2434
|
context 'and channel is attaching' do
|
@@ -570,7 +570,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
570
570
|
end
|
571
571
|
|
572
572
|
context 'when DISCONNECTED ProtocolMessage received from the server' do
|
573
|
-
it 'reconnects automatically and immediately' do
|
573
|
+
it 'reconnects automatically and immediately (#RTN15a)' do
|
574
574
|
fail_if_suspended_or_failed
|
575
575
|
|
576
576
|
connection.once(:connected) do
|
@@ -590,6 +590,61 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
590
590
|
end
|
591
591
|
end
|
592
592
|
|
593
|
+
context 'when protocolMessage contains token error' do
|
594
|
+
context "library does not have a means to renew the token (#RTN15h1)" do
|
595
|
+
let(:auth_url) { 'https://echo.ably.io/createJWT' }
|
596
|
+
let(:token) { Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}").body }
|
597
|
+
let(:client_options) { default_options.merge(token: token, log_level: :none) }
|
598
|
+
|
599
|
+
let(:error_message) { 'error_message' }
|
600
|
+
|
601
|
+
it 'moves connection state to failed' do
|
602
|
+
connection.on(:failed) do |connection_state_change|
|
603
|
+
expect(connection.error_reason.message).to eq(error_message)
|
604
|
+
stop_reactor
|
605
|
+
end
|
606
|
+
|
607
|
+
connection.on(:connected) do
|
608
|
+
protocol_message = Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Disconnected.to_i, error: { code: 40140, message: error_message })
|
609
|
+
connection.__incoming_protocol_msgbus__.publish :protocol_message, protocol_message
|
610
|
+
end
|
611
|
+
|
612
|
+
connection.connect
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context "library have a means to renew the token (#RTN15h2)" do
|
617
|
+
let(:client_options) { default_options.merge(log_level: :none) }
|
618
|
+
let(:error_message) { 'error_message' }
|
619
|
+
|
620
|
+
def send_disconnect_message
|
621
|
+
protocol_message = Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Disconnected.to_i, error: { code: 40140, message: error_message })
|
622
|
+
connection.__incoming_protocol_msgbus__.publish :protocol_message, protocol_message
|
623
|
+
end
|
624
|
+
|
625
|
+
it 'attempts to reconnect' do
|
626
|
+
connection.on(:failed) do |connection_state_change|
|
627
|
+
raise "Connection shouldn't be failed"
|
628
|
+
end
|
629
|
+
|
630
|
+
connection.on(:connected) do
|
631
|
+
connection.once(:connecting) do
|
632
|
+
connection.once(:disconnected) do
|
633
|
+
expect(connection.error_reason.message).to eq(error_message)
|
634
|
+
stop_reactor
|
635
|
+
end
|
636
|
+
|
637
|
+
send_disconnect_message
|
638
|
+
end
|
639
|
+
|
640
|
+
send_disconnect_message
|
641
|
+
end
|
642
|
+
|
643
|
+
connection.connect
|
644
|
+
end
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
593
648
|
context 'connection state freshness is monitored' do
|
594
649
|
it 'resumes connections when disconnected within the connection_state_ttl period (#RTN15g)' do
|
595
650
|
connection.once(:connected) do
|
@@ -482,6 +482,118 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
482
482
|
end
|
483
483
|
end
|
484
484
|
|
485
|
+
context 'when explicitly reconnecting disconnected/suspended connection in retry (#RTN11c)' do
|
486
|
+
let(:close_connection_proc) do
|
487
|
+
lambda do
|
488
|
+
EventMachine.add_timer(0.001) do
|
489
|
+
if connection.transport.nil?
|
490
|
+
close_connection_proc.call
|
491
|
+
else
|
492
|
+
connection.transport.close_connection_after_writing
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
context 'when suspended' do
|
499
|
+
let(:suspended_retry_timeout) { 60 }
|
500
|
+
let(:client_options) do
|
501
|
+
default_options.merge(
|
502
|
+
disconnected_retry_timeout: 0.02,
|
503
|
+
suspended_retry_timeout: suspended_retry_timeout,
|
504
|
+
connection_state_ttl: 0
|
505
|
+
)
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'reconnects immediately' do
|
509
|
+
connection.once(:connecting) { close_connection_proc.call }
|
510
|
+
|
511
|
+
connection.on(:suspended) do |connection_state_change|
|
512
|
+
if connection_state_change.retry_in.zero?
|
513
|
+
# Exhausting immediate retries
|
514
|
+
connection.once(:connecting) { close_connection_proc.call }
|
515
|
+
else
|
516
|
+
suspended_at = Time.now.to_f
|
517
|
+
connection.on(:connected) do
|
518
|
+
expect(connection_state_change.retry_in).to eq(suspended_retry_timeout)
|
519
|
+
expect(connection.state).to eq(:connected)
|
520
|
+
expect(Time.now.to_f).to be_within(4).of(suspended_at)
|
521
|
+
stop_reactor
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
connection.connect
|
526
|
+
end
|
527
|
+
|
528
|
+
connection.connect
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
context 'when disconnected' do
|
533
|
+
let(:retry_timeout) { 60 }
|
534
|
+
let(:client_options) do
|
535
|
+
default_options.merge(
|
536
|
+
disconnected_retry_timeout: retry_timeout,
|
537
|
+
suspended_retry_timeout: retry_timeout,
|
538
|
+
connection_state_ttl: 0
|
539
|
+
)
|
540
|
+
end
|
541
|
+
|
542
|
+
it 'reconnects immediately' do
|
543
|
+
connection.once(:connected) do
|
544
|
+
connection.on(:disconnected) do |connection_state_change|
|
545
|
+
disconnected_at = Time.now.to_f
|
546
|
+
connection.on(:connected) do
|
547
|
+
if connection_state_change.retry_in.zero?
|
548
|
+
# Exhausting immediate retries
|
549
|
+
close_connection_proc.call
|
550
|
+
else
|
551
|
+
expect(connection_state_change.retry_in).to eq(retry_timeout)
|
552
|
+
expect(connection.state).to eq(:connected)
|
553
|
+
expect(Time.now.to_f).to be_within(4).of(disconnected_at)
|
554
|
+
stop_reactor
|
555
|
+
end
|
556
|
+
end
|
557
|
+
connection.connect
|
558
|
+
end
|
559
|
+
|
560
|
+
close_connection_proc.call
|
561
|
+
end
|
562
|
+
|
563
|
+
connection.connect
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
context 'when reconnecting a failed connection' do
|
569
|
+
let(:channel) { client.channel(random_str) }
|
570
|
+
let(:client_options) { default_options.merge(log_level: :none) }
|
571
|
+
|
572
|
+
it 'transitions all channels state to initialized and cleares error_reason' do
|
573
|
+
connection.on(:failed) do |connection_state_change|
|
574
|
+
expect(connection.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
|
575
|
+
expect(channel.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
|
576
|
+
expect(channel).to be_failed
|
577
|
+
|
578
|
+
connection.on(:connected) do
|
579
|
+
expect(connection.error_reason).to eq(nil)
|
580
|
+
expect(channel).to be_initialized
|
581
|
+
expect(channel.error_reason).to eq(nil)
|
582
|
+
stop_reactor
|
583
|
+
end
|
584
|
+
|
585
|
+
connection.connect
|
586
|
+
end
|
587
|
+
|
588
|
+
connection.connect do
|
589
|
+
channel.attach do
|
590
|
+
error = Ably::Exceptions::ConnectionFailed.new('forced failure', 500, 50000)
|
591
|
+
client.connection.manager.error_received_from_server error
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
485
597
|
context 'with invalid auth details' do
|
486
598
|
let(:client_options) { default_options.merge(key: 'this.is:invalid', log_level: :none) }
|
487
599
|
|
@@ -693,6 +805,18 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
693
805
|
end
|
694
806
|
|
695
807
|
context '#close' do
|
808
|
+
let(:close_connection_proc) do
|
809
|
+
lambda do
|
810
|
+
EventMachine.add_timer(0.001) do
|
811
|
+
if connection.transport.nil?
|
812
|
+
close_connection_proc.call
|
813
|
+
else
|
814
|
+
connection.transport.close_connection_after_writing
|
815
|
+
end
|
816
|
+
end
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
696
820
|
it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
|
697
821
|
connection.connect do
|
698
822
|
expect(connection.close).to be_a(Ably::Util::SafeDeferrable)
|
@@ -754,6 +878,56 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
754
878
|
end
|
755
879
|
end
|
756
880
|
|
881
|
+
context ':connecting RTN12f' do
|
882
|
+
context ":connected does not arrive when trying to close" do
|
883
|
+
it 'moves to closed' do
|
884
|
+
connection.on(:closed) do |state_change|
|
885
|
+
state_changes = connection.state_history.map { |t| t[:state].to_sym }
|
886
|
+
|
887
|
+
expect(state_changes).to eq([:connecting, :closing, :closed])
|
888
|
+
stop_reactor
|
889
|
+
end
|
890
|
+
|
891
|
+
connection.on(:connecting) do
|
892
|
+
connection.close
|
893
|
+
connection.__outgoing_protocol_msgbus__.unsubscribe
|
894
|
+
end
|
895
|
+
|
896
|
+
connection.connect
|
897
|
+
end
|
898
|
+
end
|
899
|
+
|
900
|
+
context ":connected arrive when trying to close" do
|
901
|
+
let(:protocol_message_attributes) do
|
902
|
+
{
|
903
|
+
action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
|
904
|
+
connection_serial: 55,
|
905
|
+
connection_details: {
|
906
|
+
max_idle_interval: 2 * 1000
|
907
|
+
}
|
908
|
+
}
|
909
|
+
end
|
910
|
+
|
911
|
+
it 'moves to connected and then to closed' do
|
912
|
+
connection.on(:closed) do |state_change|
|
913
|
+
state_changes = connection.state_history.map { |t| t[:state].to_sym }
|
914
|
+
|
915
|
+
expect(state_changes).to eq([:connecting, :connected, :closing, :closed])
|
916
|
+
stop_reactor
|
917
|
+
end
|
918
|
+
|
919
|
+
connection.on(:connecting) do
|
920
|
+
connection.__outgoing_protocol_msgbus__.unsubscribe
|
921
|
+
|
922
|
+
connection.__incoming_protocol_msgbus__.publish :protocol_message, Ably::Models::ProtocolMessage.new(protocol_message_attributes)
|
923
|
+
connection.close
|
924
|
+
end
|
925
|
+
|
926
|
+
connection.connect
|
927
|
+
end
|
928
|
+
end
|
929
|
+
end
|
930
|
+
|
757
931
|
context ':connected' do
|
758
932
|
it 'changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage' do
|
759
933
|
connection.on(:connected) do
|
@@ -800,6 +974,81 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
800
974
|
end
|
801
975
|
end
|
802
976
|
end
|
977
|
+
|
978
|
+
context ':suspended RTN12d' do
|
979
|
+
let(:suspended_retry_timeout) { 60 }
|
980
|
+
let(:client_options) do
|
981
|
+
default_options.merge(
|
982
|
+
disconnected_retry_timeout: 0.02,
|
983
|
+
suspended_retry_timeout: suspended_retry_timeout,
|
984
|
+
connection_state_ttl: 0
|
985
|
+
)
|
986
|
+
end
|
987
|
+
|
988
|
+
it 'immediatly closes connection' do
|
989
|
+
connection.on(:connecting) { close_connection_proc.call }
|
990
|
+
connection.on(:suspended) do |connection_state_change|
|
991
|
+
if connection_state_change.retry_in.zero?
|
992
|
+
# Exhausting immediate retries
|
993
|
+
connection.once(:connecting) { close_connection_proc.call }
|
994
|
+
else
|
995
|
+
suspended_at = Time.now.to_f
|
996
|
+
connection.on(:closed) do
|
997
|
+
expect(connection_state_change.retry_in).to eq(suspended_retry_timeout)
|
998
|
+
expect(connection.state).to eq(:closed)
|
999
|
+
expect(Time.now.to_f).to be_within(4).of(suspended_at)
|
1000
|
+
stop_reactor
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
connection.close
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
connection.connect
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
connection.connect
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
context ':disconnected RTN12d' do
|
1014
|
+
let(:retry_timeout) { 60 }
|
1015
|
+
let(:client_options) do
|
1016
|
+
default_options.merge(
|
1017
|
+
disconnected_retry_timeout: retry_timeout,
|
1018
|
+
suspended_retry_timeout: retry_timeout,
|
1019
|
+
connection_state_ttl: 0
|
1020
|
+
)
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
it 'immediatly closes connection' do
|
1024
|
+
connection.once(:connected) do
|
1025
|
+
connection.on(:disconnected) do |connection_state_change|
|
1026
|
+
disconnected_at = Time.now.to_f
|
1027
|
+
connection.on(:connected) do
|
1028
|
+
if connection_state_change.retry_in.zero?
|
1029
|
+
# Exhausting immediate retries
|
1030
|
+
close_connection_proc.call
|
1031
|
+
else
|
1032
|
+
connection.once(:closed) do
|
1033
|
+
expect(connection_state_change.retry_in).to eq(retry_timeout)
|
1034
|
+
expect(connection.state).to eq(:closed)
|
1035
|
+
expect(Time.now.to_f).to be_within(4).of(disconnected_at)
|
1036
|
+
stop_reactor
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
connection.close
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
connection.connect
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
close_connection_proc.call
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
connection.connect
|
1050
|
+
end
|
1051
|
+
end
|
803
1052
|
end
|
804
1053
|
end
|
805
1054
|
|
@@ -2634,7 +2634,24 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2634
2634
|
end
|
2635
2635
|
end
|
2636
2636
|
|
2637
|
-
context 'channel state side effects' do
|
2637
|
+
context 'channel state side effects (RTP5)' do
|
2638
|
+
context 'channel transitions to the ATTACHED state (RTP5b)' do
|
2639
|
+
it 'all queued presence messages are sent' do
|
2640
|
+
channel_client_one.on(:attached) do
|
2641
|
+
client_one.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2642
|
+
if protocol_message.action == :presence
|
2643
|
+
expect(protocol_message.action).to eq(:presence)
|
2644
|
+
stop_reactor
|
2645
|
+
end
|
2646
|
+
end
|
2647
|
+
end
|
2648
|
+
|
2649
|
+
presence_client_one.enter do
|
2650
|
+
channel_client_one.attach
|
2651
|
+
end
|
2652
|
+
end
|
2653
|
+
end
|
2654
|
+
|
2638
2655
|
context 'channel transitions to the FAILED state' do
|
2639
2656
|
let(:anonymous_client) { auto_close Ably::Realtime::Client.new(client_options.merge(log_level: :fatal)) }
|
2640
2657
|
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(client_id: client_one_id, log_level: :fatal)) }
|