plezi 0.14.4 → 0.14.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/bin/ws_shootout +30 -0
- data/exe/plezi +108 -108
- data/lib/plezi.rb +18 -26
- data/lib/plezi/activation.rb +16 -16
- data/lib/plezi/api.rb +51 -50
- data/lib/plezi/controller/controller.rb +249 -229
- data/lib/plezi/controller/controller_class.rb +189 -174
- data/lib/plezi/controller/cookies.rb +49 -47
- data/lib/plezi/helpers.rb +35 -35
- data/lib/plezi/render/erb.rb +25 -26
- data/lib/plezi/render/has_cache.rb +31 -31
- data/lib/plezi/render/markdown.rb +53 -53
- data/lib/plezi/render/render.rb +36 -38
- data/lib/plezi/render/sass.rb +43 -44
- data/lib/plezi/render/slim.rb +25 -25
- data/lib/plezi/router/adclient.rb +14 -15
- data/lib/plezi/router/assets.rb +59 -61
- data/lib/plezi/router/errors.rb +22 -22
- data/lib/plezi/router/route.rb +98 -100
- data/lib/plezi/router/router.rb +120 -113
- data/lib/plezi/version.rb +1 -1
- data/lib/plezi/websockets/message_dispatch.rb +118 -80
- data/lib/plezi/websockets/redis.rb +42 -43
- data/plezi.gemspec +3 -3
- data/resources/client.js +229 -204
- data/resources/ctrlr.rb +26 -26
- data/resources/mini_app.rb +1 -1
- data/resources/simple-client.js +50 -43
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f914fd397c3ff4c119da17c2a97ad294813e7a1
|
4
|
+
data.tar.gz: c8cce257a36d1ee92512ef4a38cd1432f847a4fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bdfdb162d587f8ab5f79267180d2395ca46491de8cb10d95f3db8749b4b00b2f5106229854b53cd6c3b06edf91f6f8432eb38ed212d547d7f9c3c2f208b8184
|
7
|
+
data.tar.gz: 3bb3173130fa9c20e26aecb4fbae2417ba3cfd1627b35974f0b216f3fb54997bf4d418f148eea9307f07e09e8971b33b38130cf7da53d18031e03ee093386b4a
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.14.5
|
6
|
+
|
7
|
+
**Fix**: Fixed Plezi client issues related to the code beautifier moving things around.
|
8
|
+
|
9
|
+
**Fix**: Fixed a possible issue with unicasting (sending a message to a specific connection).
|
10
|
+
|
11
|
+
**Styling**: styling updated and some indentation fixed with the help of Rubocop.
|
12
|
+
|
13
|
+
**Misc**: minor refactoring of our message dispatch logic and other minor prevents temporary empty arrays from being created when possible.
|
14
|
+
|
15
|
+
***
|
16
|
+
|
5
17
|
Change log v.0.14.4
|
6
18
|
|
7
19
|
**Fix**: fixed an issue were scaling using `fork` or server workers would break the automatic scaling feature. The issue was caused by the pub/Sub channel ID of the new processes being identical to the origin process. Credit to Vladimir Dementyev (@palkan) for exposing this issue. This did not seem to effect applications that scaled up with independent processes / machines, such as applications that scaled up using "dynos" on Heroku.
|
data/bin/ws_shootout
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# # Uncomment and set Redis URL for automatic scalling across proccesses and machines:
|
4
|
+
# require 'redis'
|
5
|
+
# ENV['PL_REDIS_URL'] ||= "redis://localhost:7777/0"
|
6
|
+
# ENV['PL_REDIS_URL'] ||= "redis://:password@my.host:6389/0"
|
7
|
+
|
8
|
+
Dir.chdir(File.expand_path(File.join('..', '..', 'lib'), __FILE__))
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'plezi'
|
11
|
+
class ShootoutApp
|
12
|
+
# the default HTTP response
|
13
|
+
def index
|
14
|
+
"This application should be used with the websocket-shootout benchmark utility."
|
15
|
+
end
|
16
|
+
# we won't be using AutoDispatch, but directly using the `on_message` callback.
|
17
|
+
def on_message data
|
18
|
+
cmd, payload = JSON(data).values_at('type', 'payload')
|
19
|
+
if cmd == 'echo'
|
20
|
+
write({type: 'echo', payload: payload}.to_json)
|
21
|
+
else
|
22
|
+
ShootoutApp.write2everyone({type: 'broadcast', payload: payload}.to_json)
|
23
|
+
write({type: "broadcastResult", payload: payload}.to_json)
|
24
|
+
end
|
25
|
+
rescue
|
26
|
+
puts "Incoming message format error - not JSON?"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Plezi.route '*', ShootoutApp
|
data/exe/plezi
CHANGED
@@ -6,106 +6,106 @@ require 'securerandom'
|
|
6
6
|
######################################################################
|
7
7
|
# tweek the string class for termial coloring options
|
8
8
|
class String
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
# colorization
|
10
|
+
def colorize(color_code)
|
11
|
+
"\e[#{color_code}m#{self}\e[0m"
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def red
|
15
|
+
colorize(31)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def green
|
19
|
+
colorize(32)
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def yellow
|
23
|
+
colorize(33)
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
def pink
|
27
|
+
colorize(35)
|
28
|
+
end
|
29
29
|
end
|
30
30
|
|
31
31
|
module Builder
|
32
|
-
|
32
|
+
Root ||= Pathname.new(File.dirname(__FILE__)).expand_path.join('..')
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
def self.app_tree
|
35
|
+
@app_tree ||= {}.dup
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
def self.write_files(files, parent = '.')
|
39
|
+
if files.is_a? Hash
|
40
|
+
files.each do |k, v|
|
41
|
+
if v.is_a? Hash
|
42
|
+
begin
|
43
|
+
Dir.mkdir k
|
44
|
+
puts " created #{parent}/#{k}".green
|
45
|
+
rescue => e
|
46
|
+
puts " exists #{parent}/#{k}".red
|
47
|
+
end
|
48
|
+
Dir.chdir k
|
49
|
+
write_files v, (parent + '/' + k)
|
50
|
+
Dir.chdir '..'
|
51
|
+
elsif v.is_a? String
|
52
|
+
if ::File.exist? k
|
53
|
+
puts " EXISTS(!) #{parent}/#{k}".red
|
54
|
+
else
|
55
|
+
IO.write k, v
|
56
|
+
puts " wrote #{parent}/#{k}".yellow
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
59
60
|
end
|
60
|
-
|
61
|
-
end
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
63
|
+
def self.create_app(app_name = ARGV[1])
|
64
|
+
require Root.join('lib', 'plezi', 'version')
|
65
|
+
app_tree[app_name.to_s] ||= IO.read(Root.join('resources', 'mini_exec')).gsub('appname', app_name)
|
66
|
+
app_tree["#{app_name}.rb"] ||= IO.read(Root.join('resources', 'mini_app.rb')).gsub('appname', app_name).gsub('appsecret', "#{app_name}_#{SecureRandom.hex}")
|
67
|
+
app_tree['routes.rb'] ||= IO.read(Root.join('resources', 'routes.rb')).gsub('appname', app_name)
|
68
|
+
app_tree['config.ru'] ||= IO.read(Root.join('resources', 'config.ru')).gsub('appname', app_name)
|
69
|
+
app_tree['Procfile'] ||= IO.read(Root.join('resources', 'procfile')).gsub('appname', app_name)
|
70
|
+
app_tree['Gemfile'] ||= ''
|
71
|
+
app_tree['Gemfile'] << "source 'https://rubygems.org'\n\n# include the basic plezi framework and server\ngem 'plezi', '~> #{Plezi::VERSION}'\n"
|
72
|
+
app_tree['Gemfile'] << IO.read(Root.join('resources', 'gemfile'))
|
73
|
+
app_tree['Gemfile'] << "\n\nruby '#{RUBY_VERSION}'\n"
|
74
|
+
app_tree['rakefile'] ||= IO.read(Root.join('resources', 'rakefile'))
|
75
|
+
app_tree['app'] ||= {}
|
76
|
+
app_tree['app']['my_controler.rb'] ||= IO.read(Root.join('resources', 'ctrlr.rb')).gsub('appname', app_name)
|
77
|
+
app_tree['views'] ||= {}
|
78
|
+
app_tree['views']['welcome.html.erb'] ||= IO.read(Root.join('resources', 'mini_welcome_page.html')).gsub('appname', app_name)
|
79
|
+
app_tree['views']['404.html.erb'] ||= IO.read(Root.join('resources', '404.erb'))
|
80
|
+
app_tree['views']['500.html.erb'] ||= IO.read(Root.join('resources', '500.erb'))
|
81
|
+
app_tree['views']['503.html'] ||= IO.read(Root.join('resources', '503.html'))
|
82
|
+
app_tree['public'] ||= {}
|
83
|
+
app_tree['public']['javascripts'] ||= {}
|
84
|
+
app_tree['public']['javascripts']['client.js'] ||= IO.read(Root.join('resources', 'client.js')).gsub('appname', app_name)
|
85
|
+
app_tree['public']['javascripts']['simple-client.js'] ||= IO.read(Root.join('resources', 'simple-client.js')).gsub('appname', app_name)
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
87
|
+
begin
|
88
|
+
Dir.mkdir app_name
|
89
|
+
puts "created the #{app_name} application directory.".green
|
90
|
+
rescue => e
|
91
|
+
puts "the #{app_name} application directory exists - trying to rebuild (no overwrite).".pink
|
92
|
+
end
|
93
|
+
Dir.chdir app_name
|
94
|
+
puts 'starting to write template data...'.red
|
95
|
+
puts ''
|
96
|
+
Builder.write_files app_tree
|
97
|
+
begin
|
98
|
+
File.chmod 0o775, app_name.to_s
|
99
|
+
rescue
|
100
|
+
true
|
101
|
+
end
|
102
|
+
puts 'done.'
|
103
|
+
puts ''
|
104
|
+
puts "please change directory into the app directory: cd #{app_name}"
|
105
|
+
puts ''
|
106
|
+
puts "run the #{app_name} app using: ./#{app_name} or using the iodine / rackup commands."
|
107
|
+
puts ''
|
108
|
+
end
|
109
109
|
end
|
110
110
|
|
111
111
|
######################################################################
|
@@ -121,25 +121,25 @@ end
|
|
121
121
|
# require 'optparser'
|
122
122
|
|
123
123
|
if ARGV[0] == 'new' || ARGV[0] == 'n' || ARGV[0] == 'force'
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
124
|
+
#########
|
125
|
+
## set up building environment
|
126
|
+
ARGV[1] = ARGV[1].gsub(/[^a-zA-Z0-9]/, '_')
|
127
|
+
ARGV[1].downcase!
|
128
|
+
if Dir.exist?(ARGV[1]) && ARGV[0] != 'force'
|
129
|
+
puts ''
|
130
|
+
puts "WARNING: app/folder alread exists, use `plezi fource #{ARGV[1]}` to attempt rebuild (no files will be overwritten).".red
|
131
|
+
puts ''
|
132
|
+
exit
|
133
|
+
end
|
134
|
+
Builder.create_app
|
135
135
|
else
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
136
|
+
puts ''
|
137
|
+
puts 'Plezi fast web app starter.'.pink
|
138
|
+
puts 'use: plezi new appname'
|
139
|
+
puts 'or: plezi n appname'
|
140
|
+
puts ''
|
141
|
+
puts "Run the app using the app's script with an optional: -p {port number}. i.e."
|
142
|
+
puts ' cd ./appname'.pink
|
143
|
+
puts ' ./appname -p 8080'.pink
|
144
|
+
puts ''
|
145
145
|
end
|
data/lib/plezi.rb
CHANGED
@@ -1,34 +1,26 @@
|
|
1
|
-
|
1
|
+
# standard library used by Plezi
|
2
|
+
require 'json'
|
3
|
+
require 'erb'
|
4
|
+
require 'thread'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'set'
|
7
|
+
require 'securerandom'
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
require 'rack'
|
11
|
+
require 'rack/query_parser.rb'
|
2
12
|
require 'iodine'
|
3
13
|
|
14
|
+
require 'plezi/version'
|
4
15
|
require 'plezi/api'
|
5
16
|
require 'plezi/controller/controller'
|
6
17
|
|
7
18
|
# Plezi is amazing. Read the {README}
|
8
19
|
module Plezi
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
20
|
+
# Shhh... the modules and classes defined under the {Base} namespace are sleeping...
|
21
|
+
#
|
22
|
+
# The namespace signifies that Plezi uses these modules and classes internally.
|
23
|
+
# We don't need to worry about these unless we're monkey-patching stuff or contributing to the Plezi project.
|
24
|
+
module Base
|
25
|
+
end
|
15
26
|
end
|
16
|
-
|
17
|
-
###############
|
18
|
-
## Dev notes.
|
19
|
-
###############
|
20
|
-
#
|
21
|
-
# Plezi 0.13.0 is heaviliy Rack based. Whenever Possible, Rack middleware was preffered.
|
22
|
-
# The is a list of available Rack middleware:
|
23
|
-
# * https://github.com/rack/rack/wiki/List-of-Middleware
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# def uuid
|
30
|
-
# @uuid ||= SecureRandom.uuid
|
31
|
-
# end
|
32
|
-
# def redis_channel_name
|
33
|
-
# @redis_channel_name ||= "#{File.basename($0, '.*')}_redis_channel"
|
34
|
-
# end
|
data/lib/plezi/activation.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
require 'plezi/websockets/message_dispatch' unless defined?(::Plezi::Base::MessageDispatch)
|
2
2
|
|
3
3
|
module Plezi
|
4
|
-
|
4
|
+
protected
|
5
5
|
|
6
6
|
@plezi_finalize = nil
|
7
7
|
def plezi_finalize
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
if @plezi_finalize.nil?
|
9
|
+
@plezi_finalize = true
|
10
|
+
@plezi_finalize = 1
|
11
|
+
end
|
12
12
|
end
|
13
13
|
@plezi_initialize = nil
|
14
14
|
def self.plezi_initialize
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
if @plezi_initialize.nil?
|
16
|
+
@plezi_initialize = true
|
17
|
+
@plezi_autostart = true if @plezi_autostart.nil?
|
18
|
+
puts "WARNNING: auto-scaling with redis is set using ENV['PL_REDIS_URL'.freeze]\r\n but the Redis gem isn't included! - SCALING IS IGNORED!" if ENV['PL_REDIS_URL'.freeze] && !defined?(::Redis)
|
19
|
+
at_exit do
|
20
|
+
next if @plezi_autostart == false
|
21
|
+
::Iodine::Rack.app = ::Plezi.app
|
22
|
+
::Iodine.start
|
23
|
+
end
|
24
|
+
end
|
25
|
+
true
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/lib/plezi/api.rb
CHANGED
@@ -3,60 +3,61 @@ require 'plezi/helpers'
|
|
3
3
|
require 'plezi/router/router'
|
4
4
|
|
5
5
|
module Plezi
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
# Plezi is amazing. Read the {README}
|
7
|
+
class << self
|
8
|
+
# Get / set the template folder for the {Controller#render} function.
|
9
|
+
attr_accessor :templates
|
10
|
+
# Get / set the assets folder for the `:assets` route (the root for `Plezi.route '/assets/path'`, :assets).
|
11
|
+
attr_accessor :assets
|
12
|
+
# Get / set the application name, which is used to create and identify the application's global pub/sub channel when using Redis.
|
13
|
+
attr_accessor :app_name
|
14
|
+
end
|
15
|
+
@app_name = "#{File.basename($PROGRAM_NAME, '.*')}_app"
|
16
|
+
@templates = File.expand_path(File.join(File.dirname($PROGRAM_NAME), 'views'.freeze))
|
17
|
+
@assets = File.expand_path(File.join(File.dirname($PROGRAM_NAME), 'assets'.freeze))
|
18
|
+
@plezi_autostart = nil
|
18
19
|
|
19
|
-
|
20
|
+
module_function
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
# Disables the autostart feature
|
23
|
+
def no_autostart
|
24
|
+
@plezi_autostart = false
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
# @private
|
28
|
+
# Allows Plezi to be used as middleware.
|
29
|
+
def new(app, *_args)
|
30
|
+
Plezi::Base::Router.new(app)
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
# Returns the Plezi Rack application
|
34
|
+
def app
|
35
|
+
no_autostart
|
36
|
+
puts "Running Plezi version: #{::Plezi::VERSION}"
|
37
|
+
Plezi::Base::Router.call_method
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
40
|
+
# Will add a route to the Plezi application.
|
41
|
+
#
|
42
|
+
# The order of route creation is the order of precedence.
|
43
|
+
#
|
44
|
+
# path:: the HTTP path for the route. Inline parameters and optional parameters are supported. i.e.
|
45
|
+
#
|
46
|
+
# Plezi.route '/fixed/path', controller
|
47
|
+
# Plezi.route '/fixed/path/:required_param/(:optional_param)', controller
|
48
|
+
# Plezi.route '/(:format)', /^(html|json|xml)$/ # a rewrite route, usally on top.
|
49
|
+
# Plezi.route '*', controller # catch all
|
50
|
+
#
|
51
|
+
#
|
52
|
+
# controller:: A Controller class or one of the included controllers: `false` for rewrite routes; `:client` for the Javascript Auto Dispatch client; `:assets` for a missing asset baker controller (bakes any unbaked assets into the public folder file).
|
53
|
+
def route(path, controller)
|
54
|
+
plezi_initialize
|
55
|
+
Plezi::Base::Router.route path, controller
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
# Will make a weak attempt to retrive a string representing a valid URL for the requested Controller's function.
|
59
|
+
# False positives (invalid URL strings) are possible (i.e., when requesting a URL of a method that doesn't exist).
|
60
|
+
def url_for(controller, method_sym, params = {})
|
61
|
+
Plezi::Base::Router.url_for controller, method_sym, params
|
62
|
+
end
|
62
63
|
end
|