marilyn-rpc 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/LICENCE +18 -0
  2. data/README.md +170 -0
  3. data/doc/MarilynRPC/CallRequestMail.html +578 -0
  4. data/doc/MarilynRPC/CallResponseMail.html +418 -0
  5. data/doc/MarilynRPC/Envelope.html +705 -0
  6. data/doc/MarilynRPC/ExceptionMail.html +338 -0
  7. data/doc/MarilynRPC/Gentleman.html +658 -0
  8. data/doc/MarilynRPC/MailFactory.html +284 -0
  9. data/doc/MarilynRPC/MailHelper.html +489 -0
  10. data/doc/MarilynRPC/NativeClient.html +579 -0
  11. data/doc/MarilynRPC/NativeClientProxy.html +303 -0
  12. data/doc/MarilynRPC/Server.html +406 -0
  13. data/doc/MarilynRPC/Service.html +599 -0
  14. data/doc/MarilynRPC/ServiceCache.html +481 -0
  15. data/doc/MarilynRPC.html +108 -0
  16. data/doc/_index.html +219 -0
  17. data/doc/class_list.html +36 -0
  18. data/doc/css/common.css +1 -0
  19. data/doc/css/full_list.css +53 -0
  20. data/doc/css/style.css +318 -0
  21. data/doc/file.README.html +154 -0
  22. data/doc/file_list.html +38 -0
  23. data/doc/frames.html +13 -0
  24. data/doc/index.html +154 -0
  25. data/doc/js/app.js +203 -0
  26. data/doc/js/full_list.js +149 -0
  27. data/doc/js/jquery.js +16 -0
  28. data/doc/method_list.html +467 -0
  29. data/doc/top-level-namespace.html +88 -0
  30. data/examples/async/client.rb +40 -0
  31. data/examples/async/server.rb +26 -0
  32. data/examples/callbacks/client.rb +8 -0
  33. data/examples/callbacks/server.rb +26 -0
  34. data/examples/secure/client.rb +9 -0
  35. data/examples/secure/server.rb +22 -0
  36. data/kiss.png +0 -0
  37. data/lib/marilyn-rpc/client.rb +91 -26
  38. data/lib/marilyn-rpc/gentleman.rb +4 -1
  39. data/lib/marilyn-rpc/mails.rb +1 -1
  40. data/lib/marilyn-rpc/server.rb +27 -3
  41. data/lib/marilyn-rpc/service.rb +64 -0
  42. data/lib/marilyn-rpc/service_cache.rb +13 -2
  43. data/lib/marilyn-rpc/version.rb +1 -1
  44. metadata +39 -3
