wamp_client 0.0.5 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87be6cf98c5f02b19c59566bd0dca4c740bc72ea
4
- data.tar.gz: 027fdc23b28f45c66f527716fe5836e8cd0aa093
3
+ metadata.gz: 38ed148dd65f5a524eef4a6f6d6adaf6d832b2e4
4
+ data.tar.gz: 6987c5eea6218af8562546b159a1355a8fc9493f
5
5
  SHA512:
6
- metadata.gz: 684135ebcb5a497b45d40f526dcd94dc59ac5f4c914681c6a6c790f1d375ee1b52aaf8b63159b95b665cce4db1982c6206eff88ac3d08abee651cd2dad4182ee
7
- data.tar.gz: de64371b6db6b9deaad66af0296d413b160848508fe36fb8fb70cd8288138d5f7693cd3fcb4022e4ff1aa15964a0ecec06e88042c99b09f3366345aa6289a276
6
+ metadata.gz: 7576c79cf402f373b7126c97e7af3c70c9b62217c27afe4c7fe0ab25359eb0fa489945bec2e9c6c5b972f4dc4b665d8829e7f60d0707b5540e3506e3ad4ae16e
7
+ data.tar.gz: 771b11d86f4a5efa8aa13af794b07b031d656ea43f58315b01b5a50fe945495944a4ecb95ff595b690870a7a058956b3abb4412ecae1bceb9ad7f3c1165c2f7e
data/README.md CHANGED
@@ -4,12 +4,13 @@
4
4
  [![Circle CI](https://circleci.com/gh/ericchapman/ruby_wamp_client/tree/master.svg?&style=shield&circle-token=92813c17f9c9510c4c644e41683e7ba2572e0b2a)](https://circleci.com/gh/ericchapman/ruby_wamp_client/tree/master)
5
5
  [![Codecov](https://img.shields.io/codecov/c/github/ericchapman/ruby_wamp_client/master.svg)](https://codecov.io/github/ericchapman/ruby_wamp_client)
6
6
 
7
- Client for talking to a WAMP Router. This is defined at
8
-
9
- https://tools.ietf.org/html/draft-oberstet-hybi-tavendo-wamp-02
7
+ Client for talking to a WAMP Router. This is defined [here](https://tools.ietf.org/html/draft-oberstet-hybi-tavendo-wamp-02)
10
8
 
11
9
  ## Revision History
12
10
 
11
+ - v0.0.6:
12
+ - Added call cancelling
13
+ - Added call timeout
13
14
  - v0.0.5:
14
15
  - Fixed issue where excluding the 'authmethods' and 'authid' was setting their values to none rather
15
16
  than excluding them. This was being rejected by some routers
@@ -439,6 +440,7 @@ Options are
439
440
 
440
441
  - receive_progress [Boolean] - "true" if you support results being able to be sent progressively
441
442
  - disclose_me [Boolean] - "true" if the caller would like the callee to know the identity
443
+ - timeout [Integer] - specifies the number of milliseconds the caller should wait before cancelling the call
442
444
 
443
445
  #### Errors
444
446
  Errors can either be raised OR returned as shown below
@@ -518,6 +520,72 @@ end
518
520
  session.register('com.example.procedure', method(:add))
519
521
  ```
520
522
 
523
+ #### Cancelled Call
524
+ A cancelled call will tell a callee who implements a progressive call to cancel it
525
+
526
+ **Caller**
527
+
528
+ ```ruby
529
+ call = session.call('com.example.procedure', [15], {param: value}, {}) do |result, error, details|
530
+ # TODO: Do something
531
+ args = result.args
532
+ kwargs = result.kwargs
533
+ end
534
+
535
+ # At some later time...
536
+
537
+ session.cancel(call, 'skip') # Options are 'skip', 'kill', or 'killnowait'
538
+
539
+ # or ...
540
+
541
+ call.cancel('skip')
542
+ ```
543
+
544
+ **Callee**
545
+
546
+ (There is probably a better way to do this. This is a bad example)
547
+
548
+ ```ruby
549
+ @interrupts = {}
550
+
551
+ def interrupt_handler(request, mode)
552
+ @interrups[request] = mode
553
+
554
+ # To trigger a custom error, either return something or raise a "CallError"
555
+ # else the library will raise a standard error for you
556
+ end
557
+
558
+ def add(args, kwargs, details)
559
+ defer = WampClient::Defer::ProgressiveCallDefer.new
560
+ EM.add_timer(2) { # Something Async
561
+ if @interrupts[defer.request].nil?
562
+ defer.progress(WampClient::CallResult.new([1,2,3]))
563
+ end
564
+ }
565
+ EM.add_timer(4) { # Something Async
566
+ if @interrupts[defer.request].nil?
567
+ defer.progress(WampClient::CallResult.new([4,5,6]))
568
+ end
569
+ }
570
+ EM.add_timer(6) { # Something Async
571
+ if @interrupts[defer.request].nil?
572
+ defer.succeed(WampClient::CallResult.new)
573
+ end
574
+ @interrupts.delete(request)
575
+ }
576
+ defer
577
+ end
578
+
579
+ session.register('com.example.procedure', method(:add), nil, method(:interrupt_handler))
580
+ ```
581
+
582
+ Notes:
583
+
584
+ - Once the response is cancelled, subsequent succeed, progress, or errors are ignored
585
+ and not sent to the caller
586
+ - Cancels are only processed by calls that had defers. If the defer does not exist then
587
+ the cancel is ignored
588
+
521
589
  ## Contributing
522
590
 
523
591
  1. Fork it ( https://github.com/ericchapman/ruby_wamp_client )
@@ -526,11 +594,6 @@ session.register('com.example.procedure', method(:add))
526
594
  4. Push to the branch (`git push origin my-new-feature`)
527
595
  5. Create a new Pull Request
528
596
 
529
- ### TODOs
530
-
531
- - call_timeout
532
- - call_canceling
533
-
534
597
  ### Testing
535
598
 
536
599
  The unit tests are run as follows
@@ -29,7 +29,7 @@ module WampClient
29
29
  module Defer
30
30
 
31
31
  class CallDefer
32
- attr_accessor :request
32
+ attr_accessor :request, :registration
33
33
 
34
34
  @on_complete
35
35
  def on_complete(&on_complete)
@@ -36,8 +36,8 @@ module WampClient
36
36
  caller: {
37
37
  features: {
38
38
  caller_identification: true,
39
- ##call_timeout: true,
40
- ##call_canceling: true,
39
+ call_timeout: true,
40
+ call_canceling: true,
41
41
  progressive_call_results: true
42
42
  }
43
43
  },
@@ -48,7 +48,7 @@ module WampClient
48
48
  pattern_based_registration: true,
49
49
  shared_registration: true,
50
50
  ##call_timeout: true,
51
- ##call_canceling: true,
51
+ call_canceling: true,
52
52
  progressive_call_results: true,
53
53
  registration_revocation: true
54
54
  }
@@ -108,12 +108,13 @@ module WampClient
108
108
  end
109
109
 
110
110
  class Registration
111
- attr_accessor :procedure, :handler, :options, :session, :id
111
+ attr_accessor :procedure, :handler, :i_handler, :options, :session, :id
112
112
 
113
- def initialize(procedure, handler, options, session, id)
113
+ def initialize(procedure, handler, options, i_handler, session, id)
114
114
  self.procedure = procedure
115
115
  self.handler = handler
116
116
  self.options = options
117
+ self.i_handler = i_handler
117
118
  self.session = session
118
119
  self.id = id
119
120
  end
@@ -124,6 +125,19 @@ module WampClient
124
125
 
125
126
  end
126
127
 
128
+ class Call
129
+ attr_accessor :session, :id
130
+
131
+ def initialize(session, id)
132
+ self.session = session
133
+ self.id = id
134
+ end
135
+
136
+ def cancel(mode='skip')
137
+ self.session.cancel(self, mode)
138
+ end
139
+
140
+ end
127
141
 
128
142
  class Session
129
143
  include WampClient::Check
@@ -360,6 +374,8 @@ module WampClient
360
374
  self._process_UNREGISTERED(message)
361
375
  elsif message.is_a? WampClient::Message::Invocation
362
376
  self._process_INVOCATION(message)
377
+ elsif message.is_a? WampClient::Message::Interrupt
378
+ self._process_INTERRUPT(message)
363
379
  elsif message.is_a? WampClient::Message::Result
364
380
  self._process_RESULT(message)
365
381
  else
@@ -587,21 +603,23 @@ module WampClient
587
603
 
588
604
  # Register to a procedure
589
605
  # @param procedure [String] The procedure to register for
590
- # @param handler [lambda] The handler(args, kwargs, details) when a invocation is received
591
- # @param options [Hash] The options for the registration
606
+ # @param handler [lambda] The handler(args, kwargs, details) when an invocation is received
607
+ # @param options [Hash, nil] The options for the registration
608
+ # @param interrupt [lambda] The handler(request, mode) when an interrupt is received
592
609
  # @param callback [block] The callback(registration, error, details) called to signal if the registration was a success or not
593
- def register(procedure, handler, options={}, &callback)
610
+ def register(procedure, handler, options=nil, interrupt=nil, &callback)
594
611
  unless is_open?
595
612
  raise RuntimeError, "Session must be open to call 'register'"
596
613
  end
597
614
 
615
+ options ||= {}
616
+
598
617
  self.class.check_uri('procedure', procedure)
599
- self.class.check_dict('options', options)
600
618
  self.class.check_nil('handler', handler, false)
601
619
 
602
620
  # Create a new registration request
603
621
  request = self._generate_id
604
- self._requests[:register][request] = {p: procedure, h: handler, o: options, c: callback}
622
+ self._requests[:register][request] = {p: procedure, h: handler, i: interrupt, o: options, c: callback}
605
623
 
606
624
  # Send the message
607
625
  register = WampClient::Message::Register.new(request, options, procedure)
@@ -615,7 +633,7 @@ module WampClient
615
633
  # Remove the pending subscription, add it to the registered ones, and inform the caller
616
634
  r = self._requests[:register].delete(msg.register_request)
617
635
  if r
618
- n_r = Registration.new(r[:p], r[:h], r[:o], self, msg.registration)
636
+ n_r = Registration.new(r[:p], r[:h], r[:o], r[:i], self, msg.registration)
619
637
  self._registrations[msg.registration] = n_r
620
638
 
621
639
  details = {}
@@ -646,6 +664,49 @@ module WampClient
646
664
 
647
665
  end
648
666
 
667
+ # Sends an error back to the caller
668
+ # @param request[Integer] - The request ID
669
+ # @param error
670
+ def _send_INVOCATION_error(request, error, check_defer=false)
671
+ # Prevent responses for defers that have already completed or had an error
672
+ if check_defer and not self._defers[request]
673
+ return
674
+ end
675
+
676
+ if error.nil?
677
+ error = CallError.new('wamp.error.runtime')
678
+ elsif not error.is_a?(CallError)
679
+ error = CallError.new('wamp.error.runtime', [error.to_s])
680
+ end
681
+
682
+ error_msg = WampClient::Message::Error.new(WampClient::Message::Types::INVOCATION, request, {}, error.error, error.args, error.kwargs)
683
+ self._send_message(error_msg)
684
+ end
685
+
686
+ # Sends a result for the invocation
687
+ def _send_INVOCATION_result(request, result, options={}, check_defer=false)
688
+ # Prevent responses for defers that have already completed or had an error
689
+ if check_defer and not self._defers[request]
690
+ return
691
+ end
692
+
693
+ if result.nil?
694
+ result = CallResult.new
695
+ elsif result.is_a?(CallError)
696
+ # Do nothing
697
+ elsif not result.is_a?(CallResult)
698
+ result = CallResult.new([result])
699
+ end
700
+
701
+ if result.is_a?(CallError)
702
+ self._send_INVOCATION_error(request, result)
703
+ else
704
+ yield_msg = WampClient::Message::Yield.new(request, options, result.args, result.kwargs)
705
+ self._send_message(yield_msg)
706
+ end
707
+ end
708
+
709
+
649
710
  # Processes and event from the broker
650
711
  # @param msg [WampClient::Message::Invocation] An procedure that was called
651
712
  def _process_INVOCATION(msg)
@@ -664,73 +725,80 @@ module WampClient
664
725
  begin
665
726
  value = h.call(args, kwargs, details)
666
727
 
667
- def send_error(request, error)
668
- if error.nil?
669
- error = CallError.new('wamp.error.runtime')
670
- elsif not error.is_a?(CallError)
671
- error = CallError.new('wamp.error.runtime', [error.to_s])
672
- end
673
-
674
- error_msg = WampClient::Message::Error.new(WampClient::Message::Types::INVOCATION, request, {}, error.error, error.args, error.kwargs)
675
- self._send_message(error_msg)
676
- end
677
-
678
- def send_result(request, result, options={})
679
- if result.nil?
680
- result = CallResult.new
681
- elsif result.is_a?(CallError)
682
- # Do nothing
683
- elsif not result.is_a?(CallResult)
684
- result = CallResult.new([result])
685
- end
686
-
687
- if result.is_a?(CallError)
688
- send_error(request, result)
689
- else
690
- yield_msg = WampClient::Message::Yield.new(request, options, result.args, result.kwargs)
691
- self._send_message(yield_msg)
692
- end
693
- end
694
-
695
728
  # If a defer was returned, handle accordingly
696
729
  if value.is_a? WampClient::Defer::CallDefer
697
730
  value.request = request
731
+ value.registration = msg.registered_registration
698
732
 
699
733
  # Store the defer
700
734
  self._defers[request] = value
701
735
 
702
736
  # On complete, send the result
703
737
  value.on_complete do |defer, result|
704
- send_result(defer.request, result)
738
+ self._send_INVOCATION_result(defer.request, result, {}, true)
705
739
  self._defers.delete(defer.request)
706
740
  end
707
741
 
708
742
  # On error, send the error
709
743
  value.on_error do |defer, error|
710
- send_error(defer.request, error)
744
+ self._send_INVOCATION_error(defer.request, error, true)
711
745
  self._defers.delete(defer.request)
712
746
  end
713
747
 
714
748
  # For progressive, return the progress
715
749
  if value.is_a? WampClient::Defer::ProgressiveCallDefer
716
750
  value.on_progress do |defer, result|
717
- send_result(defer.request, result, {progress: true})
751
+ self._send_INVOCATION_result(defer.request, result, {progress: true}, true)
718
752
  end
719
753
  end
720
754
 
721
755
  # Else it was a normal response
722
756
  else
723
- send_result(request, value)
757
+ self._send_INVOCATION_result(request, value)
724
758
  end
725
759
 
726
760
  rescue Exception => error
727
- send_error(request, error)
761
+ self._send_INVOCATION_error(request, error)
728
762
  end
729
763
 
730
764
  end
731
765
  end
732
766
  end
733
767
 
768
+ # Processes the interrupt
769
+ # @param msg [WampClient::Message::Interrupt] An interrupt to a procedure
770
+ def _process_INTERRUPT(msg)
771
+
772
+ request = msg.invocation_request
773
+ mode = msg.options[:mode]
774
+
775
+ defer = self._defers[request]
776
+ if defer
777
+ r = self._registrations[defer.registration]
778
+ if r
779
+ # If it exists, call the interrupt handler to inform it of the interrupt
780
+ i = r.i_handler
781
+ error = nil
782
+ if i
783
+ begin
784
+ error = i.call(request, mode)
785
+ rescue Exception => e
786
+ error = e
787
+ end
788
+ end
789
+
790
+ error ||= 'interrupt'
791
+
792
+ # Send the error back to the client
793
+ self._send_INVOCATION_error(request, error, true)
794
+ end
795
+
796
+ # Delete the defer
797
+ self._defers.delete(request)
798
+ end
799
+
800
+ end
801
+
734
802
  #endregion
735
803
 
736
804
  #region Unregister Logic
@@ -802,6 +870,7 @@ module WampClient
802
870
  # @param kwargs [Hash] The keyword arguments
803
871
  # @param options [Hash] The options for the call
804
872
  # @param callback [block] The callback(result, error, details) called to signal if the call was a success or not
873
+ # @return [Call] An object representing the call
805
874
  def call(procedure, args=nil, kwargs=nil, options={}, &callback)
806
875
  unless is_open?
807
876
  raise RuntimeError, "Session must be open to call 'call'"
@@ -817,8 +886,22 @@ module WampClient
817
886
  self._requests[:call][request] = {p: procedure, a: args, k: kwargs, o: options, c: callback}
818
887
 
819
888
  # Send the message
820
- call = WampClient::Message::Call.new(request, options, procedure, args, kwargs)
821
- self._send_message(call)
889
+ msg = WampClient::Message::Call.new(request, options, procedure, args, kwargs)
890
+ self._send_message(msg)
891
+
892
+ call = Call.new(self, request)
893
+
894
+ # Timeout Logic
895
+ if options[:timeout] and options[:timeout] > 0
896
+ self.transport.timer(options[:timeout]) do
897
+ # Once the timer expires, if the call hasn't completed, cancel it
898
+ if self._requests[:call][call.id]
899
+ call.cancel
900
+ end
901
+ end
902
+ end
903
+
904
+ call
822
905
  end
823
906
 
824
907
  # Processes the response to a publish request
@@ -862,5 +945,24 @@ module WampClient
862
945
 
863
946
  #endregion
864
947
 
948
+ #region Cancel Logic
949
+
950
+ # Cancels a call
951
+ # @param call [Call] - The call object
952
+ # @param mode [String] - The mode of the skip. Options are 'skip', 'kill', 'killnowait'
953
+ def cancel(call, mode='skip')
954
+ unless is_open?
955
+ raise RuntimeError, "Session must be open to call 'cancel'"
956
+ end
957
+
958
+ self.class.check_nil('call', call, false)
959
+
960
+ # Send the message
961
+ cancel = WampClient::Message::Cancel.new(call.id, { mode: mode })
962
+ self._send_message(cancel)
963
+ end
964
+
965
+ #endregion
966
+
865
967
  end
866
968
  end
@@ -106,6 +106,13 @@ module WampClient
106
106
  # Implement in subclass
107
107
  end
108
108
 
109
+ # Process the callback when the timer expires
110
+ # @param [Integer] milliseconds - The number
111
+ # @param [block] callback - The callback that is fired when the timer expires
112
+ def timer(milliseconds, &callback)
113
+ # Implement in subclass
114
+ end
115
+
109
116
  end
110
117
 
111
118
  # This implementation uses the 'websocket-eventmachine-client' Gem. This is the default if no transport is included
@@ -151,6 +158,13 @@ module WampClient
151
158
  end
152
159
  end
153
160
 
161
+ def timer(milliseconds, &callback)
162
+ delay = (milliseconds.to_f/1000.0).ceil
163
+ EM.add_timer(delay) {
164
+ callback.call
165
+ }
166
+ end
167
+
154
168
  end
155
169
  end
156
170
  end
@@ -26,5 +26,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
26
  =end
27
27
 
28
28
  module WampClient
29
- VERSION = '0.0.5'
29
+ VERSION = '0.0.6'
30
30
  end
data/spec/session_spec.rb CHANGED
@@ -26,6 +26,8 @@ describe WampClient::Session do
26
26
  expect(transport.messages[0][0]).to eq(WampClient::Message::Types::HELLO)
27
27
  expect(transport.messages[0][1]).to eq('test') # Realm Test
28
28
  expect(transport.messages[0][2][:roles]).not_to be_nil # Roles exists
29
+ expect(transport.messages[0][2].key?(:authid)).to eq(false) # Ensure authid is omitted
30
+ expect(transport.messages[0][2].key?(:authmethods)).to eq(false) # Ensure authmethods is ommitted
29
31
 
30
32
  # Check State
31
33
  expect(session.id).to be_nil
@@ -559,6 +561,9 @@ describe WampClient::Session do
559
561
 
560
562
  describe 'invocation' do
561
563
  before(:each) do
564
+ @mode = nil
565
+ @request = nil
566
+
562
567
  # Check Exception
563
568
  expect { session.register('test.procedure', nil, {test: 1}) }.to raise_exception("Session must be open to call 'register'")
564
569
 
@@ -603,6 +608,18 @@ describe WampClient::Session do
603
608
  registered = WampClient::Message::Registered.new(request_id, 6789)
604
609
  transport.receive_message(registered.payload)
605
610
 
611
+ # Defer Interrupt Register
612
+ defer_interrupt_handler = lambda do |request, mode|
613
+ @request = request
614
+ @mode = mode
615
+ @response
616
+ end
617
+ session.register('test.defer.interrupt.procedure', defer_handler, nil, defer_interrupt_handler)
618
+
619
+ request_id = session._requests[:register].keys.first
620
+ registered = WampClient::Message::Registered.new(request_id, 7896)
621
+ transport.receive_message(registered.payload)
622
+
606
623
  transport.messages = []
607
624
  end
608
625
 
@@ -784,6 +801,75 @@ describe WampClient::Session do
784
801
  expect(transport.messages[0][6]).to eq({error: true})
785
802
 
786
803
  end
804
+
805
+ context 'cancels' do
806
+ it 'default response' do
807
+
808
+ @response = nil
809
+
810
+ @defer = WampClient::Defer::CallDefer.new
811
+
812
+ # Generate server event
813
+ invocation = WampClient::Message::Invocation.new(7890, 7896, {test:1}, [2], {param: 'value'})
814
+ transport.receive_message(invocation.payload)
815
+
816
+ expect(transport.messages.count).to eq(0)
817
+
818
+ # Generate the interrupt from the broker/dealer
819
+ interrupt = WampClient::Message::Interrupt.new(7890, { mode: 'killnowait'})
820
+ transport.receive_message(interrupt.payload)
821
+
822
+ # Check and make sure request and mode were sent
823
+ expect(@request).to eq(7890)
824
+ expect(@mode).to eq('killnowait')
825
+
826
+ # Check and make sure error message was sent
827
+ expect(transport.messages.count).to eq(1)
828
+ expect(transport.messages[0][0]).to eq(WampClient::Message::Types::ERROR)
829
+ expect(transport.messages[0][1]).to eq(WampClient::Message::Types::INVOCATION)
830
+ expect(transport.messages[0][2]).to eq(7890)
831
+ expect(transport.messages[0][3]).to eq({})
832
+ expect(transport.messages[0][4]).to eq('wamp.error.runtime')
833
+ expect(transport.messages[0][5]).to eq(['interrupt'])
834
+
835
+ # Check and make sure the additional response is ignored
836
+ @defer.succeed('test')
837
+ expect(transport.messages.count).to eq(1)
838
+
839
+ end
840
+
841
+ it 'custom response' do
842
+
843
+ @response = 'custom'
844
+
845
+ @defer = WampClient::Defer::CallDefer.new
846
+
847
+ # Generate server event
848
+ invocation = WampClient::Message::Invocation.new(7890, 7896, {test:1}, [2], {param: 'value'})
849
+ transport.receive_message(invocation.payload)
850
+
851
+ expect(transport.messages.count).to eq(0)
852
+
853
+ # Generate the interrupt from the broker/dealer
854
+ interrupt = WampClient::Message::Interrupt.new(7890, { mode: 'kill'})
855
+ transport.receive_message(interrupt.payload)
856
+
857
+ # Check and make sure request and mode were sent
858
+ expect(@request).to eq(7890)
859
+ expect(@mode).to eq('kill')
860
+
861
+ # Check and make sure error message was sent
862
+ expect(transport.messages.count).to eq(1)
863
+ expect(transport.messages[0][0]).to eq(WampClient::Message::Types::ERROR)
864
+ expect(transport.messages[0][1]).to eq(WampClient::Message::Types::INVOCATION)
865
+ expect(transport.messages[0][2]).to eq(7890)
866
+ expect(transport.messages[0][3]).to eq({})
867
+ expect(transport.messages[0][4]).to eq('wamp.error.runtime')
868
+ expect(transport.messages[0][5]).to eq(['custom'])
869
+
870
+ end
871
+
872
+ end
787
873
  end
788
874
 
789
875
  describe 'unregister' do
@@ -992,6 +1078,73 @@ describe WampClient::Session do
992
1078
 
993
1079
  end
994
1080
 
1081
+ it 'cancels calling a procedure' do
1082
+
1083
+ count = 0
1084
+ call = session.call('test.procedure', nil, nil, {acknowledge: true}) do |result, error, details|
1085
+ count += 1
1086
+
1087
+ expect(result).to be_nil
1088
+ expect(error[:error]).to eq('this.cancelled')
1089
+ expect(details).to eq({fail: true, procedure: 'test.procedure', type: 'call'})
1090
+ end
1091
+
1092
+ @request_id = session._requests[:call].keys.first
1093
+
1094
+ expect(count).to eq(0)
1095
+
1096
+ # Call Cancel
1097
+ call.cancel('kill')
1098
+
1099
+ # Check transport
1100
+ expect(transport.messages.count).to eq(2)
1101
+ expect(transport.messages[1][0]).to eq(WampClient::Message::Types::CANCEL)
1102
+ expect(transport.messages[1][1]).to eq(call.id)
1103
+ expect(transport.messages[1][2]).to eq({mode: 'kill'})
1104
+
1105
+ # Generate Server Response
1106
+ error = WampClient::Message::Error.new(WampClient::Message::Types::CALL,
1107
+ @request_id, {fail: true}, 'this.cancelled')
1108
+ transport.receive_message(error.payload)
1109
+
1110
+ expect(count).to eq(1)
1111
+
1112
+ # Check the request dictionary
1113
+ expect(session._requests[:call].count).to eq(0)
1114
+
1115
+ end
1116
+
1117
+ context 'timeout' do
1118
+ it 'does not cancel a call if no timeout specified' do
1119
+ @defer = WampClient::Defer::ProgressiveCallDefer.new
1120
+
1121
+ count = 0
1122
+ session.call('test.procedure', nil, nil) do |result, error, details|
1123
+ count += 1
1124
+ end
1125
+
1126
+ expect(transport.timer_callback).to be_nil
1127
+ expect(transport.messages.count).to eq(1)
1128
+ end
1129
+
1130
+ it 'does cancel a call if a timeout is specified' do
1131
+ @defer = WampClient::Defer::ProgressiveCallDefer.new
1132
+
1133
+ count = 0
1134
+ call = session.call('test.procedure', nil, nil, {timeout: 1000}) do |result, error, details|
1135
+ count += 1
1136
+ end
1137
+
1138
+ expect(transport.timer_callback).not_to be_nil
1139
+ transport.timer_callback.call
1140
+
1141
+ expect(transport.messages.count).to eq(2)
1142
+
1143
+ expect(transport.messages[1][0]).to eq(WampClient::Message::Types::CANCEL)
1144
+ expect(transport.messages[1][1]).to eq(call.id)
1145
+ expect(transport.messages[1][2]).to eq({mode: 'skip'})
1146
+ end
1147
+ end
995
1148
  end
996
1149
 
997
1150
  describe 'progressive_call_results' do
@@ -1004,7 +1157,7 @@ describe WampClient::Session do
1004
1157
  transport.messages = []
1005
1158
  end
1006
1159
 
1007
- it 'caller ignores (should only get the first response' do
1160
+ it 'caller ignores (should only get the first response because receive_progress is false)' do
1008
1161
 
1009
1162
  results = []
1010
1163
  session.call('test.procedure', [], {}, {}) do |result, error, details|
@@ -1162,6 +1315,56 @@ describe WampClient::Session do
1162
1315
 
1163
1316
  end
1164
1317
 
1318
+ it 'callee error support' do
1319
+
1320
+ # Defer Register
1321
+ @defer = WampClient::Defer::ProgressiveCallDefer.new
1322
+ defer_handler = lambda do |args, kwargs, details|
1323
+ @defer
1324
+ end
1325
+ session.register('test.defer.procedure', defer_handler)
1326
+
1327
+ request_id = session._requests[:register].keys.first
1328
+ registered = WampClient::Message::Registered.new(request_id, 4567)
1329
+ transport.receive_message(registered.payload)
1330
+
1331
+ transport.messages = []
1332
+
1333
+ # Generate server event
1334
+ invocation = WampClient::Message::Invocation.new(7890, 4567, {test:1}, [2], {param: 'value'})
1335
+ transport.receive_message(invocation.payload)
1336
+
1337
+ expect(transport.messages.count).to eq(0)
1338
+ expect(session._defers.count).to eq(1)
1339
+
1340
+ @defer.progress(WampClient::CallResult.new(['test1']))
1341
+ expect(session._defers.count).to eq(1)
1342
+ @defer.progress(WampClient::CallResult.new(['test2']))
1343
+ expect(session._defers.count).to eq(1)
1344
+ @defer.fail(WampClient::CallError.new('test.error'))
1345
+ expect(session._defers.count).to eq(0)
1346
+
1347
+ expect(transport.messages.count).to eq(3)
1348
+
1349
+ # Check and make sure yield message was sent
1350
+ expect(transport.messages[0][0]).to eq(WampClient::Message::Types::YIELD)
1351
+ expect(transport.messages[0][1]).to eq(7890)
1352
+ expect(transport.messages[0][2]).to eq({progress: true})
1353
+ expect(transport.messages[0][3]).to eq(['test1'])
1354
+
1355
+ expect(transport.messages[1][0]).to eq(WampClient::Message::Types::YIELD)
1356
+ expect(transport.messages[1][1]).to eq(7890)
1357
+ expect(transport.messages[1][2]).to eq({progress: true})
1358
+ expect(transport.messages[1][3]).to eq(['test2'])
1359
+
1360
+ expect(transport.messages[2][0]).to eq(WampClient::Message::Types::ERROR)
1361
+ expect(transport.messages[2][1]).to eq(WampClient::Message::Types::INVOCATION)
1362
+ expect(transport.messages[2][2]).to eq(7890)
1363
+ expect(transport.messages[2][3]).to eq({})
1364
+ expect(transport.messages[2][4]).to eq('test.error')
1365
+
1366
+ end
1367
+
1165
1368
  end
1166
1369
 
1167
1370
  describe 'auth' do
data/spec/spec_helper.rb CHANGED
@@ -14,7 +14,7 @@ module SpecHelper
14
14
 
15
15
  class TestTransport < WampClient::Transport::Base
16
16
 
17
- attr_accessor :messages
17
+ attr_accessor :messages, :timer_callback
18
18
 
19
19
  def initialize(options)
20
20
  super(options)
@@ -40,6 +40,10 @@ module SpecHelper
40
40
  @on_message.call(deserialize) unless @on_message.nil?
41
41
  end
42
42
 
43
+ def timer(milliseconds, &callback)
44
+ self.timer_callback = callback
45
+ end
46
+
43
47
  end
44
48
 
45
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wamp_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Chapman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-05 00:00:00.000000000 Z
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler