ia-redis-rpc 2.0.0.pre.dev
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 +7 -0
- data/.gitignore +19 -0
- data/CHANGELOG.markdown +79 -0
- data/Gemfile +3 -0
- data/LICENSE +674 -0
- data/README.markdown +164 -0
- data/Rakefile +7 -0
- data/VERSION +1 -0
- data/build-and-publish.sh +2 -0
- data/docs/github-flavored-markdown.rb +65 -0
- data/docs/redisrpc_example.ai +1075 -1
- data/docs/redisrpc_example.png +0 -0
- data/docs/redisrpc_example.svg +329 -0
- data/examples/calc.rb +32 -0
- data/examples/client.rb +39 -0
- data/examples/server.rb +12 -0
- data/lib/redis-rpc/version.rb +3 -0
- data/lib/redis-rpc.rb +204 -0
- data/redis-rpc.gemspec +44 -0
- data/spec/calculator_spec.rb +62 -0
- data/spec/client_spec.rb +26 -0
- data/spec/kwargs_spec.rb +32 -0
- data/spec/redis-test.conf +3 -0
- data/spec/server_spec.rb +18 -0
- data/spec/spec_helper.rb +53 -0
- metadata +161 -0
data/README.markdown
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
RedisRpc
|
2
|
+
========
|
3
|
+
|
4
|
+
originated by Nathan Farrington
|
5
|
+
<http://nathanfarrington.com>
|
6
|
+
|
7
|
+
RedisRpc is the easiest to use RPC library in the world. (No small claim!).
|
8
|
+
|
9
|
+
repackaged by Phuong Nguyen
|
10
|
+
This repo only has Ruby implementations
|
11
|
+
|
12
|
+
Introduction
|
13
|
+
------------
|
14
|
+
|
15
|
+
[Redis][Redis] is a powerful in-memory data structure server that is useful
|
16
|
+
for building fast distributed systems. Redis implements message queue
|
17
|
+
functionality with its use of list data structures and the `LPOP`, `BLPOP`,
|
18
|
+
and `RPUSH` commands. RedisRpc implements a lightweight RPC mechanism using
|
19
|
+
Redis message queues to temporarily hold RPC request and response
|
20
|
+
messages. These messages are encoded as [JSON][JSON] strings for portability.
|
21
|
+
|
22
|
+
Many other RPC mechanisms are either programming language specific (e.g. [Java
|
23
|
+
RMI][JavaRMI]) or require boiler-plate code for explicit typing (e.g.
|
24
|
+
[Thrift][Thrift]). RedisRpc was designed to be extremely easy to use by
|
25
|
+
eliminating boiler-plate code while also being programming language neutral.
|
26
|
+
High performance was not an initial goal of RedisRpc and other RPC libraries
|
27
|
+
are likely to have better performance. Instead, RedisRpc has better programmer
|
28
|
+
performance; it lets you get something working immediately.
|
29
|
+
|
30
|
+
Calculator Example
|
31
|
+
------------------
|
32
|
+
Each library implementation uses the same client and server example based off
|
33
|
+
of a mutable calculator object. The clients and servers from different
|
34
|
+
languages are interoperable.
|
35
|
+
|
36
|
+
<img
|
37
|
+
src="https://github.com/phuongnd08/redis-rpc-ruby/raw/master/docs/redisrpc_example.png"
|
38
|
+
width=438 height=238>
|
39
|
+
|
40
|
+
1. The client issues an RPC Request by using the Redis `RPUSH` command to push
|
41
|
+
an RPC Request message into a Redis list called `calc`.
|
42
|
+
2. The server retrieves the RPC Request message by using the Redis `BLPOP`
|
43
|
+
command.
|
44
|
+
3. The server dispatches the RPC Request to a local object, which in this case
|
45
|
+
is a Calculator object.
|
46
|
+
4. The server accepts the return value (or exception) from the Calculator object.
|
47
|
+
5. The server issues an RPC Response by using the Redis `RPUSH` command to push
|
48
|
+
an RPC Response message into a Redis list called `calc:rpc:<RAND_STRING>`,
|
49
|
+
which was chosen by the client.
|
50
|
+
6. The client retrieves the RPC Response message by using the Redis `BLPOP`
|
51
|
+
command.
|
52
|
+
|
53
|
+
*Note that the server or client can be made non-blocking by using the Redis
|
54
|
+
LPOP command instead of BLPOP. I currently do not need this feature and have
|
55
|
+
not added support for this, but patches are welcome.*
|
56
|
+
|
57
|
+
That's all there is to it!
|
58
|
+
|
59
|
+
Ruby Usage
|
60
|
+
----------
|
61
|
+
|
62
|
+
### client.rb
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
redis_server = Redis.new
|
66
|
+
message_queue = 'calc'
|
67
|
+
calculator = RedisRpc::Client.new redis_server, 'calc'
|
68
|
+
calculator.clr
|
69
|
+
calculator.add 5
|
70
|
+
calculator.sub 3
|
71
|
+
calculator.mul 4
|
72
|
+
calculator.div 2
|
73
|
+
assert calculator.val == 4
|
74
|
+
```
|
75
|
+
|
76
|
+
### server.rb
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
redis_server = Redis.new
|
80
|
+
message_queue = 'calc'
|
81
|
+
local_object = Calculator.new
|
82
|
+
server = RedisRpc::Server.new redis_server, message_queue, local_object
|
83
|
+
server.run
|
84
|
+
```
|
85
|
+
|
86
|
+
Installation
|
87
|
+
------------
|
88
|
+
|
89
|
+
### Ruby Installation
|
90
|
+
|
91
|
+
The [redis-rb][redis-rb] library is required. Install using RubyGems:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
gem install redis-rpc
|
95
|
+
```
|
96
|
+
|
97
|
+
Internal Message Formats
|
98
|
+
------------------------
|
99
|
+
All RPC messages are JSON objects. User code will never see these objects
|
100
|
+
because they are handled by the RedisRpc library.
|
101
|
+
|
102
|
+
### RPC Request
|
103
|
+
An RPC Request contains two members: a `function_call` object and
|
104
|
+
a `response_queue` string.
|
105
|
+
|
106
|
+
A `function_call` object has one required member: a `name` string for the function
|
107
|
+
name. It also has two optional members: (a) an `args` list for positional
|
108
|
+
function arguments, and (b) a `kwargs` object for named function arguments.
|
109
|
+
|
110
|
+
The `response_queue` string is the name of the Redis list where the
|
111
|
+
corresponding RPC Response message should be pushed by the server. This queue
|
112
|
+
is chosen programmatically by the client to be collision free in the Redis
|
113
|
+
namespace. Also, this queue is used only for a single RPC Response message
|
114
|
+
and is not reused for future RPC Response messages.
|
115
|
+
|
116
|
+
```javascript
|
117
|
+
{ "function_call" : {
|
118
|
+
"args" : [ 1, 2, 3 ],
|
119
|
+
"kwargs" : { "a" : 4, "b" : 5, "c" : 6 },
|
120
|
+
"name" : "foo"
|
121
|
+
},
|
122
|
+
"response_queue" : "calc:rpc:X7Y2US"
|
123
|
+
}
|
124
|
+
```
|
125
|
+
|
126
|
+
### RPC Response (Successful)
|
127
|
+
If an RPC is successful, then the RPC Response object will contain a single
|
128
|
+
member, a `return_value` of some JSON type.
|
129
|
+
|
130
|
+
```javascript
|
131
|
+
{ "return_value" : 4.0 }
|
132
|
+
```
|
133
|
+
|
134
|
+
### RPC Response (Exception)
|
135
|
+
If an RPC encounters an exceptional condition, then the RPC Response object
|
136
|
+
will contain a single member, an `exception` string. Note that the value of
|
137
|
+
the `exception` string might not have any meaning to the client since the
|
138
|
+
client and server might be written in different languages or the client
|
139
|
+
might have no knowledge of the server's wrapped object. Therefore the best
|
140
|
+
course of action is probably to display the `exception` value to the user.
|
141
|
+
|
142
|
+
```javascript
|
143
|
+
{ "exception" : "AttributeError(\\"\'Calculator\' object has no attribute \'foo\'\\",)" }
|
144
|
+
```
|
145
|
+
|
146
|
+
Source Code
|
147
|
+
-----------
|
148
|
+
Source code is available at <http://github.com/phuongnd08/redis-rpc-ruby>.
|
149
|
+
|
150
|
+
License
|
151
|
+
-------
|
152
|
+
This software is available under the [GPLv3][GPLv3] or later.
|
153
|
+
|
154
|
+
[Redis]: http://redis.io/
|
155
|
+
|
156
|
+
[JSON]: http://json.org/
|
157
|
+
|
158
|
+
[JavaRMI]: https://en.wikipedia.org/wiki/Java_remote_method_invocation
|
159
|
+
|
160
|
+
[Thrift]: https://en.wikipedia.org/wiki/Apache_Thrift
|
161
|
+
|
162
|
+
[redis-rb]: https://github.com/ezmobius/redis-rb
|
163
|
+
|
164
|
+
[GPLv3]: http://www.gnu.org/licenses/gpl.html
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.6rc4
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# @author Aaron Lampros
|
3
|
+
#
|
4
|
+
# Github-flavored markdown to HTML, in a command-line util.
|
5
|
+
#
|
6
|
+
# $ cat README.md | ./github-flavored-markdown.rb
|
7
|
+
#
|
8
|
+
# Notes:
|
9
|
+
# You will need to install Pygments for syntax coloring
|
10
|
+
# ```bash
|
11
|
+
# $ sudo easy_install pygments
|
12
|
+
# ```
|
13
|
+
#
|
14
|
+
# Install the gems `redcarpet` and `Pygments`
|
15
|
+
#
|
16
|
+
#
|
17
|
+
require 'rubygems'
|
18
|
+
require 'redcarpet'
|
19
|
+
require 'pygments.rb'
|
20
|
+
|
21
|
+
# puts Pygments.styles()
|
22
|
+
# monokai
|
23
|
+
# manni
|
24
|
+
# perldoc
|
25
|
+
# borland
|
26
|
+
# colorful
|
27
|
+
# default
|
28
|
+
# murphy
|
29
|
+
# vs
|
30
|
+
# trac
|
31
|
+
# tango
|
32
|
+
# fruity
|
33
|
+
# autumn
|
34
|
+
# bw
|
35
|
+
# emacs
|
36
|
+
# vim
|
37
|
+
# pastie
|
38
|
+
# friendly
|
39
|
+
# native
|
40
|
+
class HTMLwithPygments < Redcarpet::Render::XHTML
|
41
|
+
# def doc_header()
|
42
|
+
# '<style>' + Pygments.css('.highlight',:style => 'default') + '</style>'
|
43
|
+
# end
|
44
|
+
# def block_code(code, language)
|
45
|
+
# Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'})
|
46
|
+
# end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def fromMarkdown(text)
|
51
|
+
# options = [:fenced_code => true, :generate_toc => true, :hard_wrap => true, :no_intraemphasis => true, :strikethrough => true ,:gh_blockcode => true, :autolink => true, :xhtml => true, :tables => true]
|
52
|
+
markdown = Redcarpet::Markdown.new(HTMLwithPygments,
|
53
|
+
:fenced_code_blocks => true,
|
54
|
+
:no_intra_emphasis => true,
|
55
|
+
:autolink => true,
|
56
|
+
:strikethrough => true,
|
57
|
+
:lax_html_blocks => true,
|
58
|
+
:superscript => true,
|
59
|
+
:hard_wrap => true,
|
60
|
+
:tables => true,
|
61
|
+
:xhtml => true)
|
62
|
+
markdown.render(text)
|
63
|
+
end
|
64
|
+
|
65
|
+
puts fromMarkdown(ARGF.read)
|