redisrpc 0.3.3

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