mack-distributed 0.7.0
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/README +106 -0
- data/bin/mack_ring_server +33 -0
- data/doc/classes/Mack/Distributable.html +137 -0
- data/doc/classes/Mack/Distributed/Errors/ApplicationNameUndefined.html +118 -0
- data/doc/classes/Mack/Distributed/Errors/InvalidAddressableURIFormat.html +152 -0
- data/doc/classes/Mack/Distributed/Errors/UnknownApplication.html +155 -0
- data/doc/classes/Mack/Distributed/Errors/UnknownRouteName.html +156 -0
- data/doc/classes/Mack/Distributed/Routes/Urls.html +213 -0
- data/doc/classes/Mack/Distributed/Utils/Rinda.html +230 -0
- data/doc/classes/Mack/Distributed/View.html +221 -0
- data/doc/classes/Mack/Distributed/ViewCache.html +170 -0
- data/doc/classes/Mack/Rendering/Type/Distributed.html +173 -0
- data/doc/classes/Mack/Rendering/Type/Layout.html +174 -0
- data/doc/classes/Mack/Routes/Urls.html +165 -0
- data/doc/created.rid +1 -0
- data/doc/files/README.html +272 -0
- data/doc/files/lib/mack-distributed/distributable_rb.html +101 -0
- data/doc/files/lib/mack-distributed/distributed_rb.html +101 -0
- data/doc/files/lib/mack-distributed/errors/errors_rb.html +101 -0
- data/doc/files/lib/mack-distributed/extensions/route_map_rb.html +101 -0
- data/doc/files/lib/mack-distributed/extensions/urls_rb.html +101 -0
- data/doc/files/lib/mack-distributed/routes/urls_rb.html +101 -0
- data/doc/files/lib/mack-distributed/utils/rinda_rb.html +101 -0
- data/doc/files/lib/mack-distributed/views/rendering/type/distributed_rb.html +101 -0
- data/doc/files/lib/mack-distributed/views/rendering/type/layout_rb.html +101 -0
- data/doc/files/lib/mack-distributed/views/view_cache_rb.html +101 -0
- data/doc/files/lib/mack-distributed/views/view_rb.html +101 -0
- data/doc/files/lib/mack-distributed_rb.html +110 -0
- data/doc/fr_class_index.html +38 -0
- data/doc/fr_file_index.html +39 -0
- data/doc/fr_method_index.html +43 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/mack-distributed/distributable.rb +68 -0
- data/lib/mack-distributed/distributed.rb +24 -0
- data/lib/mack-distributed/errors/errors.rb +33 -0
- data/lib/mack-distributed/extensions/route_map.rb +26 -0
- data/lib/mack-distributed/extensions/urls.rb +32 -0
- data/lib/mack-distributed/routes/urls.rb +51 -0
- data/lib/mack-distributed/tasks/ring_server_tasks.rake +33 -0
- data/lib/mack-distributed/utils/rinda.rb +48 -0
- data/lib/mack-distributed/views/rendering/type/distributed.rb +39 -0
- data/lib/mack-distributed/views/rendering/type/layout.rb +46 -0
- data/lib/mack-distributed/views/view.rb +41 -0
- data/lib/mack-distributed/views/view_cache.rb +32 -0
- data/lib/mack-distributed.rb +27 -0
- metadata +108 -0
data/doc/rdoc-style.css
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
font-family: Verdana,Arial,Helvetica,sans-serif;
|
4
|
+
font-size: 90%;
|
5
|
+
margin: 0;
|
6
|
+
margin-left: 40px;
|
7
|
+
padding: 0;
|
8
|
+
background: white;
|
9
|
+
}
|
10
|
+
|
11
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
12
|
+
h1 { font-size: 150%; }
|
13
|
+
h2,h3,h4 { margin-top: 1em; }
|
14
|
+
|
15
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
16
|
+
a:hover { background: #039; color: #eef; }
|
17
|
+
|
18
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
19
|
+
td > a {
|
20
|
+
background: transparent;
|
21
|
+
color: #039;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* and inside a section title */
|
26
|
+
.section-title > a {
|
27
|
+
background: transparent;
|
28
|
+
color: #eee;
|
29
|
+
text-decoration: none;
|
30
|
+
}
|
31
|
+
|
32
|
+
/* === Structural elements =================================== */
|
33
|
+
|
34
|
+
div#index {
|
35
|
+
margin: 0;
|
36
|
+
margin-left: -40px;
|
37
|
+
padding: 0;
|
38
|
+
font-size: 90%;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
div#index a {
|
43
|
+
margin-left: 0.7em;
|
44
|
+
}
|
45
|
+
|
46
|
+
div#index .section-bar {
|
47
|
+
margin-left: 0px;
|
48
|
+
padding-left: 0.7em;
|
49
|
+
background: #ccc;
|
50
|
+
font-size: small;
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
div#classHeader, div#fileHeader {
|
55
|
+
width: auto;
|
56
|
+
color: white;
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
58
|
+
margin: 0;
|
59
|
+
margin-left: -40px;
|
60
|
+
border-bottom: 3px solid #006;
|
61
|
+
}
|
62
|
+
|
63
|
+
div#classHeader a, div#fileHeader a {
|
64
|
+
background: inherit;
|
65
|
+
color: white;
|
66
|
+
}
|
67
|
+
|
68
|
+
div#classHeader td, div#fileHeader td {
|
69
|
+
background: inherit;
|
70
|
+
color: white;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
div#fileHeader {
|
75
|
+
background: #057;
|
76
|
+
}
|
77
|
+
|
78
|
+
div#classHeader {
|
79
|
+
background: #048;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
.class-name-in-header {
|
84
|
+
font-size: 180%;
|
85
|
+
font-weight: bold;
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
div#bodyContent {
|
90
|
+
padding: 0 1.5em 0 1.5em;
|
91
|
+
}
|
92
|
+
|
93
|
+
div#description {
|
94
|
+
padding: 0.5em 1.5em;
|
95
|
+
background: #efefef;
|
96
|
+
border: 1px dotted #999;
|
97
|
+
}
|
98
|
+
|
99
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
100
|
+
color: #125;;
|
101
|
+
background: transparent;
|
102
|
+
}
|
103
|
+
|
104
|
+
div#validator-badges {
|
105
|
+
text-align: center;
|
106
|
+
}
|
107
|
+
div#validator-badges img { border: 0; }
|
108
|
+
|
109
|
+
div#copyright {
|
110
|
+
color: #333;
|
111
|
+
background: #efefef;
|
112
|
+
font: 0.75em sans-serif;
|
113
|
+
margin-top: 5em;
|
114
|
+
margin-bottom: 0;
|
115
|
+
padding: 0.5em 2em;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
/* === Classes =================================== */
|
120
|
+
|
121
|
+
table.header-table {
|
122
|
+
color: white;
|
123
|
+
font-size: small;
|
124
|
+
}
|
125
|
+
|
126
|
+
.type-note {
|
127
|
+
font-size: small;
|
128
|
+
color: #DEDEDE;
|
129
|
+
}
|
130
|
+
|
131
|
+
.xxsection-bar {
|
132
|
+
background: #eee;
|
133
|
+
color: #333;
|
134
|
+
padding: 3px;
|
135
|
+
}
|
136
|
+
|
137
|
+
.section-bar {
|
138
|
+
color: #333;
|
139
|
+
border-bottom: 1px solid #999;
|
140
|
+
margin-left: -20px;
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
.section-title {
|
145
|
+
background: #79a;
|
146
|
+
color: #eee;
|
147
|
+
padding: 3px;
|
148
|
+
margin-top: 2em;
|
149
|
+
margin-left: -30px;
|
150
|
+
border: 1px solid #999;
|
151
|
+
}
|
152
|
+
|
153
|
+
.top-aligned-row { vertical-align: top }
|
154
|
+
.bottom-aligned-row { vertical-align: bottom }
|
155
|
+
|
156
|
+
/* --- Context section classes ----------------------- */
|
157
|
+
|
158
|
+
.context-row { }
|
159
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
160
|
+
.context-item-value { font-size: small; color: #448; }
|
161
|
+
.context-item-desc { color: #333; padding-left: 2em; }
|
162
|
+
|
163
|
+
/* --- Method classes -------------------------- */
|
164
|
+
.method-detail {
|
165
|
+
background: #efefef;
|
166
|
+
padding: 0;
|
167
|
+
margin-top: 0.5em;
|
168
|
+
margin-bottom: 1em;
|
169
|
+
border: 1px dotted #ccc;
|
170
|
+
}
|
171
|
+
.method-heading {
|
172
|
+
color: black;
|
173
|
+
background: #ccc;
|
174
|
+
border-bottom: 1px solid #666;
|
175
|
+
padding: 0.2em 0.5em 0 0.5em;
|
176
|
+
}
|
177
|
+
.method-signature { color: black; background: inherit; }
|
178
|
+
.method-name { font-weight: bold; }
|
179
|
+
.method-args { font-style: italic; }
|
180
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
181
|
+
|
182
|
+
/* --- Source code sections -------------------- */
|
183
|
+
|
184
|
+
a.source-toggle { font-size: 90%; }
|
185
|
+
div.method-source-code {
|
186
|
+
background: #262626;
|
187
|
+
color: #ffdead;
|
188
|
+
margin: 1em;
|
189
|
+
padding: 0.5em;
|
190
|
+
border: 1px dashed #999;
|
191
|
+
overflow: hidden;
|
192
|
+
}
|
193
|
+
|
194
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
195
|
+
|
196
|
+
/* --- Ruby keyword styles --------------------- */
|
197
|
+
|
198
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
199
|
+
|
200
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
201
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
202
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
203
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
204
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
205
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
206
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
207
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
208
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Mack # :nodoc:
|
2
|
+
# Include this module into any class it will instantly register that class with
|
3
|
+
# the mack_ring_server. The class will be registered with the name of the class
|
4
|
+
# and the mack.distributed_app_name configured in your config/app_config/*.yml file.
|
5
|
+
# If the mack.distributed_app_name configuration parameter is nil it will raise
|
6
|
+
# an Mack::Distributed::Errors::ApplicationNameUndefined exception.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# class User
|
10
|
+
# include Mack::Distributable
|
11
|
+
# def name
|
12
|
+
# "mark"
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Mack::Distributed::User.new.name # => "mark"
|
17
|
+
module Distributable
|
18
|
+
|
19
|
+
def self.included(base) # :nodoc:
|
20
|
+
if app_config.mack.share_objects
|
21
|
+
base.class_eval do
|
22
|
+
include ::DRbUndumped
|
23
|
+
end
|
24
|
+
eval %{
|
25
|
+
class ::Mack::Distributed::#{base}Proxy
|
26
|
+
include Singleton
|
27
|
+
include DRbUndumped
|
28
|
+
|
29
|
+
def method_missing(sym, *args)
|
30
|
+
#{base}.send(sym, *args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
#{base}.inspect
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
#{base}.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
# def respond_to?(sym)
|
42
|
+
# #{base}.respond_to?(sym)
|
43
|
+
# end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
raise Mack::Distributed::Errors::ApplicationNameUndefined.new if app_config.mack.distributed_app_name.nil?
|
47
|
+
Mack::Distributed::Utils::Rinda.register_or_renew(:space => app_config.mack.distributed_app_name.to_sym,
|
48
|
+
:klass_def => "#{base}".to_sym,
|
49
|
+
:object => "Mack::Distributed::#{base}Proxy".constantize.instance)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # Distributable
|
54
|
+
end # Mack
|
55
|
+
|
56
|
+
module DRb # :nodoc:
|
57
|
+
class DRbObject # :nodoc:
|
58
|
+
|
59
|
+
alias_method :original_inspect, :inspect
|
60
|
+
|
61
|
+
def inspect
|
62
|
+
"#{original_inspect}|#{method_missing(:inspect)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
undef :id
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Mack # :nodoc:
|
2
|
+
module Distributed # :nodoc:
|
3
|
+
|
4
|
+
# Looks up and tries to find the missing constant using the ring server.
|
5
|
+
def self.const_missing(const)
|
6
|
+
Mack::Distributed::Utils::Rinda.read(:klass_def => "#{const}".to_sym)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Allows for the specific lookup of services on the ring server
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
# Mack::Distributed::Utils::Rinda.register_or_renew(:space => :app_1, :klass_def => :Test, :object => "Hello World!")
|
13
|
+
# Mack::Distributed::Utils::Rinda.register_or_renew(:space => :app_2, :klass_def => :Test, :object => "Hello WORLD!")
|
14
|
+
# Mack::Distributed.lookup("distributed://app_1/Test") # => "Hello World!"
|
15
|
+
# Mack::Distributed.lookup("distributed://app_2/Test") # => "Hello WORLD!"
|
16
|
+
def self.lookup(address)
|
17
|
+
uri = Addressable::URI.parse(address)
|
18
|
+
path = uri.path[1..uri.path.size] # remove the first slash
|
19
|
+
host = uri.host
|
20
|
+
Mack::Distributed::Utils::Rinda.read(:klass_def => path.to_sym, :space => host.to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
end # Distributed
|
24
|
+
end # Mack
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed # :nodoc:
|
3
|
+
module Errors # :nodoc:
|
4
|
+
|
5
|
+
# Raised when an unknown distributed application is referenced.
|
6
|
+
class UnknownApplication < StandardError
|
7
|
+
# Takes the application name.
|
8
|
+
def initialize(app_name)
|
9
|
+
super("APPLICATION: #{app_name} is not a known/registered distributed application.")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when an unknown distributed route name for a distributed application is referenced.
|
14
|
+
class UnknownRouteName < StandardError
|
15
|
+
# Takes the application name and the route name.
|
16
|
+
def initialize(app_name, route_name)
|
17
|
+
super("ROUTE_NAME: #{route_name}, is not a known/registered distributed route name for application: #{app_name}.")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Raised when an application doesn't declare it's application name for use in a distributed system.
|
22
|
+
class ApplicationNameUndefined < StandardError
|
23
|
+
end
|
24
|
+
|
25
|
+
# Raised when the distributed path is not a well formed addressable format
|
26
|
+
class InvalidAddressableURIFormat < StandardError
|
27
|
+
def inititalize(msg)
|
28
|
+
super("Invalid addressable format: #{msg}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end # Errors
|
32
|
+
end # Distributed
|
33
|
+
end # Mack
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mack
|
2
|
+
module Routes # :nodoc:
|
3
|
+
class RouteMap # :nodoc:
|
4
|
+
|
5
|
+
# let's make sure we only do the alias_method once.
|
6
|
+
unless self.private_instance_methods.include?("normal_connect_with_named_route")
|
7
|
+
|
8
|
+
alias_method :normal_connect_with_named_route, :connect_with_named_route
|
9
|
+
|
10
|
+
def connect_with_named_route(n_route, pattern, options = {}) # :nodoc:
|
11
|
+
n_route = n_route.methodize
|
12
|
+
normal_connect_with_named_route(n_route, pattern, options)
|
13
|
+
if app_config.mack.share_routes
|
14
|
+
Mack::Routes::Urls.class_eval %{
|
15
|
+
def #{n_route}_distributed_url(options = {})
|
16
|
+
(@dsd || app_config.mack.distributed_site_domain) + #{n_route}_url(options)
|
17
|
+
end
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end # connect_with_named_route
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end # RouteMap
|
25
|
+
end # Routes
|
26
|
+
end # Mack
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mack # :nodoc:
|
2
|
+
module Routes # :nodoc:
|
3
|
+
module Urls
|
4
|
+
|
5
|
+
alias_deprecated_method :droute_url, :distributed_url, '0.7.0', '>=0.8.0'
|
6
|
+
# Retrieves a distributed route from a DRb server.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# distributed_url(:app_1, :home_page_url)
|
10
|
+
# distributed_url(:registration_app, :signup_url, {:from => :google})
|
11
|
+
def distributed_url(app_name, route_name, options = {})
|
12
|
+
route_name = route_name.to_s
|
13
|
+
if route_name.match(/_url$/)
|
14
|
+
unless route_name.match(/_distributed_url$/)
|
15
|
+
route_name.gsub!("_url", "_distributed_url")
|
16
|
+
end
|
17
|
+
else
|
18
|
+
route_name << "_distributed_url"
|
19
|
+
end
|
20
|
+
|
21
|
+
if !app_config.mack.distributed_app_name.nil? && app_name.to_sym == app_config.mack.distributed_app_name.to_sym
|
22
|
+
# if it's local let's just use it and not go out to Rinda
|
23
|
+
return self.send(route_name, options)
|
24
|
+
end
|
25
|
+
d_urls = Mack::Distributed::Routes::Urls.get(app_name)
|
26
|
+
raise Mack::Distributed::Errors::UnknownRouteName.new(app_name, route_name) unless d_urls.respond_to?(route_name)
|
27
|
+
return d_urls.run(route_name, options)
|
28
|
+
end # distributed_url
|
29
|
+
|
30
|
+
end # Urls
|
31
|
+
end # Routes
|
32
|
+
end # Mack
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
module Routes # :nodoc:
|
4
|
+
# A class used to house the Mack::Routes::Url module for distributed applications.
|
5
|
+
# Functionally this class does nothing, but since you can't cache a module, a class is needed.
|
6
|
+
class Urls
|
7
|
+
include DRbUndumped
|
8
|
+
|
9
|
+
def initialize(dsd) # :nodoc:
|
10
|
+
@dsd = dsd
|
11
|
+
end
|
12
|
+
|
13
|
+
def put
|
14
|
+
Mack::Distributed::Utils::Rinda.register_or_renew(:space => app_config.mack.distributed_app_name.to_sym,
|
15
|
+
:klass_def => :distributed_routes,
|
16
|
+
:object => self, :timeout => 0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(meth, options)
|
20
|
+
self.send(meth, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
def get(app_name)
|
26
|
+
Mack::Distributed::Utils::Rinda.read(:space => app_name.to_sym, :klass_def => :distributed_routes)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end # Urls
|
32
|
+
|
33
|
+
end # Routes
|
34
|
+
end # Distributed
|
35
|
+
|
36
|
+
end # Mack
|
37
|
+
|
38
|
+
Mack::Routes.after_class_method(:build) do
|
39
|
+
if app_config.mack.share_routes
|
40
|
+
raise Mack::Distributed::Errors::ApplicationNameUndefined.new if app_config.mack.distributed_app_name.nil?
|
41
|
+
|
42
|
+
d_urls = Mack::Distributed::Routes::Urls.new(app_config.mack.distributed_site_domain)
|
43
|
+
d_urls.put
|
44
|
+
Mack::Routes::Urls.include_safely_into(Mack::Distributed::Routes::Urls)
|
45
|
+
Mack::Distributed::Routes::Urls.protected_instance_methods.each do |m|
|
46
|
+
Mack::Distributed::Routes::Urls.instance_eval do
|
47
|
+
public m if m.match(/_url$/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rinda/ring'
|
2
|
+
namespace :mack do
|
3
|
+
namespace :ring_server do
|
4
|
+
|
5
|
+
desc "Start the Rinda ring server"
|
6
|
+
task :start do
|
7
|
+
`mack_ring_server start`
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Stop the Rinda ring server"
|
11
|
+
task :stop do
|
12
|
+
`mack_ring_server stop`
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :services do
|
16
|
+
|
17
|
+
desc "Lists all services on the ring server"
|
18
|
+
task :list do
|
19
|
+
DRb.start_service
|
20
|
+
ring_server = Rinda::RingFinger.primary
|
21
|
+
services = ring_server.read_all([nil, nil, nil, nil])
|
22
|
+
puts "Services on #{ring_server.__drburi}"
|
23
|
+
services.each do |service|
|
24
|
+
puts "#{service[0]}: #{service[1]} on #{service[2].__drburi} - #{service[3]}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end # services
|
29
|
+
|
30
|
+
end # ring_server
|
31
|
+
end # mack
|
32
|
+
|
33
|
+
alias_task "mack:ring_server:restart", "mack:ring_server:stop", "mack:ring_server:start"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
module Utils # :nodoc:
|
4
|
+
module Rinda
|
5
|
+
|
6
|
+
def self.register_or_renew(options = {})
|
7
|
+
options = handle_options(options)
|
8
|
+
begin
|
9
|
+
ring_server.take([options[:space], options[:klass_def], nil, nil], options[:timeout])
|
10
|
+
rescue Exception => e
|
11
|
+
# Mack.logger.error(e)
|
12
|
+
end
|
13
|
+
register(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register(options = {})
|
17
|
+
options = handle_options(options)
|
18
|
+
ring_server.write([options[:space],
|
19
|
+
options[:klass_def],
|
20
|
+
options[:object],
|
21
|
+
options[:description]],
|
22
|
+
::Rinda::SimpleRenewer.new)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.ring_server
|
26
|
+
if app_config.mack.distributed_acl
|
27
|
+
acl = ACL.new(app_config.mack.distributed_acl)
|
28
|
+
DRb.install_acl(acl)
|
29
|
+
end
|
30
|
+
::DRb.start_service
|
31
|
+
rs = ::Rinda::RingFinger.primary
|
32
|
+
rs
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.read(options = {})
|
36
|
+
options = handle_options(options)
|
37
|
+
ring_server.read([options[:space], options[:klass_def], nil, options[:description]], options[:timeout])[2]
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def self.handle_options(options = {})
|
42
|
+
{:space => nil, :klass_def => nil, :object => nil, :description => nil, :timeout => app_config.mack.drb_timeout}.merge(options)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Mack
|
2
|
+
module Rendering
|
3
|
+
module Type
|
4
|
+
class Distributed < Mack::Rendering::Type::Base
|
5
|
+
|
6
|
+
# render(:distributed, "distributed://host/resource")
|
7
|
+
def render
|
8
|
+
uri = Addressable::URI.parse(self.render_value)
|
9
|
+
raise InvalidAddressableURIFormat.new("#{self.render_value}") if uri.host.nil? or uri.path.nil?
|
10
|
+
|
11
|
+
app_name = uri.host
|
12
|
+
resource = File.join("app", "views", uri.path)
|
13
|
+
|
14
|
+
data = Mack::Distributed::View.ref(app_name)
|
15
|
+
if data
|
16
|
+
raw = ""
|
17
|
+
Mack::Rendering::Engine::Registry.engines[:distributed].each do |e|
|
18
|
+
@engine = find_engine(e).new(self.view_template)
|
19
|
+
|
20
|
+
view_path = "#{resource}.#{self.options[:format]}.#{@engine.extension}"
|
21
|
+
raw = data.get(view_path)
|
22
|
+
break if !raw.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
raise Mack::Errors::ResourceNotFound.new("#{self.options[:distributed]}") if raw.nil?
|
26
|
+
|
27
|
+
old_render_value = self.view_template.render_value.dup
|
28
|
+
self.view_template.render_value = raw
|
29
|
+
Mack::Rendering::Type::Inline.new(self.view_template).render
|
30
|
+
# self.view_template.render_value = old_render_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Mack::Rendering::Engine::Registry.register(:distributed, :builder)
|
39
|
+
Mack::Rendering::Engine::Registry.register(:distributed, :erubis)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Mack
|
2
|
+
module Rendering # :nodoc:
|
3
|
+
module Type # :nodoc:
|
4
|
+
class Layout
|
5
|
+
|
6
|
+
unless public_instance_methods.include?("old_render")
|
7
|
+
alias_method :old_render, :render
|
8
|
+
end
|
9
|
+
|
10
|
+
def render
|
11
|
+
if !self.options[:layout].starts_with?("distributed")
|
12
|
+
# this is the regular layout, so call the local_render method
|
13
|
+
old_render
|
14
|
+
else
|
15
|
+
uri = Addressable::URI.parse(self.options[:layout])
|
16
|
+
raise InvalidAddressableURIFormat.new("#{self.options[:layout]}") if uri.host.nil? or uri.path.nil?
|
17
|
+
|
18
|
+
app_name = uri.host
|
19
|
+
resource = File.join("app", "views", "layouts", uri.path)
|
20
|
+
|
21
|
+
data = Mack::Distributed::View.ref(app_name)
|
22
|
+
if data
|
23
|
+
raw = ""
|
24
|
+
Mack::Rendering::Engine::Registry.engines[:layout].each do |e|
|
25
|
+
@engine = find_engine(e).new(self.view_template)
|
26
|
+
|
27
|
+
layout_path = "#{resource}.#{self.options[:format]}.#{@engine.extension}"
|
28
|
+
raw = data.get(layout_path)
|
29
|
+
break if !raw.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
raise Mack::Errors::ResourceNotFound.new("#{self.options[:distributed]}") if raw.nil?
|
33
|
+
|
34
|
+
old_render_value = self.view_template.render_value.dup
|
35
|
+
self.view_template.render_value = raw
|
36
|
+
Mack::Rendering::Type::Inline.new(self.view_template).render
|
37
|
+
# self.view_template.render_value = old_render_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
class View
|
4
|
+
|
5
|
+
include Singleton
|
6
|
+
include DRbUndumped
|
7
|
+
|
8
|
+
def get(resource)
|
9
|
+
path = File.join(Mack.root, resource)
|
10
|
+
raw = Mack::Distributed::ViewCache.get(path)
|
11
|
+
return raw
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def register
|
16
|
+
if app_config.mack.share_views
|
17
|
+
raise Mack::Distributed::Errors::ApplicationNameUndefined.new if app_config.mack.distributed_app_name.nil?
|
18
|
+
# Mack.logger.info "Registering Mack::Distributed::View for '#{app_config.mack.distributed_app_name}' with Rinda"
|
19
|
+
|
20
|
+
Mack::Distributed::Utils::Rinda.register_or_renew(:space => app_config.mack.distributed_app_name.to_sym,
|
21
|
+
:klass_def => :distributed_views,
|
22
|
+
:object => Mack::Distributed::View.instance)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def ref(app_name)
|
27
|
+
begin
|
28
|
+
obj = Mack::Distributed::Utils::Rinda.read(:space => app_name.to_sym,
|
29
|
+
:klass_def => :distributed_views)
|
30
|
+
return obj
|
31
|
+
rescue Rinda::RequestExpiredError => er
|
32
|
+
Mack.logger.warn(er)
|
33
|
+
end
|
34
|
+
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end # View
|
40
|
+
end # Distributed
|
41
|
+
end # Mack
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
class ViewCache < Cachetastic::Caches::Base
|
4
|
+
|
5
|
+
class << self
|
6
|
+
include Mack::ViewHelpers::LinkHelpers
|
7
|
+
|
8
|
+
def get(path)
|
9
|
+
raw = super(path) do
|
10
|
+
raw = ""
|
11
|
+
if File.exists?(path)
|
12
|
+
raw = File.read(path)
|
13
|
+
|
14
|
+
# preprocess the raw content so we can resolve css/javascript/image path
|
15
|
+
arr = raw.scan(/<%=.*?%>/)
|
16
|
+
arr.each do |scriptlet|
|
17
|
+
if scriptlet.match(/stylesheet/) or scriptlet.match(/javascript/) or scriptlet.match(/image/)
|
18
|
+
res = ERB.new(scriptlet).result(binding)
|
19
|
+
raw.gsub!(scriptlet, res)
|
20
|
+
end
|
21
|
+
end # if arr.each
|
22
|
+
end # if File.exists?
|
23
|
+
|
24
|
+
set(path, raw)
|
25
|
+
end # super(key)
|
26
|
+
return raw
|
27
|
+
end # def get
|
28
|
+
end # class << self
|
29
|
+
|
30
|
+
end # ViewCache
|
31
|
+
end # Distributed
|
32
|
+
end # Mack
|