pipe_rpc 0.3.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d06d3d11acca99089b43065d1ad56988c0d3113
4
- data.tar.gz: 39649de0d7021a175a9537e1e9749a20f2240da6
3
+ metadata.gz: db3929008eaf1ac0b4d3d3d2f54ca17ea82ffa9c
4
+ data.tar.gz: 7737ad82b6cc89bb348179659b64617f28a5b1a1
5
5
  SHA512:
6
- metadata.gz: 2807e8f2f0594d408a8839f1e7297027222508fea89454bb02d56fa4b444cb80a0cfc72ca2f286ccdd3ad1bf2fbec634ad12acbabad58a9624d5b5e004cdfff5
7
- data.tar.gz: e04c2e989be39d481123c98c636cef5699ced3d47821c6fe5b2020378b6191dccec7747bfecaec05aadffae6b21e49a8713d434a8d36770f1f0d835d5a95462a
6
+ metadata.gz: 5a70e27fe8b73c7630c1101f4234d78d991254965c598839622763bd5f37197294bbef0dbdaad93f0f3b35c5659f36f88157fbba6a9d8f5b0a809b8b96f0f70d
7
+ data.tar.gz: a4ebe6276e87fb6d8613c4f8f721c59c001e6f8635a029848ef0c3be912aaafe44c5f6015c7691af1400557c2d275b0fc2af09d1d7615f0f90c0c317947ff545
@@ -1,22 +1,13 @@
1
1
  module PipeRpc
2
2
  class Client < BasicObject
3
- def initialize(hub, args = {})
3
+ def initialize(server = :default, hub)
4
+ @server = server.to_sym
4
5
  @hub = hub
5
- @server = args.fetch(:server, :default).to_sym
6
6
  end
7
7
 
8
8
  def method_missing(method, *args)
9
- backtrace = ::Kernel.respond_to?(:caller) ? ::Kernel.caller(1) : []
10
-
11
- @hub.request(server: @server, method: method, arguments: args) do |result|
12
- if result.is_a? ::StandardError
13
- result.set_backtrace(result.backtrace.to_a + backtrace.to_a) if result.respond_to? :set_backtrace
14
- ::Kernel.raise result
15
- else
16
- result
17
- end
18
- end
19
- # Method won't return until we got a result because @hub.request starts a loop and blocks!
9
+ request = Client::Request.new(server: @server, method: method, arguments: args)
10
+ @hub.requests.evaluate(request)
20
11
  end
21
12
 
22
13
  def to_s
