farcall 0.1.0 → 0.1.1
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/Gemfile +3 -0
- data/README.md +57 -36
- data/farcall.gemspec +1 -0
- data/lib/farcall.rb +6 -0
- data/lib/farcall/boss_transport.rb +52 -0
- data/lib/farcall/json_transport.rb +13 -7
- data/lib/farcall/transport.rb +6 -1
- data/lib/farcall/version.rb +1 -1
- data/spec/endpoint_spec.rb +12 -5
- data/spec/rmi_spec.rb +7 -0
- data/spec/transports_spec.rb +24 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00f92b591c51a5eed01bd1bf156d902e4865ec4f
|
4
|
+
data.tar.gz: 741af581d714a7e6b435941a9f2e1b1946361ed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8da68133b9dbf39cc77e11287b6bc491a0bdbecac048b8bfd94f02e88a521bd9e6360755a89060da73ef40d02efb61c85ff45d4cb4cfe495c232192780abd65e
|
7
|
+
data.tar.gz: 5af5f225af489f8c6aa75cc880d6855a45991f1baf500b4072af75cdd80286f1ce4625c781579b89f64a66244a20cdca257a080e410cf63d0d8c48b8c699ce58
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,46 +2,74 @@
|
|
2
2
|
|
3
3
|
## Important!
|
4
4
|
|
5
|
-
The gem creation is under active development, current state is: beta.
|
5
|
+
The gem creation is under active development, current state is: beta. The JSON and
|
6
|
+
(BOSS)[https://github.com/sergeych/boss_protocol] formats are supported out of the box,
|
7
|
+
thogh XML and other could be easily implemented.
|
6
8
|
|
7
9
|
## Description
|
8
10
|
|
9
11
|
The simple and elegant cross-platform RPC protocol that uses any formatter/transport capable of
|
10
|
-
transmitting dictionary-like objects, for example, JSON, XML, BSON, BOSS and many others.
|
12
|
+
transmitting dictionary-like objects, for example, JSON, XML, BSON, BOSS and many others. This gem
|
13
|
+
supports out of the box JSON and (BOSS)[https://github.com/sergeych/boss_protocol] protocols.
|
11
14
|
|
12
15
|
RPC is made asynchronously, each call can have any return values. While one call is waiting,
|
13
16
|
other calls can be executed. The protocol is bidirectional Call parameters could be
|
14
17
|
both arrays of arguments and keyword arguments, return value could be any object, e.g. array,
|
15
18
|
dictionary, wahtever.
|
16
19
|
|
17
|
-
Exception/errors transmitting is also supported.
|
20
|
+
Exception/errors transmitting is also supported. The interface is very simple and rubyish. The
|
21
|
+
protocol is very easy to support, its description will be available in the github wiki soon.
|
18
22
|
|
19
|
-
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
20
26
|
|
21
27
|
```ruby
|
22
|
-
|
23
|
-
#
|
24
|
-
|
28
|
+
gem 'farcall'
|
29
|
+
# If you want to use binary-effective boss encoding:
|
30
|
+
# gem 'noss-protocol', '>= 1.4.1'
|
31
|
+
```
|
25
32
|
|
26
|
-
|
33
|
+
And then execute:
|
27
34
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
return "Foo: #{a+b}, #{optional}"
|
32
|
-
end
|
33
|
-
end
|
35
|
+
$ bundle
|
36
|
+
|
37
|
+
Or install it yourself as:
|
34
38
|
|
35
|
-
|
39
|
+
$ gem install farcall
|
36
40
|
|
37
|
-
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
|
45
|
+
# The sample class that exports all its methods to the remote callers:
|
46
|
+
#
|
47
|
+
class TestProvider < Farcall::Provider
|
48
|
+
|
49
|
+
attr :foo_calls, :a, :b
|
50
|
+
|
51
|
+
def foo a, b, optional: 'none'
|
52
|
+
@foo_calls = (@foo_calls || 0) + 1
|
53
|
+
@a, @b = a, b
|
54
|
+
return "Foo: #{a+b}, #{optional}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# create instance and export it to some connected socket:
|
59
|
+
TestProvider.new socket: connected_socket # default format is JSON
|
60
|
+
|
61
|
+
# or using boss, if you need to pass dates and binary data
|
62
|
+
TestProvider.new socket: connected_socket, format: :boss
|
38
63
|
```
|
39
64
|
|
40
65
|
Suppose whe have some socket connected to one above, then TestProvider methods are available via
|
41
66
|
this connection:
|
42
67
|
|
43
68
|
```ruby
|
69
|
+
|
44
70
|
i = Farcall::Interface.new socket: client_socket
|
71
|
+
# or
|
72
|
+
# i = Farcall::Interface.new socket: client_socket, format: :boss
|
45
73
|
|
46
74
|
# Plain arguments
|
47
75
|
i.foo(10, 20).should == 'Foo: 30, none'
|
@@ -57,30 +85,23 @@ this connection:
|
|
57
85
|
i.b.should == 6
|
58
86
|
```
|
59
87
|
|
60
|
-
|
61
|
-
|
62
|
-
Add this line to your application's Gemfile:
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
gem 'farcall'
|
66
|
-
```
|
67
|
-
|
68
|
-
And then execute:
|
69
|
-
|
70
|
-
$ bundle
|
71
|
-
|
72
|
-
Or install it yourself as:
|
73
|
-
|
74
|
-
$ gem install farcall
|
88
|
+
More creation options ofr both provider and interface creation are:
|
75
89
|
|
76
|
-
|
90
|
+
* `endpoint:` at this point please refrain of using it as endpoint interface is going to change a
|
91
|
+
bit
|
92
|
+
* `transport:` subclass the `Farcall::Transport` and provide your own. It overrides `socket:`,
|
93
|
+
`input:` and `ouput:` parameters.
|
94
|
+
* `input:` and `output:` should be presented both or none - override `socket` - provide streams to
|
95
|
+
build the transport over.
|
96
|
+
|
77
97
|
|
78
|
-
|
98
|
+
Get more in (online docs)[http://www.rubydoc.info/gems/farcall]
|
79
99
|
|
80
100
|
## Contributing
|
81
101
|
|
82
102
|
1. Fork it ( https://github.com/[my-github-username]/farcall/fork )
|
83
103
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
-
3.
|
85
|
-
4.
|
86
|
-
5.
|
104
|
+
3. Do not forget ot add specs and ensure all of them pass
|
105
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
106
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
107
|
+
6. Create a new Pull Request
|
data/farcall.gemspec
CHANGED
data/lib/farcall.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
|
1
2
|
require 'farcall/version'
|
2
3
|
require 'farcall/transport'
|
3
4
|
require 'farcall/json_transport'
|
4
5
|
require 'farcall/endpoint'
|
6
|
+
begin
|
7
|
+
require 'boss-protocol'
|
8
|
+
require 'farcall/boss_transport'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
5
11
|
|
6
12
|
module Farcall
|
7
13
|
# Your code goes here...
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Farcall
|
2
|
+
|
3
|
+
class BossTransport < Farcall::Transport
|
4
|
+
include TransportBase
|
5
|
+
|
6
|
+
# Create json transport, see Farcall::Transpor#create for parameters
|
7
|
+
def initialize **params
|
8
|
+
setup_streams **params
|
9
|
+
end
|
10
|
+
|
11
|
+
def on_data_received= block
|
12
|
+
super
|
13
|
+
if block && !@thread
|
14
|
+
@thread = Thread.start {
|
15
|
+
load_loop
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def send_data hash
|
21
|
+
@output << Boss.dump(hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
def close
|
25
|
+
if !@closing
|
26
|
+
@closing = true
|
27
|
+
close_connection
|
28
|
+
@thread and @thread.join
|
29
|
+
@thread = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def load_loop
|
36
|
+
Boss::Parser.new(@input).each { |object|
|
37
|
+
on_data_received and on_data_received.call object
|
38
|
+
}
|
39
|
+
rescue Errno::EPIPE
|
40
|
+
close
|
41
|
+
rescue
|
42
|
+
if !@closing
|
43
|
+
STDERR.puts "Farcall::BossTransport read loop failed: #{$!.class.name}: #$!"
|
44
|
+
STDERR.puts $!.backtrace.join("\n")
|
45
|
+
connection_aborted $!
|
46
|
+
else
|
47
|
+
close
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'socket'
|
2
3
|
|
3
4
|
module Farcall
|
4
5
|
|
@@ -10,17 +11,22 @@ module Farcall
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def read length=1
|
13
|
-
data = ''
|
14
|
-
while data.length < length
|
15
|
-
|
16
|
-
end
|
17
|
-
data
|
14
|
+
# data = ''
|
15
|
+
# while data.length < length
|
16
|
+
# data << @socket.recv(length - data.length, Socket::MSG_WAITALL)
|
17
|
+
# end
|
18
|
+
# data
|
19
|
+
@socket.read length
|
18
20
|
end
|
19
21
|
|
20
22
|
def write data
|
21
23
|
@socket.write data
|
22
24
|
end
|
23
25
|
|
26
|
+
def eof?
|
27
|
+
@socket.eof?
|
28
|
+
end
|
29
|
+
|
24
30
|
def << data
|
25
31
|
write data
|
26
32
|
end
|
@@ -110,7 +116,6 @@ module Farcall
|
|
110
116
|
close_connection
|
111
117
|
@thread and @thread.join
|
112
118
|
@thread = nil
|
113
|
-
@in_close = false
|
114
119
|
end
|
115
120
|
end
|
116
121
|
|
@@ -118,7 +123,7 @@ module Farcall
|
|
118
123
|
|
119
124
|
def load_loop
|
120
125
|
buffer = ''
|
121
|
-
while
|
126
|
+
while !@input.eof?
|
122
127
|
buffer << @input.read(1)
|
123
128
|
if buffer[@dlength..-1] == @delimiter
|
124
129
|
on_data_received and on_data_received.call(JSON.parse(buffer[0...@dlength]))
|
@@ -130,6 +135,7 @@ module Farcall
|
|
130
135
|
rescue
|
131
136
|
if !@closing
|
132
137
|
STDERR.puts "Farcall::JsonTransport read loop failed: #{$!.class.name}: #$!"
|
138
|
+
STDERR.puts $!.backtrace.join("\n")
|
133
139
|
connection_aborted $!
|
134
140
|
else
|
135
141
|
close
|
data/lib/farcall/transport.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Farcall
|
3
2
|
|
4
3
|
# Generic error in Farcall library
|
@@ -35,6 +34,12 @@ module Farcall
|
|
35
34
|
case format
|
36
35
|
when :json
|
37
36
|
Farcall::JsonTransport.new **params
|
37
|
+
when :boss
|
38
|
+
if defined?(Farcall::BossTransport)
|
39
|
+
Farcall::BossTransport.new **params
|
40
|
+
else
|
41
|
+
raise Farcall::Error.new("add gem 'boss-protocol' to use boss transport")
|
42
|
+
end
|
38
43
|
else
|
39
44
|
raise Farcall::Error, "unknown format: #{format}"
|
40
45
|
end
|
data/lib/farcall/version.rb
CHANGED
data/spec/endpoint_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'stringio'
|
3
2
|
|
4
3
|
# The sample class that exports all its methods to the remote callers:
|
5
4
|
#
|
@@ -14,6 +13,7 @@ class TestProvider < Farcall::Provider
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
16
|
+
|
17
17
|
describe 'endpoint' do
|
18
18
|
include Farcall
|
19
19
|
|
@@ -41,12 +41,11 @@ describe 'endpoint' do
|
|
41
41
|
ib.split.should == ['Hello', 'world']
|
42
42
|
end
|
43
43
|
|
44
|
-
|
44
|
+
def check_protocol format
|
45
45
|
s1, s2 = Socket.pair(:UNIX, :STREAM, 0)
|
46
46
|
|
47
|
-
tp = TestProvider.new socket: s1, format:
|
48
|
-
i
|
49
|
-
|
47
|
+
tp = TestProvider.new socket: s1, format: format
|
48
|
+
i = Farcall::Interface.new socket: s2, format: format, provider: "Hello world"
|
50
49
|
|
51
50
|
expect(-> { i.foo() }).to raise_error Farcall::RemoteError
|
52
51
|
|
@@ -59,4 +58,12 @@ describe 'endpoint' do
|
|
59
58
|
tp.far_interface.split.should == ['Hello', 'world']
|
60
59
|
end
|
61
60
|
|
61
|
+
it 'should connect json via shortcut' do
|
62
|
+
check_protocol :json
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should connect boss via shortcut' do
|
66
|
+
check_protocol :boss
|
67
|
+
end
|
68
|
+
|
62
69
|
end
|
data/spec/rmi_spec.rb
ADDED
data/spec/transports_spec.rb
CHANGED
@@ -70,5 +70,29 @@ describe 'transports' do
|
|
70
70
|
results.should == [{ 'echo' => { 'foo' => 'bar' } }, { 'echo' => { 'one' => 2 } }]
|
71
71
|
end
|
72
72
|
|
73
|
+
it 'should run boss transport' do
|
74
|
+
s1, s2 = Socket.pair(:UNIX, :STREAM, 0)
|
75
|
+
|
76
|
+
j1 = Farcall::BossTransport.new socket: s1
|
77
|
+
j2 = Farcall::BossTransport.new socket: s2
|
78
|
+
|
79
|
+
j2.receive_data { |data|
|
80
|
+
j2.send_data({ echo: data })
|
81
|
+
}
|
82
|
+
|
83
|
+
results = []
|
84
|
+
j1.receive_data { |data|
|
85
|
+
results << data
|
86
|
+
}
|
87
|
+
|
88
|
+
j1.send_data({ foo: "bar" })
|
89
|
+
j1.send_data({ one: 2 })
|
90
|
+
sleep 0.01
|
91
|
+
j1.close
|
92
|
+
j2.close
|
93
|
+
|
94
|
+
results.should == [{ 'echo' => { 'foo' => 'bar' } }, { 'echo' => { 'one' => 2 } }]
|
95
|
+
end
|
96
|
+
|
73
97
|
|
74
98
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: farcall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sergeych
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: boss-protocol
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.4.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.4.1
|
55
69
|
description: |-
|
56
70
|
Can work with any transpot capable of conveing dictionaries (json, xml, bson, boss, yaml.
|
57
71
|
Incides some transports.
|
@@ -69,11 +83,13 @@ files:
|
|
69
83
|
- Rakefile
|
70
84
|
- farcall.gemspec
|
71
85
|
- lib/farcall.rb
|
86
|
+
- lib/farcall/boss_transport.rb
|
72
87
|
- lib/farcall/endpoint.rb
|
73
88
|
- lib/farcall/json_transport.rb
|
74
89
|
- lib/farcall/transport.rb
|
75
90
|
- lib/farcall/version.rb
|
76
91
|
- spec/endpoint_spec.rb
|
92
|
+
- spec/rmi_spec.rb
|
77
93
|
- spec/spec_helper.rb
|
78
94
|
- spec/transports_spec.rb
|
79
95
|
homepage: ''
|
@@ -102,5 +118,6 @@ specification_version: 4
|
|
102
118
|
summary: Simple, elegant and cross-platofrm RCP and RMI protocol
|
103
119
|
test_files:
|
104
120
|
- spec/endpoint_spec.rb
|
121
|
+
- spec/rmi_spec.rb
|
105
122
|
- spec/spec_helper.rb
|
106
123
|
- spec/transports_spec.rb
|