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.
Files changed (119) hide show
  1. data/AUTHORS +8 -0
  2. data/ChangeLog +1546 -0
  3. data/LICENCE +32 -0
  4. data/README +278 -0
  5. data/RELEASES +7 -0
  6. data/Rakefile +79 -0
  7. data/bin/cluster.rb +219 -0
  8. data/doc/architecture.txt +28 -0
  9. data/doc/bugs.txt +7 -0
  10. data/doc/css.txt +20 -0
  11. data/doc/ideas.txt +120 -0
  12. data/doc/pg.txt +47 -0
  13. data/doc/svn.txt +82 -0
  14. data/doc/todo.txt +30 -0
  15. data/etc/new-project.rb +18 -0
  16. data/examples/simple/README +15 -0
  17. data/examples/simple/app.rb +31 -0
  18. data/examples/simple/conf/apache.conf +100 -0
  19. data/examples/simple/conf/config.rb +89 -0
  20. data/examples/simple/conf/debug-config.rb +53 -0
  21. data/examples/simple/conf/live-config.rb +48 -0
  22. data/examples/simple/conf/overrides.rb +9 -0
  23. data/examples/simple/conf/requires.rb +51 -0
  24. data/examples/simple/ctl +32 -0
  25. data/examples/simple/env.rb +33 -0
  26. data/examples/simple/install.rb +12 -0
  27. data/examples/simple/lib/articles/entities.rb +35 -0
  28. data/examples/simple/lib/articles/lc-en.rb +36 -0
  29. data/examples/simple/lib/articles/methods.rb +55 -0
  30. data/examples/simple/lib/articles/part.rb +58 -0
  31. data/examples/simple/logs/access_log +2 -0
  32. data/examples/simple/logs/apache.log +3 -0
  33. data/examples/simple/logs/app.log +1 -0
  34. data/examples/simple/logs/events.log +1 -0
  35. data/examples/simple/root/add-article.sx +15 -0
  36. data/examples/simple/root/article-form.ss +20 -0
  37. data/examples/simple/root/comments-form.ss +16 -0
  38. data/examples/simple/root/comments.si +30 -0
  39. data/examples/simple/root/index.sx +44 -0
  40. data/examples/simple/root/shader/shader.xsl +100 -0
  41. data/examples/simple/root/shader/style.css +9 -0
  42. data/examples/simple/root/view-article.sx +30 -0
  43. data/examples/tiny/app.rb +30 -0
  44. data/examples/tiny/conf/apache.conf +100 -0
  45. data/examples/tiny/conf/config.rb +67 -0
  46. data/examples/tiny/conf/requires.rb +40 -0
  47. data/examples/tiny/ctl +31 -0
  48. data/examples/tiny/logs/access_log +9 -0
  49. data/examples/tiny/logs/apache.log +9 -0
  50. data/examples/tiny/root/index.sx +35 -0
  51. data/lib/n/app/cluster.rb +219 -0
  52. data/lib/n/app/cookie.rb +86 -0
  53. data/lib/n/app/filters/autologin.rb +50 -0
  54. data/lib/n/app/fragment.rb +67 -0
  55. data/lib/n/app/handlers.rb +120 -0
  56. data/lib/n/app/handlers/code-handler.rb +184 -0
  57. data/lib/n/app/handlers/page-handler.rb +612 -0
  58. data/lib/n/app/request-part.rb +59 -0
  59. data/lib/n/app/request.rb +653 -0
  60. data/lib/n/app/script.rb +398 -0
  61. data/lib/n/app/server.rb +53 -0
  62. data/lib/n/app/session.rb +224 -0
  63. data/lib/n/app/user.rb +47 -0
  64. data/lib/n/app/webrick-servlet.rb +213 -0
  65. data/lib/n/app/webrick.rb +70 -0
  66. data/lib/n/application.rb +187 -0
  67. data/lib/n/config.rb +31 -0
  68. data/lib/n/db.rb +217 -0
  69. data/lib/n/db/README +232 -0
  70. data/lib/n/db/connection.rb +369 -0
  71. data/lib/n/db/make-release.sh +26 -0
  72. data/lib/n/db/managed.rb +235 -0
  73. data/lib/n/db/mixins.rb +282 -0
  74. data/lib/n/db/mysql.rb +342 -0
  75. data/lib/n/db/psql.rb +378 -0
  76. data/lib/n/db/tools.rb +110 -0
  77. data/lib/n/db/utils.rb +99 -0
  78. data/lib/n/events.rb +118 -0
  79. data/lib/n/l10n.rb +22 -0
  80. data/lib/n/logger.rb +33 -0
  81. data/lib/n/macros.rb +53 -0
  82. data/lib/n/mixins.rb +46 -0
  83. data/lib/n/parts.rb +154 -0
  84. data/lib/n/properties.rb +194 -0
  85. data/lib/n/server.rb +61 -0
  86. data/lib/n/server/PLAYBACK.txt +8 -0
  87. data/lib/n/server/RESEARCH.txt +13 -0
  88. data/lib/n/server/filter.rb +77 -0
  89. data/lib/n/shaders.rb +167 -0
  90. data/lib/n/sitemap.rb +188 -0
  91. data/lib/n/std.rb +69 -0
  92. data/lib/n/sync/clc.rb +108 -0
  93. data/lib/n/sync/handler.rb +221 -0
  94. data/lib/n/sync/server.rb +170 -0
  95. data/lib/n/tools/README +11 -0
  96. data/lib/n/ui/date-select.rb +74 -0
  97. data/lib/n/ui/pager.rb +187 -0
  98. data/lib/n/ui/popup.rb +45 -0
  99. data/lib/n/ui/select.rb +41 -0
  100. data/lib/n/ui/tabs.rb +34 -0
  101. data/lib/n/utils/array.rb +92 -0
  102. data/lib/n/utils/cache.rb +144 -0
  103. data/lib/n/utils/gfx.rb +108 -0
  104. data/lib/n/utils/hash.rb +148 -0
  105. data/lib/n/utils/html.rb +147 -0
  106. data/lib/n/utils/http.rb +98 -0
  107. data/lib/n/utils/mail.rb +28 -0
  108. data/lib/n/utils/number.rb +31 -0
  109. data/lib/n/utils/pool.rb +66 -0
  110. data/lib/n/utils/string.rb +297 -0
  111. data/lib/n/utils/template.rb +38 -0
  112. data/lib/n/utils/time.rb +91 -0
  113. data/lib/n/utils/uri.rb +193 -0
  114. data/lib/xsl/base.xsl +205 -0
  115. data/lib/xsl/ce.xsl +30 -0
  116. data/lib/xsl/localization.xsl +23 -0
  117. data/lib/xsl/xforms.xsl +26 -0
  118. data/test/run.rb +95 -0
  119. 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
+
@@ -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.
@@ -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
@@ -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