@@ -0,0 +1,24 @@
1
+ class PipeRpc::Request; end
2
+
3
+ module PipeRpc
4
+ class Client::Request < Request
5
+ def initialize(*args)
6
+ super
7
+ # discard first three entries mentioning Client::Request#initialize,
8
+ # Client::Request.new and Client#method_missing in stacktrace
9
+ @stacktrace = Kernel.respond_to?(:caller) ? Kernel.caller(3).to_a : []
10
+ @result = Result.new(self)
11
+ end
12
+
13
+ attr_reader :stacktrace, :result
14
+
15
+ def id=(id)
16
+ raise 'id already set' if @id
17
+ @id = id
18
+ end
19
+
20
+ def id
21
+ @id or raise 'id not set'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ class PipeRpc::ErrorResponse; end
2
+
3
+ module PipeRpc
4
+ class Client::Request::ErrorResponse < ErrorResponse
5
+ def initialize(request, body)
6
+ @request = request
7
+ super body
8
+ end
9
+
10
+ def to_result
11
+ case @code
12
+ when -32601 then no_method_error
13
+ when -32602 then argument_error
14
+ when -32603 then internal_error
15
+ when -32604 then no_server_error
16
+ when -32605 then reflected_error
17
+ else unknown_error
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def no_method_error
24
+ method = @data.fetch(:method)
25
+ args = @data.fetch(:args)
26
+ NoMethodError.new("undefined method `#{method}' for <Client:#{@request.server}>", method, args)
27
+ end
28
+
29
+ def argument_error
30
+ ArgumentError.new(@data.fetch(:message))
31
+ end
32
+
33
+ def no_server_error
34
+ NoServerError.new("undefined server `#{@request.server}'")
35
+ end
36
+
37
+ def internal_error
38
+ InternalError.new(@data[:message]).tap do |error|
39
+ error.set_backtrace(@data[:backtrace]) if error.respond_to? :set_backtrace
40
+ end
41
+ end
42
+
43
+ def reflected_error
44
+ ReflectedError.new(@data[:message]).tap do |error|
45
+ error.set_backtrace(@data[:backtrace]) if error.respond_to? :set_backtrace
46
+ end
47
+ end
48
+
49
+ def unknown_error
50
+ UnknownError.new(@data[:message])
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,26 @@
1
+ module PipeRpc
2
+ class Client::Request
3
+ class Response
4
+ def initialize(hub, body)
5
+ @hub = hub
6
+ @body = body
7
+ end
8
+
9
+ attr_reader :body
10
+
11
+ def result?
12
+ @body.has_key? :result
13
+ end
14
+
15
+ def error?
16
+ @body.has_key? :error
17
+ end
18
+
19
+ def handle
20
+ type = result? ? ResultResponse : ErrorResponse
21
+ result = type.new(@hub.requests[@body[:id]], @body).to_result
22
+ @hub.requests.inject_result_for(@body[:id], result)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module PipeRpc
2
+ class Client::Request::Result
3
+ def initialize(request)
4
+ @request = request
5
+ end
6
+
7
+ def value=(result)
8
+ @received = true
9
+ @value = result
10
+ end
11
+
12
+ def received?
13
+ @received
14
+ end
15
+
16
+ def value
17
+ if @value.is_a? Exception
18
+ @value.set_backtrace(@value.backtrace.to_a + @request.stacktrace) if @value.respond_to? :set_backtrace
19
+ raise @value
20
+ else
21
+ @value
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ class PipeRpc::ResultResponse; end
2
+
3
+ module PipeRpc
4
+ class Client::Request::ResultResponse < ResultResponse
5
+ def initialize(request, body)
6
+ @request = request
7
+ super body
8
+ end
9
+
10
+ def to_result
11
+ result
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,14 @@
1
1
  module PipeRpc
2
2
  class Error < RuntimeError; end
3
- class InternalError < Error; end
3
+ class ClosedError < Error; end
4
+ class UnknownError < Error; end
5
+
6
+ class MessageError < Error; end
7
+ class MessageParseError < MessageError; end
8
+ class InvalidMessageError < MessageError; end
9
+
10
+ class NoRequestForResponseError < Error; end
4
11
  class NoServerError < Error; end
12
+ class InternalError < Error; end
5
13
  class ReflectedError < Error; end
6
- class CanceledError < Error; end
7
14
  end
@@ -5,7 +5,7 @@ module PipeRpc
5
5
  error = args.fetch(:error)
6
6
  @code = error.fetch(:code)
7
7
  @message = msg_for(@code) || error.fetch(:message, 'Unknown error')
8
- @data = error.fetch(:data, nil)
8
+ @data = error.fetch(:data, {})
9
9
  end
10
10
 
11
11
  attr_reader :id, :code, :message, :data
@@ -14,15 +14,6 @@ module PipeRpc
14
14
  { id: id, error: { code: code, message: message, data: data } }
15
15
  end
16
16
 
17
- def native_error(request = nil)
18
- @request = request
19
- error_for(@code)
20
- end
21
-
22
- def result_for(*args)
23
- native_error(*args)
24
- end
25
-
26
17
  private
27
18
 
28
19
  def msg_for(code)
@@ -37,41 +28,5 @@ module PipeRpc
37
28
  else nil
38
29
  end
39
30
  end
40
-
41
- def error_for(code)
42
- case code
43
- when -32601 then no_method_error
44
- when -32602 then argument_error
45
- when -32604 then no_server_error
46
- when -32605 then reflected_error
47
- else internal_error
48
- end
49
- end
50
-
51
- def no_method_error
52
- method = @data.fetch(:method)
53
- args = @data.fetch(:args)
54
- NoMethodError.new("undefined method `#{method}' for <Client:#{@request.server}>", method, args)
55
- end
56
-
57
- def argument_error
58
- ArgumentError.new(@data.fetch(:message))
59
- end
60
-
61
- def no_server_error
62
- NoServerError.new("undefined server `#{@request.server}'")
63
- end
64
-
65
- def internal_error
66
- InternalError.new(@data[:message]).tap do |error|
67
- error.set_backtrace(@data[:backtrace]) if error.respond_to? :set_backtrace
68
- end
69
- end
70
-
71
- def reflected_error
72
- ReflectedError.new("#{@data[:message]}").tap do |error|
73
- error.set_backtrace(@data[:backtrace]) if error.respond_to? :set_backtrace
74
- end
75
- end
76
31
  end
