redisrpc 0.3.3

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.
Files changed (2) hide show
  1. data/lib/redisrpc.rb +128 -0
  2. metadata +90 -0
data/lib/redisrpc.rb ADDED
@@ -0,0 +1,128 @@
1
+ # Copyright (C) 2012. Nathan Farrington <nfarring@gmail.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'json'
17
+
18
+ require 'redis'
19
+
20
+ module RedisRPC
21
+
22
+
23
+ class RemoteException<Exception
24
+ end
25
+
26
+
27
+ class FunctionCall
28
+
29
+ def initialize(args={})
30
+ @name = args['name']
31
+ @args = args['args']
32
+ end
33
+
34
+ def as_ruby_code
35
+ argstring = ''
36
+ if @args != nil
37
+ argstring += ' '
38
+ argstring += @args.join ','
39
+ end
40
+ return @name + argstring
41
+ end
42
+
43
+ end
44
+
45
+
46
+ class Client
47
+
48
+ def initialize(redis_server, input_queue)
49
+ @redis_server = redis_server
50
+ @input_queue = input_queue
51
+ end
52
+
53
+ def method_missing(sym, *args, &block)
54
+ function_call = {'name' => sym.to_s, 'args' => args}
55
+ response_queue = @input_queue + ':rpc:' + rand_string
56
+ rpc_request = {'function_call' => function_call, 'response_queue' => response_queue}
57
+ message = JSON.generate rpc_request
58
+ if $DEBUG
59
+ $stderr.puts 'RPC Request: ' + message
60
+ end
61
+ @redis_server.rpush @input_queue, message
62
+ timeout_s = 0 # Block forever.
63
+ message_queue, message = @redis_server.blpop response_queue, timeout_s
64
+ if $DEBUG
65
+ if message_queue != response_queue
66
+ fail 'assertion failed'
67
+ end
68
+ $stderr.puts 'RPC Response: ' + message
69
+ end
70
+ rpc_response = JSON.parse message
71
+ exception = rpc_response['exception']
72
+ if exception != nil
73
+ raise RemoteException, exception
74
+ end
75
+ if not rpc_response.has_key? 'return_value'
76
+ raise RemoteException, 'Malformed RPC Response message: ' + rpc_response
77
+ end
78
+ return rpc_response['return_value']
79
+ end
80
+
81
+ def rand_string(size=8, charset=%w{ 1 2 3 4 5 6 7 8 9 0 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z})
82
+ return (0...size).map{ charset.to_a[rand(charset.size)] }.join
83
+ end
84
+
85
+ def respond_to?(sym)
86
+ return true
87
+ end
88
+
89
+ end
90
+
91
+
92
+ class Server
93
+
94
+ def initialize(redis_server, input_queue, local_object)
95
+ @redis_server = redis_server
96
+ @input_queue = input_queue
97
+ @local_object = local_object
98
+ end
99
+
100
+ def run
101
+ loop do
102
+ message_queue, message = @redis_server.blpop @input_queue, 0
103
+ if $DEBUG
104
+ fail 'assertion failed' if message_queue != @input_queue
105
+ $stderr.puts 'RPC Request: ' + message
106
+ end
107
+ rpc_request = JSON.parse(message)
108
+ response_queue = rpc_request['response_queue']
109
+ function_call = FunctionCall.new(rpc_request['function_call'])
110
+ code = '@local_object.' + function_call.as_ruby_code
111
+ begin
112
+ return_value = eval code
113
+ rpc_response = {'return_value' => return_value}
114
+ rescue => err
115
+ rpc_response = {'exception' => err}
116
+ end
117
+ message = JSON.generate rpc_response
118
+ if $DEBUG
119
+ $stderr.puts 'RPC Response: ' + message
120
+ end
121
+ @redis_server.rpush response_queue, message
122
+ end
123
+ end
124
+
125
+ end
126
+
127
+
128
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redisrpc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Farrington
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redis
16
+ requirement: &2151871000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - <
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2151871000
25
+ description: ! 'RedisRPC is the easiest to use RPC library in the world. (No small
26
+ claim!) It
27
+
28
+ has implementations in Ruby, PHP, and Python.
29
+
30
+
31
+ Redis is a powerful in-memory data structure server that is useful for building
32
+
33
+ fast distributed systems. Redis implements message queue functionality with its
34
+
35
+ use of list data structures and the `LPOP`, `BLPOP`, and `RPUSH` commands.
36
+
37
+ RedisRPC implements a lightweight RPC mechanism using Redis message queues to
38
+
39
+ temporarily hold RPC request and response messages. These messages are encoded
40
+
41
+ as JSON strings for portability.
42
+
43
+
44
+ Many other RPC mechanisms are either programming language specific (e.g.
45
+
46
+ JavaRMI or require boiler-plate code for explicit typing (e.g. Thrift).
47
+
48
+ RedisRPC was designed to be extremely easy to use by eliminating boiler-plate
49
+
50
+ code while also being programming language neutral. High performance was not
51
+
52
+ an initial goal of RedisRPC and other RPC libraries are likely to have better
53
+
54
+ performance. Instead, RedisRPC has better programmer performance; it lets you
55
+
56
+ get something working immediately.
57
+
58
+ '
59
+ email: nfarring@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - lib/redisrpc.rb
65
+ homepage: http://github.com/nfarring/redisrpc
66
+ licenses:
67
+ - GPLv3
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.15
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Lightweight RPC for Redis
90
+ test_files: []