data/LICENCE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2011 Vincent Landgraf
2
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
3
+ this software and associated documentation files (the "Software"), to deal in
4
+ the Software without restriction, including without limitation the rights to
5
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
6
+ the Software, and to permit persons to whom the Software is furnished to do so,
7
+ subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all
10
+ copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ ![alt text](https://raw.github.com/threez/marilyn-rpc/master/kiss.png "MarilynRPC")
2
+
3
+ # MarilynRPC
4
+
5
+ Marilyn is a simple, elegant rpc service and client infrastructure that has
6
+ learned some lessons on how we organize our code in typical web projects like
7
+ rails. It's purpose is to call multiple services over a persistent connection.
8
+ The services are unique per connection, so if you have 50 connections, 50
9
+ service objects will be used, if (and only if) they are requested by the client.
10
+
11
+ Since this is a session dedicated to one connection, marilyn has support for per
12
+ connection caching by using instance variables. Further on, it is planned to
13
+ enhance the capabilities of marilyn to allow connection based authentication.
14
+ Like in other protocols (e.g. IMAP) where some methods can be called
15
+ unauthenticated and some not.
16
+
17
+ Like in IMAP marilyn supports sending of multiple requests to a server over one
18
+ connection. This feature is called multiplexing supported by the current
19
+ `NativeClient` implementation.
20
+
21
+ The services rely on the eventmachine reactor. Marilyn supports asynchronous
22
+ responses based on the so called `Gentleman`. This class is a proxy object that
23
+ will handle the async responses for you.
24
+
25
+ Due to it's internals marilyn is very fast. On my local machine i can achieve
26
+ about 5000 (req + resp)/s.
27
+
28
+ Serialization of all data is done using ruby's build in `Marshal#dump` and `#load`. Since it was the fastest solution i found for typical scenarios.
29
+
30
+ It is especially designed for local connections too and therefore build to run
31
+ on both tcp and unix domain socket connections. Due to it's implementation in
32
+ operation systems is a unix domain socket typically faster than a tcp localhost
33
+ connection. I my tests up to 30 percent faster.
34
+
35
+ ## Install
36
+
37
+ Easy and common using gems:
38
+
39
+ gem install marilynrpc
40
+
41
+ ## Server Example
42
+
43
+ This is a sample server that exposes 2 Services that can be easily exposed using
44
+ the eventmachine `start_server` function:
45
+
46
+ require "marilyn-rpc"
47
+ require "eventmachine"
48
+
49
+ class CalcService < MarilynRPC::Service
50
+ register :calc
51
+
52
+ def add(a, b)
53
+ a + b
54
+ end
55
+ end
56
+
57
+ class TimeService < MarilynRPC::Service
58
+ register :time
59
+
60
+ def current
61
+ Time.now
62
+ end
63
+ end
64
+
65
+ EM.run {
66
+ EM.start_server "localhost", 8483, MarilynRPC::Server
67
+ }
68
+
69
+ ## NativeClient Example (pure ruby)
70
+
71
+ The native client is a pure ruby implementation and dosn't require eventmachine
72
+ at all. Therefor it is very easy to use. However the downside is, that the
73
+ client is blocking for the call. But, since marilyn calls last only for
74
+ fractions of a millisecond (on a local connection) there should be no problem in
75
+ typical setups.
76
+
77
+ require "marilyn-rpc"
78
+
79
+ client = MarilynRPC::NativeClient.connect_tcp('localhost', 8483)
80
+ CalcService = client.for(:calc)
81
+ TimeService = client.for(:time)
82
+
83
+ p CalcService.add(1, 2)
84
+ p TimeService.current
85
+
86
+ client.disconnect
87
+
88
+ ## Service Events
89
+
90
+ Because a client has a dedicated service it is possible to add connect and
91
+ disconnect callbacks. These callbacks may help your application to
92
+ request/cache/optimize certain aspects of your service. Here is an example:
93
+
94
+ class EventsService < MarilynRPC::Service
95
+ register :events
96
+ after_connect :connected
97
+ after_disconnect :disconnected
98
+
99
+ def connected
100
+ puts "client connected"
101
+ end
102
+
103
+ def notify(msg)
104
+ puts msg
105
+ end
106
+
107
+ def disconnected
108
+ puts "client disconnected"
109
+ end
110
+ end
111
+
112
+ ## Security
113
+
114
+ If you are using a tcp connection you can secure the connection using tls/ssl.
115
+ To enable it on the server side one has to pass the secure flag:
116
+
117
+ EM.run {
118
+ EM.start_server("localhost", 8008, MarilynRPC::Server, :secure => true)
119
+ }
120
+
121
+ The client also simply has to enable a secure connection:
122
+
123
+ client = MarilynRPC::NativeClient.connect_tcp('localhost', 8008, :secure => true)
124
+
125
+ ## Async Server Example & NativeClient
126
+
127
+ As previously said, the server can use the `Gentleman` to issue asynchronous
128
+ responses:
129
+
130
+ class SimpleCommandService < MarilynRPC::Service
131
+ register :cmd
132
+
133
+ def exec(line)
134
+ MarilynRPC::Gentleman.proxy do |helper|
135
+ EM.system(line, &helper)
136
+
137
+ lambda do |output,status|
138
+ if (code = status.exitstatus) == 0
139
+ output
140
+ else
141
+ code
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ The asynchronous server is transparent to the client. The client, doen't even
149
+ know, that his request is processed asynchronously. If the client make use of
150
+ the multiplexing feature he can use multiple threads to do so:
151
+
152
+ client = MarilynRPC::NativeClient.connect_tcp('localhost', 8000)
153
+ SimpleCommandService = client.for(:cmd)
154
+
155
+ start_time = Time.now
156
+
157
+ Thread.new do
158
+ SimpleCommandService.exec("sleep 5")
159
+ puts "=== ls -al\n: " + SimpleCommandService.exec("ls -al")
160
+ end
161
+
162
+ Thread.new do
163
+ SimpleCommandService.exec("sleep 2")
164
+ puts "=== uname -a\n: " + SimpleCommandService.exec("uname -a")
165
+ end
166
+
167
+ ## License / Author
168
+
169
+ Copyright (c) 2011 Vincent Landgraf
170
+ All Rights Reserved. Released under a [MIT License](LICENCE).