77
32
  end
@@ -0,0 +1,39 @@
1
+ module PipeRpc
2
+ class Gateway
3
+ def initialize(args)
4
+ @hub = Hub.new(args)
5
+ end
6
+
7
+ def channel
8
+ @hub.channel
9
+ end
10
+
11
+ def servers
12
+ @hub.servers
13
+ end
14
+
15
+ def clients
16
+ @hub.clients
17
+ end
18
+
19
+ def loop_iteration=(iteration)
20
+ @hub.requests.wait_for_results_through(iteration)
21
+ end
22
+
23
+ def on_sent(&on_sent)
24
+ @hub.socket.on_sent(&on_sent)
25
+ end
26
+
27
+ def on_received(&on_received)
28
+ @hub.socket.on_received(&on_received)
29
+ end
30
+
31
+ def close
32
+ @hub.socket.close
33
+ end
34
+
35
+ def handle_message
36
+ @hub.handle_message
37
+ end
38
+ end
39
+ end
data/lib/pipe_rpc/hub.rb CHANGED
@@ -3,111 +3,15 @@ module PipeRpc
3
3
  def initialize(args)
4
4
  @channel = args[:input]
5
5
  @socket = Socket.new(self, args)
6
- @requester = Requester.new(self)
7
- @responder = Responder.new(self)
8
- @clients = {}
9
- self.loop_iteration = nil
6
+ @requests = Requests.new(self)
7
+ @servers = Servers.new
8
+ @clients = Clients.new(self)
10
9
  end
11
10
 
12
- attr_reader :channel
13
- attr_accessor :logger
14
-
15
- def log(msg)
16
- if logger == :reflect
17
- notify(server: :reflect_logger, method: :log, arguments: [msg])
18
- elsif logger.respond_to? :debug
19
- logger.debug msg
20
- elsif logger
21
- logger.call msg
22
- end
23
- end
24
-
25
- def add_server(servers)
26
- @responder.add_server(servers)
27
- end
28
-
29
- def rmv_server(server_name)
30
- @responder.rmv_server(server_name)
31
- end
32
-
33
- def on_incoming_request(&on_request)
34
- @responder.on_request(&on_request)
35
- end
36
-
37
- def client_for(server_name)
38
- @clients[server_name] ||= Client.new(self, server: server_name)
39
- end
40
-
41
- def loop_iteration=(proc)
42
- @loop_iteration = proc
43
- end
44
-
45
- def on_sent(&on_sent)
46
- @socket.on_write(&on_sent)
47
- end
48
-
49
- def on_received(&on_received)
50
- @socket.on_read(&on_received)
51
- end
52
-
53
- def notify(signature)
54
- @socket.write @requester.notification(signature)
55
- end
56
-
57
- def cancel
58
- @socket.close
59
- @canceled = true
60
- end
61
-
62
- def request(signature, &on_result)
63
- raise CanceledError.new if @canceled
64
-
65
- result = nil
66
- result_ready = false
67
-
68
- request = @requester.request(signature) do |*response|
69
- result = on_result.call(*response)
70
- result_ready = true
71
- end
72
- @socket.write request
73
-
74
- loop do
75
- raise CanceledError.new if @canceled
76
- return result if result_ready
77
- @loop_iteration ? @loop_iteration.call : handle_message
78
- end
79
- end
80
-
81
- def send_response(response)
82
- @socket.write response
83
- end
11
+ attr_reader :channel, :servers, :clients, :requests, :socket
84
12
 
85
13
  def handle_message
86
- message = next_message # blocks
87
-
88
- return unless message
89
-
90
- if message.notification?
91
- @responder.handle_notification(message.handler)
92
- elsif message.request?
93
- @responder.handle_request(message.handler)
94
- elsif message.response?
95
- @requester.handle_response(message.handler)
96
- elsif message.error?
97
- raise message.handler.native_error
98
- else
99
- send_response ErrorResponse.new(id: nil, error: { code: -32600,
100
- data: { message: 'no request, result or error' } })
101
- end
102
- end
103
-
104
- private
105
-
106
- def next_message
107
- Message.new(self, @socket.read) # blocks
108
- rescue => e
109
- send_response ErrorResponse.new(id: nil, error: { code: -32700, data: { message: e.message } })
110
- nil
14
+ Message.new(self, @socket.read).handle
111
15
  end
