nitro 0.1.2
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.
- data/AUTHORS +8 -0
- data/ChangeLog +1546 -0
- data/LICENCE +32 -0
- data/README +278 -0
- data/RELEASES +7 -0
- data/Rakefile +79 -0
- data/bin/cluster.rb +219 -0
- data/doc/architecture.txt +28 -0
- data/doc/bugs.txt +7 -0
- data/doc/css.txt +20 -0
- data/doc/ideas.txt +120 -0
- data/doc/pg.txt +47 -0
- data/doc/svn.txt +82 -0
- data/doc/todo.txt +30 -0
- data/etc/new-project.rb +18 -0
- data/examples/simple/README +15 -0
- data/examples/simple/app.rb +31 -0
- data/examples/simple/conf/apache.conf +100 -0
- data/examples/simple/conf/config.rb +89 -0
- data/examples/simple/conf/debug-config.rb +53 -0
- data/examples/simple/conf/live-config.rb +48 -0
- data/examples/simple/conf/overrides.rb +9 -0
- data/examples/simple/conf/requires.rb +51 -0
- data/examples/simple/ctl +32 -0
- data/examples/simple/env.rb +33 -0
- data/examples/simple/install.rb +12 -0
- data/examples/simple/lib/articles/entities.rb +35 -0
- data/examples/simple/lib/articles/lc-en.rb +36 -0
- data/examples/simple/lib/articles/methods.rb +55 -0
- data/examples/simple/lib/articles/part.rb +58 -0
- data/examples/simple/logs/access_log +2 -0
- data/examples/simple/logs/apache.log +3 -0
- data/examples/simple/logs/app.log +1 -0
- data/examples/simple/logs/events.log +1 -0
- data/examples/simple/root/add-article.sx +15 -0
- data/examples/simple/root/article-form.ss +20 -0
- data/examples/simple/root/comments-form.ss +16 -0
- data/examples/simple/root/comments.si +30 -0
- data/examples/simple/root/index.sx +44 -0
- data/examples/simple/root/shader/shader.xsl +100 -0
- data/examples/simple/root/shader/style.css +9 -0
- data/examples/simple/root/view-article.sx +30 -0
- data/examples/tiny/app.rb +30 -0
- data/examples/tiny/conf/apache.conf +100 -0
- data/examples/tiny/conf/config.rb +67 -0
- data/examples/tiny/conf/requires.rb +40 -0
- data/examples/tiny/ctl +31 -0
- data/examples/tiny/logs/access_log +9 -0
- data/examples/tiny/logs/apache.log +9 -0
- data/examples/tiny/root/index.sx +35 -0
- data/lib/n/app/cluster.rb +219 -0
- data/lib/n/app/cookie.rb +86 -0
- data/lib/n/app/filters/autologin.rb +50 -0
- data/lib/n/app/fragment.rb +67 -0
- data/lib/n/app/handlers.rb +120 -0
- data/lib/n/app/handlers/code-handler.rb +184 -0
- data/lib/n/app/handlers/page-handler.rb +612 -0
- data/lib/n/app/request-part.rb +59 -0
- data/lib/n/app/request.rb +653 -0
- data/lib/n/app/script.rb +398 -0
- data/lib/n/app/server.rb +53 -0
- data/lib/n/app/session.rb +224 -0
- data/lib/n/app/user.rb +47 -0
- data/lib/n/app/webrick-servlet.rb +213 -0
- data/lib/n/app/webrick.rb +70 -0
- data/lib/n/application.rb +187 -0
- data/lib/n/config.rb +31 -0
- data/lib/n/db.rb +217 -0
- data/lib/n/db/README +232 -0
- data/lib/n/db/connection.rb +369 -0
- data/lib/n/db/make-release.sh +26 -0
- data/lib/n/db/managed.rb +235 -0
- data/lib/n/db/mixins.rb +282 -0
- data/lib/n/db/mysql.rb +342 -0
- data/lib/n/db/psql.rb +378 -0
- data/lib/n/db/tools.rb +110 -0
- data/lib/n/db/utils.rb +99 -0
- data/lib/n/events.rb +118 -0
- data/lib/n/l10n.rb +22 -0
- data/lib/n/logger.rb +33 -0
- data/lib/n/macros.rb +53 -0
- data/lib/n/mixins.rb +46 -0
- data/lib/n/parts.rb +154 -0
- data/lib/n/properties.rb +194 -0
- data/lib/n/server.rb +61 -0
- data/lib/n/server/PLAYBACK.txt +8 -0
- data/lib/n/server/RESEARCH.txt +13 -0
- data/lib/n/server/filter.rb +77 -0
- data/lib/n/shaders.rb +167 -0
- data/lib/n/sitemap.rb +188 -0
- data/lib/n/std.rb +69 -0
- data/lib/n/sync/clc.rb +108 -0
- data/lib/n/sync/handler.rb +221 -0
- data/lib/n/sync/server.rb +170 -0
- data/lib/n/tools/README +11 -0
- data/lib/n/ui/date-select.rb +74 -0
- data/lib/n/ui/pager.rb +187 -0
- data/lib/n/ui/popup.rb +45 -0
- data/lib/n/ui/select.rb +41 -0
- data/lib/n/ui/tabs.rb +34 -0
- data/lib/n/utils/array.rb +92 -0
- data/lib/n/utils/cache.rb +144 -0
- data/lib/n/utils/gfx.rb +108 -0
- data/lib/n/utils/hash.rb +148 -0
- data/lib/n/utils/html.rb +147 -0
- data/lib/n/utils/http.rb +98 -0
- data/lib/n/utils/mail.rb +28 -0
- data/lib/n/utils/number.rb +31 -0
- data/lib/n/utils/pool.rb +66 -0
- data/lib/n/utils/string.rb +297 -0
- data/lib/n/utils/template.rb +38 -0
- data/lib/n/utils/time.rb +91 -0
- data/lib/n/utils/uri.rb +193 -0
- data/lib/xsl/base.xsl +205 -0
- data/lib/xsl/ce.xsl +30 -0
- data/lib/xsl/localization.xsl +23 -0
- data/lib/xsl/xforms.xsl +26 -0
- data/test/run.rb +95 -0
- metadata +187 -0
data/LICENCE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
The BSD Licence
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2004, Navel Ltd. (http://www.navel.gr)
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are
|
|
8
|
+
met:
|
|
9
|
+
|
|
10
|
+
* Redistributions of source code must retain the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
documentation and/or other materials provided with the distribution.
|
|
16
|
+
|
|
17
|
+
* Neither the name of Navel nor the names of its contributors may be
|
|
18
|
+
used to endorse or promote products derived from this software
|
|
19
|
+
without specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
22
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
23
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
24
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
25
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
26
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
27
|
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
28
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
29
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
30
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
31
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
|
+
|
data/README
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
= Nitro
|
|
2
|
+
|
|
3
|
+
Nitro is an efficient, yet simple engine for developing professional Web
|
|
4
|
+
Applications using the Ruby language. Nitro aims to provide a robust
|
|
5
|
+
infrastructure for scalable web applications that can be distributed
|
|
6
|
+
over a server cluster. However, Nitro can also power simple web
|
|
7
|
+
applications for deployment on intranets or even personal computers.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
== Features
|
|
11
|
+
|
|
12
|
+
A short summary of the major features:
|
|
13
|
+
|
|
14
|
+
* XML server pages (.sx)
|
|
15
|
+
|
|
16
|
+
Nitro introduces a new format for server pages that combines the
|
|
17
|
+
power of embededed Ruby (like erb, eruby) with the xml compliance
|
|
18
|
+
of Amrita. Even though it is a 'Callback' style templating system
|
|
19
|
+
it is flexible enough to run as 'Pipeline' style system if the
|
|
20
|
+
developer prefers this mode of operation.
|
|
21
|
+
|
|
22
|
+
<?xml version="1.0"?>
|
|
23
|
+
|
|
24
|
+
<!-- example page -->
|
|
25
|
+
<html>
|
|
26
|
+
<?r
|
|
27
|
+
title = "Example"
|
|
28
|
+
version = request["version"]
|
|
29
|
+
?>
|
|
30
|
+
|
|
31
|
+
<h1>#{title}</h1>
|
|
32
|
+
|
|
33
|
+
<?r if version > 1 ?>
|
|
34
|
+
<b>Version:</b> #{version}
|
|
35
|
+
<?r end ?>
|
|
36
|
+
|
|
37
|
+
</html>
|
|
38
|
+
|
|
39
|
+
* Shaders, XSLT templates
|
|
40
|
+
|
|
41
|
+
Nitro promotes the usage of XSLT for web templates. The functional
|
|
42
|
+
nature of XSL is ideal for the Web. Moreover, the engine efficiently
|
|
43
|
+
precompiles the xsl transformation along with other transformations
|
|
44
|
+
(for example localization) essentially providing a computationally
|
|
45
|
+
free transformation step.
|
|
46
|
+
|
|
47
|
+
A shader integrates many XSLT templates and or CSS stylesheets
|
|
48
|
+
to encapsulate all styling/skinning requirements of a Web Application.
|
|
49
|
+
|
|
50
|
+
* Multi phase evaluation
|
|
51
|
+
|
|
52
|
+
Experimental, facilitates efficient HTTP1.1 caching.
|
|
53
|
+
|
|
54
|
+
* Fragment Synthesis
|
|
55
|
+
|
|
56
|
+
Nitro server pages can include fragments at 'Compile' time or at
|
|
57
|
+
'RunTime' time.
|
|
58
|
+
|
|
59
|
+
<!-- compile time include (static include) -->
|
|
60
|
+
<?include xl:href="myfile.si" />
|
|
61
|
+
|
|
62
|
+
<!-- run time include (dynamic include) -->
|
|
63
|
+
<x:include xl:href="myfile.si" />
|
|
64
|
+
|
|
65
|
+
* Object-Relational Mapping
|
|
66
|
+
|
|
67
|
+
Nitro integrates the NDB object-relational mapping library. NDB
|
|
68
|
+
provides transparent serialization of object graphs to a RDBMS
|
|
69
|
+
backend. Unlike other similar libraries NDB maps standard Ruby
|
|
70
|
+
objects to SQL tables and not vice versa. NDB provides a flexible
|
|
71
|
+
and intuitive api for querieng the database, raw access to the
|
|
72
|
+
SQL language if needed (for example to fine tune the automatically
|
|
73
|
+
generated SQL tables, or for custom queries), suports deserialization
|
|
74
|
+
to Ruby objects or tuples and provides a collection of usefull Mixins
|
|
75
|
+
to synthesize common Entities.
|
|
76
|
+
|
|
77
|
+
* Distributed State
|
|
78
|
+
|
|
79
|
+
Nitro provides a powerfull distributed state mechanism that utilizes
|
|
80
|
+
the DRb library. A typicall use of this infrastructure is to provide
|
|
81
|
+
distributed sessions when running your application over a server
|
|
82
|
+
cluster. Distributed sessions are fully transparent to the developer.
|
|
83
|
+
|
|
84
|
+
* Synchronous Server
|
|
85
|
+
|
|
86
|
+
An experimental synchronous server for implementing services like
|
|
87
|
+
Chat Rooms, Multiplayer Games, etc. Compatible with Macromedia Flash.
|
|
88
|
+
|
|
89
|
+
* Request Filters
|
|
90
|
+
|
|
91
|
+
The develpoper has full access to the request handling pipeline.
|
|
92
|
+
Request filters are a powerfull mechanism for customized processing
|
|
93
|
+
of special requests. Example filters are the autologin filter,
|
|
94
|
+
a gzip filter etc.
|
|
95
|
+
|
|
96
|
+
* Hierarchical Caching
|
|
97
|
+
|
|
98
|
+
Nitro provides a well designed and efficient caching mechanism. Caching
|
|
99
|
+
will be provided at the following levels:
|
|
100
|
+
|
|
101
|
+
* DB Cache
|
|
102
|
+
* Object Cache (deserialized objects)
|
|
103
|
+
* Fragment Caching (cache generated sub-parts of a page, or a page)
|
|
104
|
+
* HTTP 1.1 Caching (downstream caching of whole pages)
|
|
105
|
+
|
|
106
|
+
The engine calculates intra-page dependencies automatically. A variety
|
|
107
|
+
of invalidation strategies can be implemented.
|
|
108
|
+
|
|
109
|
+
* Support for 'nice' urls.
|
|
110
|
+
|
|
111
|
+
Experimental
|
|
112
|
+
|
|
113
|
+
* Advanced debuging features
|
|
114
|
+
|
|
115
|
+
* When running in debug mode, all exceptions raise are logged
|
|
116
|
+
to a special debug panel in the current page. Find out the offending
|
|
117
|
+
file and line from the exception dump, fix the bug, refresh the page.
|
|
118
|
+
|
|
119
|
+
* in-process console: inject an irb session to a running application
|
|
120
|
+
server. You can use the irb console to investigate all variables
|
|
121
|
+
and code in your running server process.
|
|
122
|
+
|
|
123
|
+
* Parts
|
|
124
|
+
|
|
125
|
+
Parts are organized modules of web services. A Web Framework that
|
|
126
|
+
integrates a large collection of parts (User management, Blog,
|
|
127
|
+
Fora, CMS, Personalization, ..) will be released by Navel.
|
|
128
|
+
|
|
129
|
+
Other libraries of parts are expected from the Ruby community when
|
|
130
|
+
the Part API is finalized.
|
|
131
|
+
|
|
132
|
+
* UI Components
|
|
133
|
+
|
|
134
|
+
Nitro is distributed with a collection of usefull UI components
|
|
135
|
+
to make form based application development easier (for example
|
|
136
|
+
an efficient, ndb-aware Pager component).
|
|
137
|
+
|
|
138
|
+
* Path overloading
|
|
139
|
+
|
|
140
|
+
Experimental
|
|
141
|
+
|
|
142
|
+
* Localization
|
|
143
|
+
|
|
144
|
+
Nitro supports efficient localization of web applications.
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
== Download
|
|
148
|
+
|
|
149
|
+
The latest version of Nitro can be found at
|
|
150
|
+
|
|
151
|
+
* http://www.navel.gr/nitro
|
|
152
|
+
|
|
153
|
+
Documentation for Nitro can be found at
|
|
154
|
+
|
|
155
|
+
* http://www.navel.gr/nitro/doc
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
== Requirements
|
|
159
|
+
|
|
160
|
+
Nitro requires the following applications or libraries:
|
|
161
|
+
|
|
162
|
+
* Ruby 1.8.1 and greater (http://www.ruby-lang.org)
|
|
163
|
+
Version 1.8.2.preview2 is recomended
|
|
164
|
+
|
|
165
|
+
* Apache 2.0 (http://www.apache.org)
|
|
166
|
+
Will be optional in a future version.
|
|
167
|
+
|
|
168
|
+
The following applications or libraries are optional:
|
|
169
|
+
|
|
170
|
+
* PostgreSQL (http://www.postgres.org)
|
|
171
|
+
Used for Database driven web applications
|
|
172
|
+
|
|
173
|
+
* Ruby-psql (http://www.postgresql.jp/interfaces/ruby/archive/ruby-postgres-0.7.1.tar.gz)
|
|
174
|
+
Ruby interface to the PostgreSQL RDBMS.
|
|
175
|
+
|
|
176
|
+
* Ruby-XSLT (http://gregoire.lejeune.free.fr/ruby-xslt_0.4.0.tar.gz)
|
|
177
|
+
Used for XSLT based templates.
|
|
178
|
+
|
|
179
|
+
Please install the required applications and libraries before continuing
|
|
180
|
+
with the installation of Nitro.
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
== Instalation
|
|
184
|
+
|
|
185
|
+
Nitro is distributed as a RubyGem. First of all make sure you have
|
|
186
|
+
installed RubyGems on your system. Then run the following command:
|
|
187
|
+
|
|
188
|
+
gem install nitro
|
|
189
|
+
|
|
190
|
+
Then try to run the examples/tiny Example application.
|
|
191
|
+
|
|
192
|
+
A tar.gz distribution is also available on http://www.navel.gr/nitro
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
== Running the example applications
|
|
196
|
+
|
|
197
|
+
* examples/tiny
|
|
198
|
+
|
|
199
|
+
A simple application that requires no external applications
|
|
200
|
+
|
|
201
|
+
$ cd nitro/examples/tiny
|
|
202
|
+
|
|
203
|
+
$ vi conf/apache.conf
|
|
204
|
+
|
|
205
|
+
edit user, group,DocumentRoot root as needed.
|
|
206
|
+
|
|
207
|
+
$ ./ctl start
|
|
208
|
+
|
|
209
|
+
this script starts the distributed session cluster, apache and the
|
|
210
|
+
application server.
|
|
211
|
+
|
|
212
|
+
browse http://127.0.0.1:8080
|
|
213
|
+
|
|
214
|
+
to stop the application execute:
|
|
215
|
+
|
|
216
|
+
$ ./ctl stop
|
|
217
|
+
|
|
218
|
+
* examples/simple
|
|
219
|
+
|
|
220
|
+
A simple application to demonstrate xsl skins, entities, postback.
|
|
221
|
+
|
|
222
|
+
$ cd nitro/examples/simple
|
|
223
|
+
|
|
224
|
+
$ vi conf/apache.conf
|
|
225
|
+
|
|
226
|
+
edit user, group,DocumentRoot root as needed.
|
|
227
|
+
|
|
228
|
+
$ vi conf/config.rb
|
|
229
|
+
|
|
230
|
+
edit the postgresql user and password
|
|
231
|
+
|
|
232
|
+
run the following script to initialize the postgresql database used by
|
|
233
|
+
the example
|
|
234
|
+
|
|
235
|
+
$ ruby install.rb
|
|
236
|
+
|
|
237
|
+
$ ./ctl start
|
|
238
|
+
|
|
239
|
+
this script starts the distributed session cluster, apache and the
|
|
240
|
+
application server.
|
|
241
|
+
|
|
242
|
+
browse http://127.0.0.1:8080
|
|
243
|
+
|
|
244
|
+
to attach an irb console to the running server, execute from
|
|
245
|
+
another shell:
|
|
246
|
+
|
|
247
|
+
$ cd /examples/simple
|
|
248
|
+
|
|
249
|
+
$ irb -r env.rb
|
|
250
|
+
|
|
251
|
+
to stop the application execute:
|
|
252
|
+
|
|
253
|
+
$ ./ctl stop
|
|
254
|
+
|
|
255
|
+
== Debuging Nitro applications
|
|
256
|
+
|
|
257
|
+
Have "tail -f" commands running on logs/app.log in your application
|
|
258
|
+
directory. Nitro will automatically display debugging and runtime
|
|
259
|
+
information to these files. Debugging info will also be shown in the
|
|
260
|
+
browser when running in debug mode.
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
== Support
|
|
264
|
+
|
|
265
|
+
For any questions regarding Nitro, feel free to ask on the ruby-talk
|
|
266
|
+
mailing list (which is mirrored to comp.lang.ruby) or contact
|
|
267
|
+
mailto:gm@navel.gr.
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
== Licence
|
|
271
|
+
|
|
272
|
+
Copyright (c) 2004 Navel Ltd (http://www.navel.gr)
|
|
273
|
+
|
|
274
|
+
Nitro (http://www.navel.gr/nitro) is copyrighted free software
|
|
275
|
+
created and maintained by George Moschovitis (mailto:gm@navel.gr)
|
|
276
|
+
and released under the standard BSD Licence. For details consult
|
|
277
|
+
the file LICENCE.
|
|
278
|
+
|
data/RELEASES
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
== Version 0.1.2 was released on 21/10/2004.
|
|
3
|
+
|
|
4
|
+
The first public version. Features 2 examples and limited
|
|
5
|
+
documentation. The aim of this release is to make the procect known
|
|
6
|
+
to the Ruby Community. We hope that the Ruby hackers will respond
|
|
7
|
+
with valueable suggestions and ideas.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# = Rakefile
|
|
2
|
+
#
|
|
3
|
+
# code:
|
|
4
|
+
# George Moschovitis <gm@navel.gr>
|
|
5
|
+
#
|
|
6
|
+
# (c) 2004 Navel, all rights reserved.
|
|
7
|
+
# $Id: connection.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
8
|
+
|
|
9
|
+
require "rake"
|
|
10
|
+
require "rake/rdoctask"
|
|
11
|
+
require "rubygems"
|
|
12
|
+
require "rake/gempackagetask"
|
|
13
|
+
|
|
14
|
+
require "lib/n/config"
|
|
15
|
+
|
|
16
|
+
# ----------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
desc "Default Task"
|
|
19
|
+
task :default => :package
|
|
20
|
+
|
|
21
|
+
# ----------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
desc "Run unit tests"
|
|
24
|
+
task :test do
|
|
25
|
+
# Might wait until I"ve got some...
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# ----------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
Rake::RDocTask.new do |rd|
|
|
31
|
+
rd.main = "README"
|
|
32
|
+
rd.rdoc_dir = "rdoc"
|
|
33
|
+
rd.rdoc_files.include("README", "lib/**/*.rb")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# ----------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
PKG_VERSION = $srv_version
|
|
39
|
+
PKG_FILES = FileList[
|
|
40
|
+
"[A-Z]*", "{bin,etc,examples,doc,lib,test}/**/*"
|
|
41
|
+
# "examples/*.rb"
|
|
42
|
+
].exclude(".svn/**/*")
|
|
43
|
+
|
|
44
|
+
spec = Gem::Specification.new do |s|
|
|
45
|
+
s.name = "nitro"
|
|
46
|
+
s.version = PKG_VERSION
|
|
47
|
+
s.summary = "Web Engine"
|
|
48
|
+
s.description = "An efficient, yet simple engine for Web Applications"
|
|
49
|
+
# s.add_dependency("extensions", ">= 0.5")
|
|
50
|
+
s.required_ruby_version = ">= 1.8.1"
|
|
51
|
+
s.files = PKG_FILES.to_a
|
|
52
|
+
s.require_path = "lib"
|
|
53
|
+
s.autorequire = "n/std"
|
|
54
|
+
s.has_rdoc = true
|
|
55
|
+
s.extra_rdoc_files = FileList["[A-Z]*"].to_a
|
|
56
|
+
s.rdoc_options << "--main" << "README" << "--title" <<
|
|
57
|
+
"Nitro Documentation"
|
|
58
|
+
s.test_files = []
|
|
59
|
+
s.bindir = "bin"
|
|
60
|
+
s.author = "George Moschovitis"
|
|
61
|
+
s.email = "gm@navel.gr"
|
|
62
|
+
s.homepage = "http://www.navel.gr/nitro"
|
|
63
|
+
s.rubyforge_project = "nitro"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
|
67
|
+
pkg.package_dir = "dist"
|
|
68
|
+
pkg.need_zip = true
|
|
69
|
+
pkg.need_tar = true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# ----------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
desc "Install the gem"
|
|
75
|
+
task :install => :repackage do
|
|
76
|
+
sh "gem install --local --no-rdoc dist/nitro-#{PKG_VERSION}.gem"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# vim: ft=ruby
|
data/bin/cluster.rb
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# = Cluster
|
|
2
|
+
#
|
|
3
|
+
# TODO: use Sync instead of Monitor
|
|
4
|
+
#
|
|
5
|
+
# code:: gmosx
|
|
6
|
+
#
|
|
7
|
+
# (c) 2004 Navel, all rights reserved.
|
|
8
|
+
# $Id: cluster.rb 74 2004-10-18 11:30:20Z gmosx $
|
|
9
|
+
|
|
10
|
+
$:.unshift "nitro/lib"
|
|
11
|
+
|
|
12
|
+
require "drb"
|
|
13
|
+
require "monitor"
|
|
14
|
+
|
|
15
|
+
require "n/application"
|
|
16
|
+
require "n/server"
|
|
17
|
+
require "n/utils/cache"
|
|
18
|
+
require "n/app/session"
|
|
19
|
+
|
|
20
|
+
module N
|
|
21
|
+
|
|
22
|
+
# = Cluster
|
|
23
|
+
#
|
|
24
|
+
# A Cluster is a collection of servers. The cluster synchronizes the
|
|
25
|
+
# servers and distributes the state. An older version used a polling
|
|
26
|
+
# system, ie: the servers polled the cluster to obtain the state. This
|
|
27
|
+
# version uses a push system, ie when the state is changed a delta
|
|
28
|
+
# is pushed to the clients.
|
|
29
|
+
#
|
|
30
|
+
class Cluster < N::Application
|
|
31
|
+
|
|
32
|
+
# = CHash ClusterHash
|
|
33
|
+
#
|
|
34
|
+
class CHash < Hash
|
|
35
|
+
attr :mon
|
|
36
|
+
|
|
37
|
+
# drbobject for this hash (local)
|
|
38
|
+
attr_accessor :ldrb
|
|
39
|
+
|
|
40
|
+
# the cluster, use a cluster to implement a set
|
|
41
|
+
# (one server per drb_uri)
|
|
42
|
+
attr_accessor :cluster
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
#
|
|
46
|
+
def initialize(ldrb_uri = "druby://:8000")
|
|
47
|
+
@mon = Monitor.new
|
|
48
|
+
@ldrb = DRb.start_service(ldrb_uri, self)
|
|
49
|
+
@cluster = {}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
#
|
|
54
|
+
def join(sdrb_uri)
|
|
55
|
+
@mon.synchronize {
|
|
56
|
+
cluster[sdrb_uri] = DRbObject.new(nil, sdrb_uri)
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
alias_method :old_set, :[]=
|
|
61
|
+
|
|
62
|
+
# Not really usefull
|
|
63
|
+
#
|
|
64
|
+
def []=(key, value)
|
|
65
|
+
# store the value (useful on server restarts)
|
|
66
|
+
@mon.synchronize {
|
|
67
|
+
old_set(key, value)
|
|
68
|
+
|
|
69
|
+
puts "CLUSTER #{key} = #{value}"
|
|
70
|
+
|
|
71
|
+
cluster.each { |uri, sdrb|
|
|
72
|
+
begin
|
|
73
|
+
sdrb.server_sync(key, value)
|
|
74
|
+
rescue => ex
|
|
75
|
+
$log.error "Server at #{uri} is down, removing from cluster"
|
|
76
|
+
cluster.delete(uri)
|
|
77
|
+
end
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Use this, avoids syncing the original server, and avoids a
|
|
83
|
+
# nasty deadlock.
|
|
84
|
+
#
|
|
85
|
+
def cluster_sync(key, value, server_uri)
|
|
86
|
+
# store the value (useful on server restarts)
|
|
87
|
+
@mon.synchronize {
|
|
88
|
+
old_set(key, value)
|
|
89
|
+
|
|
90
|
+
puts "CLUSTER #{key} = #{value}"
|
|
91
|
+
|
|
92
|
+
cluster.each { |uri, sdrb|
|
|
93
|
+
begin
|
|
94
|
+
sdrb.server_sync(key, value) unless uri == server_uri
|
|
95
|
+
rescue => ex
|
|
96
|
+
$log.error "Server at #{uri} is down, removing from cluster"
|
|
97
|
+
cluster.delete(uri)
|
|
98
|
+
end
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def [](key)
|
|
104
|
+
@mon.synchronize {
|
|
105
|
+
puts "LOOKUP #{key}"
|
|
106
|
+
return super
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# = SHash ServerHash
|
|
113
|
+
#
|
|
114
|
+
class SHash < Hash
|
|
115
|
+
attr :mon
|
|
116
|
+
|
|
117
|
+
# drbobject for this hash (local)
|
|
118
|
+
attr_accessor :ldrb
|
|
119
|
+
|
|
120
|
+
# drb for the cluster hash
|
|
121
|
+
attr_accessor :cdrb
|
|
122
|
+
|
|
123
|
+
# ldrb = local drb uri
|
|
124
|
+
# cdrb = cluster drb uri
|
|
125
|
+
#
|
|
126
|
+
def initialize(ldrb_uri = "druby://:9000", cdrb_uri = "druby://:8000")
|
|
127
|
+
@mon = Monitor.new
|
|
128
|
+
@ldrb_uri = ldrb_uri
|
|
129
|
+
@ldrb = DRb.start_service(ldrb_uri, self)
|
|
130
|
+
@cdrb = DRbObject.new(nil, cdrb_uri)
|
|
131
|
+
@cdrb.join(ldrb_uri)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
alias_method :old_set, :[]=
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
#
|
|
138
|
+
def []=(key, value)
|
|
139
|
+
# store the value in the local hash
|
|
140
|
+
@mon.synchronize {
|
|
141
|
+
puts "LOCAL #{key} = #{value}"
|
|
142
|
+
old_set(key, value)
|
|
143
|
+
@cdrb.cluster_sync(key, value, @ldrb_uri)
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# If the key is not found in the local hash, try the
|
|
148
|
+
# cluster hash.
|
|
149
|
+
#
|
|
150
|
+
def [](key)
|
|
151
|
+
@mon.synchronize {
|
|
152
|
+
unless value = super
|
|
153
|
+
value = @cdrb[key]
|
|
154
|
+
old_set(key, value)
|
|
155
|
+
end
|
|
156
|
+
return value
|
|
157
|
+
}
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Called by the cluster
|
|
161
|
+
#
|
|
162
|
+
def server_sync(key, value)
|
|
163
|
+
puts "SYNC #{key} = #{value}"
|
|
164
|
+
@mon.synchronize {
|
|
165
|
+
old_set(key, value)
|
|
166
|
+
}
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# = Clm Cluster Last Modified Hash
|
|
172
|
+
#
|
|
173
|
+
class Clm < CHash
|
|
174
|
+
def [](key)
|
|
175
|
+
@mon.synchronize {
|
|
176
|
+
unless value = super
|
|
177
|
+
puts "INIT #{key}"
|
|
178
|
+
value = Time.now.to_i
|
|
179
|
+
old_set(key, value)
|
|
180
|
+
end
|
|
181
|
+
return value
|
|
182
|
+
}
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# = Slm Server Last Modified Hash
|
|
187
|
+
#
|
|
188
|
+
class Slm < SHash
|
|
189
|
+
def set!(key, lm = nil)
|
|
190
|
+
lm = Time.now.to_i unless lm
|
|
191
|
+
self[key] = lm
|
|
192
|
+
return lm
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def initialize(name = "Cluster")
|
|
197
|
+
super
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def run
|
|
201
|
+
N::Cluster::Clm.new
|
|
202
|
+
DRb.start_service("druby://:8001", N::App::SessionManager.new)
|
|
203
|
+
|
|
204
|
+
while true
|
|
205
|
+
sleep(5000)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
super
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
end # module
|
|
214
|
+
|
|
215
|
+
if $0 == __FILE__
|
|
216
|
+
require "logger"; $log = Logger.new(STDERR)
|
|
217
|
+
|
|
218
|
+
N::Cluster.new.exec()
|
|
219
|
+
end
|