plezi 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +32 -33
- data/docs/async_helpers.md +90 -40
- data/docs/logging.md +38 -3
- data/docs/routes.md +177 -5
- data/docs/websockets.md +5 -0
- data/lib/plezi.rb +2 -10
- data/lib/plezi/common/api.rb +48 -101
- data/lib/plezi/common/defer.rb +4 -4
- data/lib/plezi/common/dsl.rb +13 -24
- data/lib/plezi/common/redis.rb +9 -5
- data/lib/plezi/common/settings.rb +4 -24
- data/lib/plezi/handlers/controller_core.rb +7 -14
- data/lib/plezi/handlers/controller_magic.rb +12 -10
- data/lib/plezi/handlers/http_router.rb +27 -22
- data/lib/plezi/handlers/placebo.rb +40 -33
- data/lib/plezi/handlers/route.rb +233 -234
- data/lib/plezi/handlers/session.rb +2 -2
- data/lib/plezi/handlers/stubs.rb +7 -0
- data/lib/plezi/handlers/ws_object.rb +25 -15
- data/lib/plezi/helpers/http_sender.rb +3 -3
- data/lib/plezi/helpers/magic_helpers.rb +3 -3
- data/lib/plezi/version.rb +1 -1
- data/plezi.gemspec +1 -1
- data/resources/config.ru +12 -18
- data/resources/environment.rb +6 -7
- data/resources/mini_app.rb +22 -22
- data/resources/redis_config.rb +4 -2
- data/test/plezi_tests.rb +76 -87
- data/websocket chatroom.md +3 -5
- metadata +6 -6
- data/docs/http_helpers.md +0 -9
data/docs/logging.md
CHANGED
@@ -2,13 +2,48 @@
|
|
2
2
|
|
3
3
|
(todo: write documentation)
|
4
4
|
|
5
|
-
Inside Plezi's core code is a pure Ruby IO reactor called [
|
5
|
+
Inside Plezi's core code is a pure Ruby IO reactor called [Iodine](https://github.com/boazsegev/iodine), a wonderful Asynchronous Workflow Engine that allows us to enjoy both Multi-Threading and Multi-Processing.
|
6
6
|
|
7
|
-
Plezi leverages [
|
7
|
+
Plezi leverages [Iodine's](https://github.com/boazsegev/iodine) logging support to help you log to both files and STDOUT (terminal screen) - either one or both
|
8
8
|
|
9
|
-
You can read more about [
|
9
|
+
You can read more about [Iodine](https://github.com/boazsegev/iodine) and it's amazing features in it's [documentation](http://www.rubydoc.info/github/boazsegev/iodine/master).
|
10
10
|
|
11
11
|
## Setting up a Logger
|
12
12
|
|
13
|
+
Logging is based on the standard Ruby `Logger`, and replaceing the default logger (STDOUT) to a different logger (such as a file based logger), is as simple as:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Iodine.logger = Logger.new filename
|
17
|
+
# # the same can be done using Plezi.logger, which automatically defers to Iodine.logger
|
18
|
+
# Plezi.logger = Logger.new filename
|
19
|
+
```
|
20
|
+
|
13
21
|
|
14
22
|
## Logging Helpers Methods
|
23
|
+
|
24
|
+
// to do: complete docs
|
25
|
+
|
26
|
+
### `Iodine.info`
|
27
|
+
|
28
|
+
// to do: complete docs
|
29
|
+
|
30
|
+
### `Iodine.debug`
|
31
|
+
|
32
|
+
// to do: complete docs
|
33
|
+
|
34
|
+
### `Iodine.warn`
|
35
|
+
|
36
|
+
// to do: complete docs
|
37
|
+
|
38
|
+
### `Iodine.error`
|
39
|
+
|
40
|
+
// to do: complete docs
|
41
|
+
|
42
|
+
### `Iodine.fatal`
|
43
|
+
|
44
|
+
// to do: complete docs
|
45
|
+
|
46
|
+
### `Iodine.log(raw_string)`
|
47
|
+
|
48
|
+
// to do: complete docs
|
49
|
+
|
data/docs/routes.md
CHANGED
@@ -1,22 +1,194 @@
|
|
1
1
|
# Plezi's Smart Routing System
|
2
2
|
|
3
|
-
In the core of Plezi's framework is a smart Object Oriented Router which
|
3
|
+
In the core of Plezi's framework is a smart Object Oriented Router which acts like a "virtual folder" with RESTful routing and Websocket support.
|
4
4
|
|
5
5
|
RESTful routing and Websocket callback support both allow us to use conventionally named methods in our Controller to achive common tasks. Such names methods, as will be explored further on, include the `update`, `save` and `show` RESTful method names, as well as the `on_open`, `on_message(data)` and `on_close` Websocket callbacks.
|
6
6
|
|
7
|
+
## What is a Route?
|
8
|
+
|
9
|
+
Routes are what connects different URLs to different parts of our code.
|
10
|
+
|
11
|
+
We when we visit `www.example.com/users/index` we expect a different page than when we go to `www.example.com/users/1`. This is because we expect the first URL to provide a page with the list of users while we expect the second URL to show us just one user's page or data.
|
12
|
+
|
13
|
+
in the example above, all the requests to `www.example.com` end up at the same server and it is the server's inner workings - the server's inner router - that directs the `/users/index` to one part of our code and `/users/1` to another.
|
14
|
+
|
15
|
+
Plezi has an inner router which routes each request to the corresponding method or code.
|
16
|
+
|
17
|
+
\* It should be noted that except for file handling and the asset pipeline - which are file-system dependent - routes are case-sensitive.
|
18
|
+
|
7
19
|
## Defining a Route
|
8
20
|
|
9
|
-
(
|
21
|
+
We define a route using Plezi's `Plezi.route` method or the shortcut DSL method `route` (without the `Plezi.` part).
|
22
|
+
|
23
|
+
This method accept a String, or Regexp, that should point to a "group" of routes.
|
24
|
+
|
25
|
+
The method also requires either a class that "controls" that group of routes or a block of code that responds to that route.
|
26
|
+
|
27
|
+
Here are a two examples for valid routes. You can run the following script in the `irb` terminal:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'plezi'
|
31
|
+
|
32
|
+
class UsersController
|
33
|
+
def index
|
34
|
+
"All Users"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# the "/users" group can be extended. for now, it will only answer: "/users" or "/users/index"
|
39
|
+
# this is because that's all that UsersController defines.
|
40
|
+
Plezi.route "/users", UsersController
|
41
|
+
|
42
|
+
# this route isn't grouped under a controller. it will only answer "/people"
|
43
|
+
Plezi.route("/people") { "People" }
|
44
|
+
|
45
|
+
# this route includes a catch-all at the end and will catch anything that starts with "/stuff/"
|
46
|
+
Plezi.route("/stuff/*") { "More and more stuff" }
|
47
|
+
|
48
|
+
# this is catch-all which will answer any requests not yet answered.
|
49
|
+
Plezi.route("*") { "Lost?" }
|
50
|
+
|
51
|
+
# this route will never be seen,
|
52
|
+
# because the catch-all route answers any request before it gets here.
|
53
|
+
Plezi.route("/never-seen") { "You cant see me..." }
|
54
|
+
|
55
|
+
|
56
|
+
exit
|
57
|
+
```
|
58
|
+
|
59
|
+
As you may have noticed, the route's order of creation was important and established an order of precedence.
|
60
|
+
|
61
|
+
If the order of precedence were not to exist, we couldn't create a catch-all route, in fear that it might respond to valid requests.
|
10
62
|
|
11
63
|
### The `:id` parameter
|
12
64
|
|
13
|
-
(
|
65
|
+
In order to manage route "groups", Plezi's router attmpt to add an optional `:id` parameter at the end of the route. This is only possible when the route doesn't end with a catch-all (if a catch-all exists, the `:id` parameter can't be isolated).
|
66
|
+
|
67
|
+
So, the following two routes are identical:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
require 'plezi'
|
71
|
+
|
72
|
+
class UsersController
|
73
|
+
def index
|
74
|
+
"All Users"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
Plezi.route "/users", UsersController
|
79
|
+
|
80
|
+
route "/users/(:id)", UsersController
|
81
|
+
|
82
|
+
exit
|
83
|
+
```
|
84
|
+
|
85
|
+
It's possible to add different optional parameters either before or after the (:id) parameter... but the (:id) parameter is special and it WILL effect the way the Controller reacts to the request - this is what allows the controller to react to RESTful requests (more information about this later on).
|
86
|
+
|
87
|
+
For example:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
require 'plezi'
|
91
|
+
|
92
|
+
class UsersController
|
93
|
+
def index
|
94
|
+
"All Users"
|
95
|
+
end
|
96
|
+
def show
|
97
|
+
params[:name] ||= "unknown"
|
98
|
+
"Your name is #{ params[:name] }... why are you looking for user id '#{ params[:id] }'?"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# try visiting "/users/1/John"
|
103
|
+
route "/users/(:id)/(:name)", UsersController
|
104
|
+
|
105
|
+
exit
|
106
|
+
```
|
107
|
+
|
108
|
+
As you noticed, providing an `:id` parameter invoked the RESTful method `show`. This is only one possible outcome. We will discuss this more when we look at the Controller being used as a virtual folder and as we discuss about RESTful method.
|
14
109
|
|
15
110
|
### More inline parameters
|
16
111
|
|
17
|
-
|
112
|
+
Inline parameters come in more flavors:
|
113
|
+
|
114
|
+
* Required parameters signified only by the `:` sign. i.e. `'/users/:name'`.
|
115
|
+
* Optional parameters, as seen before. i.e. `'/users/(:name)'`.
|
116
|
+
* Required parameters matching a specific pattern, signified by the `:` sign with a `{pattern}`. i.e. `'/users/:date{[\d]{8}}'` (requiring 8 digit date, such as `'20151231'`).
|
117
|
+
* Optional parameters matching a specific pattern. i.e. `'/users/(:date){[\d]{8}}'` (optional 8 digit date, such as `'20151231'`).
|
118
|
+
|
119
|
+
Using inline parameters, it's possible to achive great flexability with the same route, allowing our code to be better organized. This is especially helpful when expecting data to be received using AJAX or when creating an accessible API for native apps to utilize.
|
120
|
+
|
121
|
+
It should be noted, that since a parameter matches against the whole of the pattern, parenthesis shouldn't be used and could cause parsing errors.
|
122
|
+
|
123
|
+
### Re-Write Routes
|
124
|
+
|
125
|
+
Sometimes, we want some of our routes to share common optional (or required) parameters. This is where "Re-Write" routes come into play.
|
126
|
+
|
127
|
+
A common use-case, is for setting the locale or language for the response.
|
128
|
+
|
129
|
+
To create a re-write route, we set the "controller" to false.
|
130
|
+
|
131
|
+
For Example:
|
132
|
+
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
require 'plezi'
|
136
|
+
|
137
|
+
class UsersController
|
138
|
+
def index
|
139
|
+
case params[:locale]
|
140
|
+
when 'sp'
|
141
|
+
"Hola!"
|
142
|
+
when 'fr'
|
143
|
+
"Bonjour!"
|
144
|
+
when 'ru'
|
145
|
+
"Здравствуйте!"
|
146
|
+
when 'jp'
|
147
|
+
"こんにちは!"
|
148
|
+
else
|
149
|
+
"Hello!"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# this is the re-write route:
|
155
|
+
Plezi.route "/(:locale){en|sp|fr|ru|jp}/*", false
|
156
|
+
|
157
|
+
# this route inherits the `:locale`'s result
|
158
|
+
# try:
|
159
|
+
# /fr/users
|
160
|
+
# /ru/users
|
161
|
+
# /en/users
|
162
|
+
# /it/users # => isn't a valid locale
|
163
|
+
Plezi.route "/users", UsersController
|
164
|
+
|
165
|
+
exit
|
166
|
+
```
|
167
|
+
|
168
|
+
notice the re-write route contained a catch all. After Plezi version 0.11.3 this catch-all is automatically added if missing. The catch-all is the part of the path that will remain for the following routes to check against.
|
169
|
+
|
170
|
+
### Routes with Blocks instead of Controllers
|
171
|
+
|
172
|
+
Routes that respond with a block of code can receive the `request` and `response` objects, allowing for greater usability.
|
173
|
+
|
174
|
+
These Routes favor a global response over the different features offered by Controllers (i.e. RESTful routing and virtual folder method routing). Also, the block of code does NOT inherit all the magical abilities bestowed on Controllers which could allow for a slight increase in response time.
|
175
|
+
|
176
|
+
Here's a more powerful example of a route with a block of code, thistime using the `request` and `response` passed on to it:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
require 'plezi'
|
180
|
+
|
181
|
+
Plezi.route "/(:id)/(:value)" do |request, response|
|
182
|
+
if request.params[:id]
|
183
|
+
response.cookies[request.params[:id]] = request.params[:value]
|
184
|
+
response << "Set the #{request.params[:id]} cookie to #{request.params[:value] || 'be removed'}.\n\n"
|
185
|
+
end
|
186
|
+
response << "Your cookies are:\n"
|
187
|
+
request.cookies.each {|k, v| response << "* #{k}: #{v}\n" }
|
188
|
+
end
|
18
189
|
|
19
|
-
|
190
|
+
exit
|
191
|
+
```
|
20
192
|
|
21
193
|
## The Controller
|
22
194
|
|
data/docs/websockets.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Plezi Websockets
|
2
2
|
|
3
|
+
Inside Plezi's core code is the pure Ruby HTTP and Websocket Server (and client) that comes with [Iodine](https://github.com/boazsegev/iodine), a wonderful little server that supports an effective websocket fanctionality both as a server and as a client.
|
4
|
+
|
5
|
+
Plezi augmentes Iodine by adding auto-Redis support for scaling and automatically mapping each Contoller Class as a broadcast channel and each server instance to it's own unique channel - allowing unicasting to direct it's message at the target connection's server and optimizing resources.
|
6
|
+
|
7
|
+
|
3
8
|
|
4
9
|
(todo: write documentation)
|
5
10
|
|
data/lib/plezi.rb
CHANGED
@@ -11,8 +11,8 @@ require 'yaml'
|
|
11
11
|
require 'uri'
|
12
12
|
require 'set'
|
13
13
|
|
14
|
-
#
|
15
|
-
require '
|
14
|
+
# Iodine server
|
15
|
+
require 'iodine/http'
|
16
16
|
|
17
17
|
|
18
18
|
## erb templating
|
@@ -67,7 +67,6 @@ require 'plezi/handlers/session.rb'
|
|
67
67
|
# For example, open your Ruby terminal (the `irb` command) and type:
|
68
68
|
#
|
69
69
|
# require 'plezi'
|
70
|
-
# listen
|
71
70
|
# route "*", Plezi::StubRESTCtrl
|
72
71
|
# exit # will start the service.
|
73
72
|
#
|
@@ -81,7 +80,6 @@ require 'plezi/handlers/session.rb'
|
|
81
80
|
# "Hello World!"
|
82
81
|
# end
|
83
82
|
# end
|
84
|
-
# listen
|
85
83
|
# route "*", MyController
|
86
84
|
#
|
87
85
|
# exit # I'll stop writing this line every time.
|
@@ -92,7 +90,6 @@ require 'plezi/handlers/session.rb'
|
|
92
90
|
# Plezi also accepts an optional block instead of the conrtoller Class object for example:
|
93
91
|
#
|
94
92
|
# require 'plezi'
|
95
|
-
# listen
|
96
93
|
# route(/[.]*/) {|request, response| response << "Your request, master: #{request.path}."}
|
97
94
|
#
|
98
95
|
# As you may have noticed before, the catch-all route (/[.]*/) has a shortcut: '*'.
|
@@ -101,7 +98,6 @@ require 'plezi/handlers/session.rb'
|
|
101
98
|
# accept an implied `params[:id]` variable. the following path ('/'):
|
102
99
|
#
|
103
100
|
# require 'plezi'
|
104
|
-
# listen
|
105
101
|
# route "/", Plezi::StubWSCtrl
|
106
102
|
# # go to: http://localhost:3000/1
|
107
103
|
# # => Plezi::StubRESTCtrl.new.show() # where params[:id] == 1
|
@@ -111,7 +107,6 @@ require 'plezi/handlers/session.rb'
|
|
111
107
|
# Routes are handled in the order they are created. If overlapping routes exist, the first will execute first:
|
112
108
|
#
|
113
109
|
# require 'plezi'
|
114
|
-
# listen
|
115
110
|
# route('*') do |request, response|
|
116
111
|
# response << "Your request, master: #{request.path}." unless request.path.match /cats/
|
117
112
|
# end
|
@@ -134,9 +129,6 @@ require 'plezi/handlers/session.rb'
|
|
134
129
|
# # a timer
|
135
130
|
# PL.run_after 2, -> {puts "this will wait 2 seconds to run... too late. for this example"}
|
136
131
|
#
|
137
|
-
# # an asynchronous method call with an optional callback block
|
138
|
-
# PL.callback(Kernel, :puts, "Plezi will start eating our code once we exit terminal.") {puts 'first output finished'}
|
139
|
-
#
|
140
132
|
# # remember to exit to make it all start
|
141
133
|
# exit
|
142
134
|
#
|
data/lib/plezi/common/api.rb
CHANGED
@@ -5,10 +5,32 @@ module Plezi
|
|
5
5
|
|
6
6
|
# Defines methods used to set up the Plezi app.
|
7
7
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
# Deprecated. use {Plezi.host}.
|
9
|
+
def listen parameters = {}
|
10
|
+
Iodine.warn "listen is deprecated. use `Plezi.host` instead."
|
11
|
+
host parameters.delete(:host) || :default, parameters
|
12
|
+
end
|
13
|
+
|
14
|
+
# adds a route to the last server created
|
15
|
+
def route(path, controller = nil, &block)
|
16
|
+
::Plezi::Base::HTTPRouter.add_route path, controller, &block
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# adds a shared route to all existing services and hosts.
|
21
|
+
def shared_route(path, controller = nil, &block)
|
22
|
+
::Plezi::Base::HTTPRouter.add_shared_route path, controller, &block
|
23
|
+
end
|
24
|
+
|
25
|
+
# public API to add or setup domain names related to the application.
|
26
|
+
#
|
27
|
+
# A default host can be created or accessed by using `:default` of false for the host name.
|
28
|
+
#
|
29
|
+
# Accepts:
|
30
|
+
# host_name:: the name (domain name) of the host as a String object. Use the Symbol `:default` for the catch-all domain name.
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# The options is a Hash object with any of the following options (Hash keys):
|
12
34
|
# alias:: a String or an Array of Strings which represent alternative host names (i.e. `alias: ["admin.google.com", "admin.gmail.com"]`).
|
13
35
|
# public:: the public root folder. if this is defined, static files will be served from this folder and all it's sub-folders. Plezi does NOT support file indexing.
|
14
36
|
# assets:: the assets root folder. defaults to nil (no assets support). if the path is defined, assets will be served from `/assets/...` (or the public_asset path defined) before any static files. assets will not be served if the file in the /public/assets folder if up to date (a rendering attempt will be made for systems that allow file writing).
|
@@ -16,9 +38,6 @@ module Plezi
|
|
16
38
|
# assets_callback:: a method that accepts two parameters: (request, response) and renders any custom assets. the method should return `false` unless it had set the response.
|
17
39
|
# save_assets:: saves the rendered assets to the filesystem, under the public folder. defaults to false.
|
18
40
|
# templates:: the templates root folder. defaults to nil (no template support). templates can be rendered by a Controller class, using the `render` method.
|
19
|
-
# ssl:: if true, an SSL service will be attempted. if no certificate is defined, an attempt will be made to create a self signed certificate.
|
20
|
-
# ssl_key:: the public key for the SSL service.
|
21
|
-
# ssl_cert:: the certificate for the SSL service.
|
22
41
|
#
|
23
42
|
# Assets:
|
24
43
|
#
|
@@ -31,109 +50,37 @@ module Plezi
|
|
31
50
|
#
|
32
51
|
# Plezi's controller.render ERB, Slim and Haml are natively supported.
|
33
52
|
#
|
34
|
-
# @return [Plezi::
|
35
|
-
#
|
36
|
-
def listen parameters = {}
|
37
|
-
# update default values
|
38
|
-
parameters[:index_file] ||= 'index.html'
|
39
|
-
parameters[:assets_public] ||= '/assets'
|
40
|
-
parameters[:assets_public].chomp! '/'
|
41
|
-
parameters[:public] ||= parameters[:root] # backwards compatability
|
42
|
-
puts "Warning: 'root' option is being depracated. use 'public' instead." if parameters[:root]
|
43
|
-
|
44
|
-
# check if the port is used twice.
|
45
|
-
@routers_locker.synchronize do
|
46
|
-
@active_router = GRHttp.listen(parameters)
|
47
|
-
unless @active_router[:upgrade_handler]
|
48
|
-
@routers << (@active_router[:http_handler] = ::Plezi::Base::HTTPRouter.new)
|
49
|
-
@active_router[:upgrade_handler] = @active_router[:http_handler].upgrade_proc
|
50
|
-
else
|
51
|
-
@active_router.delete :alias
|
52
|
-
end
|
53
|
-
@active_router[:http_handler].add_host(parameters[:host], @active_router.merge(parameters) )
|
54
|
-
@active_router = @active_router[:http_handler]
|
55
|
-
end
|
56
|
-
# return the current handler or the protocol..
|
57
|
-
@active_router
|
58
|
-
end
|
59
|
-
|
60
|
-
# clears all the listeners and routes defined
|
61
|
-
def clear_app
|
62
|
-
@routers_locker.synchronize {GReactor.clear_listeners; @routers.clear}
|
63
|
-
end
|
64
|
-
# adds a route to the last server created
|
65
|
-
def route(path, controller = nil, &block)
|
66
|
-
raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
|
67
|
-
@routers_locker.synchronize { @active_router.add_route path, controller, &block }
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
# adds a shared route to all existing services and hosts.
|
72
|
-
def shared_route(path, controller = nil, &block)
|
73
|
-
raise "Must have created at least one Pleze service before calling `shared_route` - use `Plezi.listen`." unless @routers
|
74
|
-
@routers_locker.synchronize { @routers.each {|r| r.add_shared_route path, controller, &block } }
|
75
|
-
end
|
76
|
-
|
77
|
-
# adds a host to the last server created
|
53
|
+
# @return [::Plezi::Base::HTTPRouter]
|
78
54
|
#
|
79
|
-
# accepts a host name and a parameter(s) Hash which are the same parameter(s) as {Plezi.listen} accepts:
|
80
55
|
def host(host_name, params)
|
81
|
-
|
82
|
-
@routers_locker.synchronize { @active_router.add_host host_name, params }
|
83
|
-
end
|
84
|
-
|
85
|
-
# starts the Plezi framework server and hangs until the exit signal is given.
|
86
|
-
def start
|
87
|
-
start_async
|
88
|
-
puts "\nPress ^C to exit.\n"
|
89
|
-
GReactor.join { puts "\r\nStarting shutdown sequesnce. Press ^C to force quit."}
|
56
|
+
::Plezi::Base::HTTPRouter.add_host host_name, params
|
90
57
|
end
|
91
58
|
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# This method is a both a fail safe and a shortcut. Plezi will automatically attempt to diable autostart when discovering Rack
|
95
|
-
# but this method also makes sure that the GRHttp is set as the Rack server by setting the ENV\["RACK_HANDLER"] variable.
|
96
|
-
#
|
97
|
-
# This is used as an alternative to {Plezi.start_placebo}.
|
98
|
-
#
|
99
|
-
# Use {Plezi.start_placebo} to augment an existing app while operating Plezi on a different process or server.
|
100
|
-
#
|
101
|
-
# Use {Plezi.start_rack} to augment an existing Rack app (i.e. Rails/Sinatra) by loading both Plezi and the existing Rack app
|
102
|
-
# to the GRHtto server (it will set up GRHttp as the Rack server).
|
103
|
-
def start_rack
|
104
|
-
Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
|
105
|
-
ENV["RACK_HANDLER"] = 'grhttp'
|
106
|
-
end
|
107
|
-
# starts the Plezi framework and returns immidiately,
|
108
|
-
# allowing you to run the Plezi framework along side another framework.
|
109
|
-
def start_async
|
110
|
-
Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
|
111
|
-
return GReactor.start if GReactor.running?
|
112
|
-
puts "Starting Plezi #{Plezi::VERSION} Services using GRHttp #{GRHttp::VERSION} and GReactor #{GReactor::VERSION}."
|
113
|
-
GReactor.on_shutdown { puts "Plezi shutdown. It was fun to serve you." }
|
114
|
-
GReactor.start ::Plezi::Settings.max_threads
|
115
|
-
end
|
116
|
-
# This allows you to run the Plezi framework along side another framework - WITHOUT running the actual server.
|
59
|
+
# This allows you to use the Plezi framework's code inside your existing Rack application - WITHOUT running the actual server.
|
117
60
|
#
|
118
61
|
# The server will not be initiatet and instead you will be able to use Plezi controllers and the Redis auto-config
|
119
|
-
# to broadcast Plezi messages to other Plezi processes - allowing for scalable intigration of Plezi into
|
120
|
-
def start_placebo
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
62
|
+
# to broadcast Plezi messages to other Plezi processes - allowing for scalable intigration of Plezi into existing Rack applications.
|
63
|
+
def start_placebo receiver = nil
|
64
|
+
# force start Iodine only if Iodine isn't used as the server
|
65
|
+
if ::Iodine.protocol == ::Iodine::Http::Http1 && (defined?(::Rack) ? (::Rack::Handler.default == ::Iodine::Http::Rack) : true)
|
66
|
+
# Iodine.info("`start_placebo` is called while using the Iodine server. `start_placebo` directive being ignored.")
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
unless @placebo_initialized
|
70
|
+
raise "Placebo fatal error: Redis connection failed to load - make sure gem is required and `ENV['PL_REDIS_URL']` is set." unless redis # make sure the redis connection is activated
|
71
|
+
puts "* Plezi #{Plezi::VERSION} Services will start with no Server...\n"
|
72
|
+
::Iodine.protocol = :no_server
|
73
|
+
Iodine.force_start!
|
74
|
+
@placebo_initialized = true
|
75
|
+
end
|
76
|
+
receiver ? Plezi::Placebo.new(receiver) : true
|
125
77
|
end
|
126
78
|
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
@active_router = nil
|
132
|
-
@routers_locker = Mutex.new
|
133
|
-
@routers ||= [].to_set
|
79
|
+
# deprecation notice
|
80
|
+
def start_rack
|
81
|
+
Iodine.warn "`start_rack` is deprecated. There is no need to call this method."
|
82
|
+
end
|
134
83
|
end
|
135
84
|
|
136
85
|
Encoding.default_internal = 'utf-8'
|
137
86
|
Encoding.default_external = 'utf-8'
|
138
|
-
|
139
|
-
Object.const_set("NO_PLEZI_AUTO_START", true) if defined?(::Rack::Builder) && !defined?(NO_PLEZI_AUTO_START)
|