pipe_rpc 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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