112
16
  end
113
17
  end
@@ -0,0 +1,12 @@
1
+ module PipeRpc
2
+ class Hub::Clients
3
+ def initialize(hub)
4
+ @hub = hub
5
+ @clients = {}
6
+ end
7
+
8
+ def [](server)
9
+ @clients[server.to_sym] ||= Client.new(server.to_sym, @hub)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ module PipeRpc
2
+ class Hub
3
+ class Message
4
+ def initialize(hub, body)
5
+ @hub = hub
6
+ @body = body
7
+ end
8
+
9
+ def request?
10
+ @body.has_key? :method
11
+ end
12
+
13
+ def response?
14
+ (@body.has_key? :error or @body.has_key? :result) and !!@body[:id]
15
+ end
16
+
17
+ def error?
18
+ @body.has_key? :error and @body[:id].nil?
19
+ end
20
+
21
+ def handler_type
22
+ if request?
23
+ Hub::Request
24
+ elsif response?
25
+ Client::Request::Response
26
+ elsif error?
27
+ Message::ErrorResponse
28
+ else
29
+ raise 'no request, result or error'
30
+ end
31
+ end
32
+
33
+ def handler
34
+ handler_type.new(@hub, @body)
35
+ rescue => e
36
+ @hub.socket.write ErrorResponse.new(id: @body[:id], error: { code: -32600,
37
+ data: { message: e.message } })
38
+ nil
39
+ end
40
+
41
+ def handle
42
+ handler.tap do |handler|
43
+ handler.handle if handler
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,22 @@
1
+ class PipeRpc::ErrorResponse; end
2
+
3
+ module PipeRpc
4
+ class Hub::Message::ErrorResponse < ErrorResponse
5
+ def initialize(hub, body)
6
+ @hub = hub
7
+ super body
8
+ end
9
+
10
+ def to_error
11
+ case @code
12
+ when -32700 then MessageParseError.new(@data.fetch(:message))
13
+ when -32600 then InvalidMessageError.new(@data.fetch(:message))
14
+ else UnknownError.new(@data[:message])
15
+ end
16
+ end
17
+
18
+ def handle
19
+ raise to_error
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ class PipeRpc::Request; end
2
+
3
+ module PipeRpc
4
+ class Hub::Request < Request
5
+ def initialize(hub, body)
6
+ @hub = hub
7
+ super body
8
+ end
9
+
10
+ CALL_FILE, CALL_LINENO = __FILE__, __LINE__+4
11
+ def handle
12
+ evaluate_result do
13
+ # the block is passed for asynchronous evaluation
14
+ @hub.servers[server].__send__(method, *arguments, &evaluate_result_proc)
15
+ end
16
+ end
17
+
18
+ def evaluate_result(result = nil, &block)
19
+ result = Result.new(self, block_given? ? yield : result)
20
+ rescue Exception => e
21
+ result = ErrorResult.new(self, e)
22
+ ensure
23
+ asynchronous = result.value == evaluate_result_proc
24
+ @hub.socket.write(result.to_response) unless asynchronous
25
+ return result.value
26
+ end
27
+
28
+ def evaluate_result_proc
29
+ @evaluate_result_proc ||= proc do |result = nil, &block|
30
+ evaluate_result(result, &block)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module PipeRpc
2
- class Hub::Responder::Request
2
+ class Hub::Request
3
3
  class Error
4
4
  def initialize(error)
5
5
  @error = error
@@ -13,8 +13,7 @@ module PipeRpc
13
13
  when method_call_error? && NoMethodError then -32601
14
14
  when method_call_error? && ArgumentError then -32602
15
15
  when InternalError then -32605
16
- when StandardError then -32603
17
- else nil
16
+ else -32603
18
17
  end
19
18
  end
20
19
 
@@ -1,5 +1,5 @@
1
1
  module PipeRpc
2
- class Hub::Responder::Request
2
+ class Hub::Request
3
3
  class ErrorResult
4
4
  def initialize(request, error)
5
5
  @request, @error = request, Error.new(error)
@@ -9,10 +9,6 @@ module PipeRpc
9
9
  @error.error
10
10
  end
11
11
 
12
- def asynchronous?
13
- false
14
- end
15
-
16
12
  def to_response
17
13
  ErrorResponse.new(id: @request.id, error: { code: @error.code, data: { message: @error.message,
18
14
  backtrace: @error.backtrace, method: @request.method, args: @request.arguments } })
@@ -1,17 +1,13 @@
1
1
  module PipeRpc
2
- class Hub::Responder::Request::Result
2
+ class Hub::Request::Result
3
3
  def initialize(request, result)
4
- @request, @result = request, result
4
+ @request, @result, @async_responder = request, result
5
5
  end
6
6
 
7
7
  def value
8
8
  @result
9
9
  end
10
10
 
11
- def asynchronous?
12
- @result == @request.evaluate_result_proc
13
- end
14
-
15
11
  def to_response
16
12
  ResultResponse.new(id: @request.id, result: @result)
17
13
  end
@@ -0,0 +1,35 @@
1
+ module PipeRpc
2
+ class Hub::Requests
3
+ def initialize(hub)
4
+ @hub = hub
5
+ @requests ={}
6
+ @uid = 0
7
+ wait_for_results_through nil
8
+ end
9
+
10
+ attr_reader :requests
11
+
12
+ def evaluate(request)
13
+ @uid += 1
14
+ request.id = @uid
15
+ @requests[@uid] = request
16
+ @hub.socket.write request
17
+ @wait.call until request.result.received?
18
+ request.result.value
19
+ end
20
+
21
+ def [](id)
22
+ @requests[id]
23
+ end
24
+
25
+ def inject_result_for(id, result)
26
+ request = @requests.delete(id)
27
+ raise NoRequestForResponseError.new("no request with id '#{id.inspect}'") unless request
28
+ request.result.value = result
29
+ end
30
+
31
+ def wait_for_results_through(iteration)
32
+ @wait = iteration.respond_to?(:call) ? iteration : proc{ @hub.handle_message }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ module PipeRpc
2
+ class Hub::Servers
3
+ def initialize
4
+ @servers = Hash.new{ |hash, key| raise NoServerError.new("no server #{key}") }
5
+ end
6
+
7
+ def add(servers)
8
+ servers.each{ |name, server| @servers[name.to_sym] = server }
9
+ end
10
+
11
+ def [](name)
12
+ @servers[name.to_sym]
13
+ end
14
+
15
+ def remove(name)
16
+ @servers.delete(name.to_sym)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ module PipeRpc
2
+ class Hub::Socket
3
+ def initialize(hub, args = {})
4
+ @hub = hub
5
+ @input = args.fetch(:input)
6
+ @output = args.fetch(:output)
7
+ @on_sent = []
8
+ @on_received = []
9
+ end
10
+
11
+ def read
12
+ raise ClosedError if @input.closed?
13
+ incoming = Incoming.new(@input.gets) # blocks
14
+ incoming.trigger(@on_received)
15
+ incoming.to_h
16
+ rescue JSON::JSONError => e
17
+ write ErrorResponse.new(id: nil, error: { code: -32700, data: { message: e.message } })
18
+ end
19
+
20
+ def write(obj)
21
+ raise ClosedError if @output.closed?
22
+ outgoing = Outgoing.new(obj)
23
+ outgoing.trigger(@on_sent)
24
+ @output.puts outgoing.to_payload
25
+ end
26
+
27
+ def on_sent(&on_sent)
28
+ @on_sent << on_sent
29
+ end
30
+
31
+ def on_received(&on_received)
32
+ @on_received << on_received
33
+ end
34
+
35
+ def close
36
+ @input.close
37
+ @output.close
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ module PipeRpc
2
+ class Hub::Socket
3
+ class Incoming
4
+ def initialize(payload)
5
+ @payload = payload
6
+ end
7
+
8
+ def to_h
9
+ @hash ||= JSON.load(@payload).symbolize_keys.tap do |hash|
10
+ hash[:error] = hash[:error].symbolize_keys if hash[:error]
11
+ hash[:error][:data] = hash[:error][:data].symbolize_keys if hash[:error] and hash[:error][:data]
12
+ end
13
+ end
14
+
15
+ def trigger(callbacks)
16
+ callbacks.each{ |callback| callback.call(to_h) }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module PipeRpc
2
+ class Hub::Socket
3
+ class Outgoing
4
+ def initialize(object)
5
+ @object = object
6
+ end
7
+
8
+ def to_h
9
+ @hash ||= @object.to_h
10
+ end
11
+
12
+ def to_payload
13
+ @payload ||= JSON.dump(to_h)
14
+ end
15
+
16
+ def trigger(callbacks)
17
+ callbacks.each{ |callback| callback.call(to_h) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -7,10 +7,6 @@ module PipeRpc
7
7
 
8
8
  attr_reader :result, :id
9
9
 
10
- def result_for(request)
11
- result
12
- end
13
-
14
10
  def to_h
15
11
  { id: id, result: result }
16
12
  end
@@ -1,3 +1,3 @@
1
1
  module PipeRpc
2
- VERSION = "0.3.2"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipe_rpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Aue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-04 00:00:00.000000000 Z
11
+ date: 2016-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -99,19 +99,29 @@ files:
99
99
  - lib/hash.rb
100
100
  - lib/pipe_rpc.rb
101
101
  - lib/pipe_rpc/client.rb
102
+ - lib/pipe_rpc/client_request.rb
103
+ - lib/pipe_rpc/client_request_error_response.rb
104
+ - lib/pipe_rpc/client_request_response.rb
105
+ - lib/pipe_rpc/client_request_result.rb
106
+ - lib/pipe_rpc/client_request_result_response.rb
102
107
  - lib/pipe_rpc/error.rb
103
108
  - lib/pipe_rpc/error_response.rb
109
+ - lib/pipe_rpc/gateway.rb
104
110
  - lib/pipe_rpc/hub.rb
105
- - lib/pipe_rpc/hub/message.rb
106
- - lib/pipe_rpc/hub/requester.rb
107
- - lib/pipe_rpc/hub/responder.rb
108
- - lib/pipe_rpc/hub/responder/request.rb
109
- - lib/pipe_rpc/hub/responder/request/error.rb
110
- - lib/pipe_rpc/hub/responder/request/error_result.rb
111
- - lib/pipe_rpc/hub/responder/request/result.rb
111
+ - lib/pipe_rpc/hub_clients.rb
112
+ - lib/pipe_rpc/hub_message.rb
113
+ - lib/pipe_rpc/hub_message_error_response.rb
114
+ - lib/pipe_rpc/hub_request.rb
115
+ - lib/pipe_rpc/hub_request_error.rb
116
+ - lib/pipe_rpc/hub_request_error_result.rb
117
+ - lib/pipe_rpc/hub_request_result.rb
118
+ - lib/pipe_rpc/hub_requests.rb
119
+ - lib/pipe_rpc/hub_servers.rb
120
+ - lib/pipe_rpc/hub_socket.rb
121
+ - lib/pipe_rpc/hub_socket_incoming.rb
122
+ - lib/pipe_rpc/hub_socket_outgoing.rb
112
123
  - lib/pipe_rpc/request.rb
113
124
  - lib/pipe_rpc/result_response.rb
114
- - lib/pipe_rpc/socket.rb
115
125
  - lib/pipe_rpc/version.rb
116
126
  - pipe_rpc.gemspec
117
127
  homepage: https://github.com/christopheraue/ruby-pipe_rpc
@@ -1,57 +0,0 @@
1
- module PipeRpc
2
- class Hub
3
- class Message
4
- def initialize(hub, message)
5
- @hub = hub
6
- @message = message
7
- end
8
-
9
- def notification?
10
- @message.has_key? :method and not id?
11
- end
12
-
13
- def request?
14
- @message.has_key? :method and id?
15
- end
16
-
17
- def response?
18
- (result? or error_message?) and id?
19
- end
20
-
21
- def error?
22
- error_message? and not id?
23
- end
24
-
25
- def handler
26
- @handler ||= type.new(@message)
27
- rescue => e
28
- @hub.send_response ErrorResponse.new(id: nil, error: { code: -32600, data: { message: e.message } })
29
- nil
30
- end
31
-
32
- private
33
-
34
- def result?
35
- @message.has_key? :result
36
- end
37
-
38
- def error_message?
39
- @message.has_key? :error
40
- end
41
-
42
- def type
43
- if error_message?
44
- ErrorResponse
45
- elsif result?
46
- ResultResponse
47
- else
48
- Request
49
- end
50
- end
51
-
52
- def id?
53
- not @message[:id].nil?
54
- end
55
- end
56
- end
57
- end
@@ -1,31 +0,0 @@
1
- module PipeRpc
2
- class Hub
3
- class Requester
4
- def initialize(hub)
5
- @hub = hub
6
- @requests = {}
7
- @uid = 0
8
- end
9
-
10
- def next_uid
11
- @uid += 1
12
- end
13
-
14
- def notification(signature)
15
- Request.new(signature)
16
- end
17
-
18
- def request(signature, &on_response)
19
- request = Request.new(signature.merge(id: next_uid))
20
- @requests[request.id] = { request: request, on_response: on_response }
21
- request
22
- end
23
-
24
- def handle_response(response)
25
- request = @requests.delete(response.id)
26
- raise InternalError.new("no request for response(id: #{response.id})") unless request
27
- request[:on_response].call response.result_for(request[:request])
28
- end
29
- end
30
- end
31
- end
@@ -1,35 +0,0 @@
1
- module PipeRpc
2
- class Hub::Responder
3
- class Request
4
- def initialize(responder, request)
5
- @responder, @request = responder, request
6
- end
7
-
8
- def id
9
- @request.id
10
- end
11
-
12
- CALL_FILE, CALL_LINENO = __FILE__, __LINE__+3
13
- def handle
14
- evaluate_result do
15
- @responder.servers[@request.server].__send__(@request.method, *@request.arguments, &evaluate_result_proc)
16
- end
17
- end
18
-
19
- def evaluate_result(result = nil, &block)
20
- result = Result.new(self, block_given? ? yield : result)
21
- rescue Exception => e
22
- result = ErrorResult.new(@request, e)
23
- ensure
24
- @responder.send_response(result.to_response) unless result.asynchronous?
25
- return result.value
26
- end
27
-
28
- def evaluate_result_proc
29
- @evaluate_result_proc ||= proc do |result = nil, &block|
30
- evaluate_result(result, &block)
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,39 +0,0 @@
1
- module PipeRpc
2
- class Hub
3
- class Responder
4
- def initialize(hub)
5
- @hub = hub
6
- @servers = Hash.new{ |hash, key| ::Kernel.raise NoServerError.new("no server #{key}") }
7
- end
8
-
9
- def servers
10
- @servers.dup
11
- end
12
-
13
- def add_server(servers)
14
- servers.each{ |name, server| @servers[name.to_sym] = server }
15
- end
16
-
17
- def rmv_server(server_name)
18
- @servers.delete(server_name.to_sym)
19
- end
20
-
21
- def on_request(&on_request)
22
- @on_request = on_request
23
- end
24
-
25
- def handle_notification(notification)
26
- handle_request(notification)
27
- end
28
-
29
- def handle_request(request)
30
- @on_request.call(request.server, request.method, request.arguments) if @on_request
31
- Request.new(self, request).handle
32
- end
33
-
34
- def send_response(response)
35
- @hub.send_response response
36
- end
37
- end
38
- end
39
- end
@@ -1,50 +0,0 @@
1
- module PipeRpc
2
- class Socket
3
- def initialize(hub, args = {})
4
- @hub = hub
5
- @input = args.fetch(:input)
6
- @output = args.fetch(:output)
7
- on_write{}
8
- on_read{}
9
- end
10
-
11
- def read
12
- symbolize_message_keys(JSON.load(@input.gets)).tap do |message|
13
- next if message[:server] == 'reflect_logger'
14
- @hub.log "received: #{message.inspect}"
15
- @on_read.call(message)
16
- end
17
- end
18
-
19
- def write(obj)
20
- raise InternalError.new('Output pipe broke') if @output.closed?
21
- @output.puts(JSON.dump(obj.to_h.tap do |message|
22
- next if @hub.logger == :reflect
23
- @hub.log "sent: #{message.inspect}"
24
- @on_write.call(message)
25
- end))
26
- end
27
-
28
- def on_write(&on_write)
29
- @on_write = on_write || proc{}
30
- end
31
-
32
- def on_read(&on_read)
33
- @on_read = on_read || proc{}
34
- end
35
-
36
- def close
37
- @input.close
38
- @output.close
39
- end
40
-
41
- private
42
-
43
- def symbolize_message_keys(message)
44
- hash = message.symbolize_keys
45
- hash[:error] = hash[:error].symbolize_keys if hash[:error]
46
- hash[:error][:data] = hash[:error][:data].symbolize_keys if hash[:error] and hash[:error][:data]
47
- hash
48
- end
49
- end
50
- end