plezi 0.10.8 → 0.10.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c504b33f40bbc1d8235c5d48101abab00a0facac
4
- data.tar.gz: 5fad18c3d52af38f9ecc94cb899c337b54a3afdd
3
+ metadata.gz: ef2d6297c599601166b2e26a419ad02b89b10ecb
4
+ data.tar.gz: e5f255998404493dff97e3d5ab4e17583b391d10
5
5
  SHA512:
6
- metadata.gz: c4f6a25bfa2846fd8ea384b741ee754673c3ecc6384402b9bd8c0766dea71ab0cc9711723ccaf38f20934fbf0b0f05c3c409850aa427a9d87f26775467b7382e
7
- data.tar.gz: db2844de88d6dae7a1e019b4ec46fde5f33f4342484e38d5dc03f9aa9e5cc70c897ace96b4fed46f92bfd7e8c4d572f2e4bdc4952caa7dc0b283d93a01c1aaea
6
+ metadata.gz: a8a372f2af85a2f3c24985ea15db19c1b4ab7f96f31a10c0dda71a0b4f7697c934aeabfb7738877bc39d3319dc4e9d058dfd798847c745cd7d858f19837a1da9
7
+ data.tar.gz: 09c07532144ab34453cde96ba66d7b2650b85722f62aac4b724365ccfde4b010c2296e8b704021d41baeda84745a739e0ddf50f01a04d90a30e1c73998349309
@@ -2,6 +2,14 @@
2
2
 
3
3
  ***
4
4
 
5
+ Change log v.0.10.9
6
+
7
+ **Minor**: minor update to the cache system, might improve performance somewhat and might fix rare issues related to some binary files. Updated GRHttp server version required.
8
+
9
+ **Fix**: fixed an issue with Placebo listeners where they might be thrown from the IO stack and thereby stop listening ()or, alternatively, consume CPU) . This issue was caused by GReactor's 'BasicIO#clear?' code enforcing two-way connectivity.
10
+
11
+ ***
12
+
5
13
  Change log v.0.10.8
6
14
 
7
15
  **Fix**: Fixed an issue with the new websocket upgrade handler. It is unclear how come the issue did not show up during the testing.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Plezi, The Rack Free Ruby framework for realtime web-apps
2
2
  [![Gem Version](https://badge.fury.io/rb/plezi.svg)](http://badge.fury.io/rb/plezi)
3
- [![Inline docs](http://inch-ci.org/github/boazsegev/plezi.svg?branch=master)](http://www.rubydoc.info/gems/plezi/)
3
+ [![Inline docs](http://inch-ci.org/github/boazsegev/plezi.svg?branch=master)](http://www.rubydoc.info/github/boazsegev/plezi/master)
4
4
 
5
5
  > People who are serious about their frameworks, should write their own servers...
6
6
 
7
- Find more info on [Plezi's framework documentation](http://www.rubydoc.info/gems/plezi/)
7
+ Find more info on [Plezi's framework documentation](http://www.rubydoc.info/github/boazsegev/plezi/master)
8
8
 
9
9
  ## About the Plezi framework
10
10
 
@@ -2,11 +2,15 @@
2
2
  module Plezi
3
3
 
4
4
  # File and Object Caching for Plezi
5
+ #
6
+ # Be aware that the cache is local, per process. It's possible to limit file caching by limiting the supported_types in Plezi::Cache::CACHABLE.
7
+ #
8
+ # Template rendering engines are always cached.
5
9
  module Cache
6
10
  # contains the cached data, in the format: CACHE_STORE["filename"] = CacheObject
7
11
  CACHE_STORE = {}
8
12
  CACHE_LOCK = Mutex.new
9
- CACHABLE = %w{cache object slim haml css map js html scss sass coffee txt xml json yaml rb}
13
+ CACHABLE = (%w{cache object slim haml css map js html scss sass coffee txt xml json yaml rb}).to_set
10
14
 
11
15
  @cache_to_disk = true
12
16
 
@@ -17,7 +21,8 @@ module Plezi
17
21
 
18
22
  # initialize a Cached object
19
23
  def initialize d = nil, t = Time.now
20
- @data, @mtime = d, t
24
+ @data = t
25
+ @mtime = d
21
26
  end
22
27
  end
23
28
 
@@ -34,16 +39,16 @@ module Plezi
34
39
  # force a file onto the cache (only if it is cachable - otherwise will load the file but will not cache it).
35
40
  def reload_file filename
36
41
  if CACHABLE.include? filename.match(/\.([^\.]+)$/)[1]
37
- return cache_data filename, IO.read(filename), File.mtime(filename)
42
+ return cache_data filename, IO.binread(filename), File.mtime(filename)
38
43
  else
39
- return IO.read(filename)
44
+ return IO.binread(filename)
40
45
  end
41
46
  end
42
47
  # places data into the cache, and attempts to save the data to a file name.
43
48
  def save_file filename, data, save_to_disk = false
44
49
  cache_data filename, data if CACHABLE.include? filename.match(/\.([^\.]+)$/)[1]
45
50
  begin
46
- IO.write filename, data if save_to_disk
51
+ IO.binwrite filename, data if save_to_disk
47
52
  rescue Exception => e
48
53
  Plezi.warn("File couldn't be written (#{filename}) - file system error?")
49
54
  end
@@ -14,7 +14,6 @@ module Plezi
14
14
  #
15
15
  # use the`listen`, `host` and `route` functions rather then accessing this object.
16
16
  #
17
- @servers = {}
18
17
  @active_router = nil
19
18
 
20
19
 
@@ -98,8 +97,7 @@ module Plezi
98
97
 
99
98
  # adds a host to the last server created
100
99
  #
101
- # accepts the same parameter(s) as the `listen` command (see Plezi.add_service), except :protocol and :handler are ignored:
102
- # alias:: a String or an Array of Strings which represent alternative host names (i.e. `alias: ["admin.google.com", "admin.gmail.com"]`).
100
+ # accepts a host name and a parameter(s) Hash which are the same parameter(s) as {Plezi.listen} accepts:
103
101
  def host(host_name, params)
104
102
  raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
105
103
  @active_router.add_host host_name, params
@@ -26,10 +26,10 @@ module Plezi
26
26
  # the request object, class: HTTPRequest.
27
27
  attr_reader :request
28
28
 
29
- # the ::params variable contains all the parameters set by the request (/path?locale=he => params["locale"] == "he").
29
+ # the :params variable contains all the parameters set by the request (/path?locale=he => params ["locale"] == "he").
30
30
  attr_reader :params
31
31
 
32
- # a cookie-jar to get and set cookies (set: `cookie\[:name] = data` or get: `cookie\[:name]`).
32
+ # a cookie-jar to get and set cookies (set: `cookie [:name] = data` or get: `cookie [ :name ]`).
33
33
  #
34
34
  # Cookies and some other data must be set BEFORE the response's headers are sent.
35
35
  attr_reader :cookies
@@ -37,7 +37,7 @@ module Plezi
37
37
  # the HTTPResponse **OR** the WSResponse object that formats the response and sends it. use `response << data`. This object can be used to send partial data (such as headers, or partial html content) in blocking mode as well as sending data in the default non-blocking mode.
38
38
  attr_reader :response
39
39
 
40
- # the ::flash is a little bit of a magic hash that sets and reads temporary cookies.
40
+ # the :flash is a little bit of a magic hash that sets and reads temporary cookies.
41
41
  # these cookies will live for one successful request to a Controller and will then be removed.
42
42
  attr_reader :flash
43
43
 
@@ -166,11 +166,11 @@ module Plezi
166
166
  I18n.locale = options[:locale] || I18n.default_locale if defined?(I18n) # sets the locale to nil for default behavior even if the locale was set by a previous action - removed: # && options[:locale]
167
167
  # find template and create template object
168
168
  filename = template.is_a?(String) ? File.join( host_params[:templates].to_s, template) : (File.join( host_params[:templates].to_s, *template.to_s.split('_')) + (options[:type].empty? ? '': ".#{options[:type]}") + '.slim')
169
- return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( Slim::Template.new() { IO.read filename } ) ) : (Plezi.get_cached filename) ).render(self, &block) if defined?(::Slim) && Plezi.file_exists?(filename)
169
+ return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( Slim::Template.new() { IO.binread filename } ) ) : (Plezi.get_cached filename) ).render(self, &block) if defined?(::Slim) && Plezi.file_exists?(filename)
170
170
  filename.gsub! /\.slim$/, '.haml'
171
- return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( Haml::Engine.new( IO.read(filename) ) ) ) : (Plezi.get_cached filename) ).render(self, &block) if defined?(::Haml) && Plezi.file_exists?(filename)
171
+ return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( Haml::Engine.new( IO.binread(filename) ) ) ) : (Plezi.get_cached filename) ).render(self, &block) if defined?(::Haml) && Plezi.file_exists?(filename)
172
172
  filename.gsub! /\.haml$/, '.erb'
173
- return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( ERB.new( IO.read(filename) ) ) ) : (Plezi.get_cached filename) ).result(binding, &block) if defined?(::ERB) && Plezi.file_exists?(filename)
173
+ return ( Plezi.cache_needs_update?(filename) ? Plezi.cache_data( filename, ( ERB.new( IO.binread(filename) ) ) ) : (Plezi.get_cached filename) ).result(binding, &block) if defined?(::ERB) && Plezi.file_exists?(filename)
174
174
  return false
175
175
  end
176
176
 
@@ -38,7 +38,7 @@ module Plezi
38
38
  @sass_cache = Sass::CacheStores::Memory.new if defined?(::Sass)
39
39
  end
40
40
 
41
- # adds a host to the router (or activates an existing host to add new routes). accepts a host name and any parameters not related to the service (see `Plezi.add_service`)
41
+ # adds a host to the router (or activates an existing host to add new routes). accepts a host name and any parameters not related to the actual connection (ssl etc') (see {Plezi.listen})
42
42
  def add_host host_name, params = {}
43
43
  host_name = (host_name ? host_name.to_s.downcase : :default)
44
44
  @active_host = get_host(host_name) || ( @hosts[host_name] = Host.new(params) )
@@ -142,7 +142,7 @@ module Plezi
142
142
  if defined?(::CoffeeScript) && Plezi.cache_needs_update?(coffee)
143
143
  # render coffee to cache
144
144
  Plezi.cache_data coffee, nil
145
- Plezi.save_file target_file, CoffeeScript.compile(IO.read coffee), params[:save_assets]
145
+ Plezi.save_file target_file, CoffeeScript.compile(IO.binread coffee), params[:save_assets]
146
146
  end
147
147
  # try to send the cached js file which started the request.
148
148
  return Base::HTTPSender.send_file request, response, target_file
@@ -40,6 +40,12 @@ module Plezi
40
40
  @io[:websocket_handler] = self
41
41
  super()
42
42
  end
43
+ # notice of disconnect
44
+ def on_close
45
+ return super() if defined? super
46
+ GR.warn "Placebo #{self.class.superclass.name} disconnected. Ignore if this message appears during shutdown."
47
+ end
48
+
43
49
  # handles broadcasts / unicasts
44
50
  def on_broadcast ws
45
51
  data = ws.data
@@ -91,6 +97,19 @@ module Plezi
91
97
  end
92
98
  end
93
99
  end
100
+ class PlaceboIO < GReactor::BasicIO
101
+ def clear?
102
+ io.closed?
103
+ end
104
+ def call
105
+ self.read
106
+ GR.warn "Placebo IO recieved IO signal - this is unexpected..."
107
+ end
108
+ def on_disconnect
109
+ @params[:out].close rescue nil
110
+ @cache[:websocket_handler].on_close if @cache[:websocket_handler]
111
+ end
112
+ end
94
113
  end
95
114
  module_function
96
115
  def new placebo_class
@@ -104,8 +123,8 @@ module Plezi
104
123
  Object.const_set(new_class_name, new_class)
105
124
  end
106
125
  i, o = IO.pipe
107
- o.close
108
- io = GReactor.add_io i, handler: (Proc.new {|io| io.read })
126
+ io = Placebo::Base::PlaceboIO.new i, out: o
127
+ io = GReactor.add_raw_io i, io
109
128
  new_class.new(io)
110
129
  end
111
130
  end
@@ -12,12 +12,12 @@ module Plezi
12
12
  # sends a response for an error code, rendering the relevent file (if exists).
13
13
  def send_by_code request, response, code, headers = {}
14
14
  begin
15
- base_code_path = request.io[:params][:templates] || File.expand_path('.')
15
+ base_code_path = request.io.params[:templates] || File.expand_path('.')
16
16
  if defined?(::Slim) && Plezi.file_exists?(fn = File.join(base_code_path, "#{code}.html.slim"))
17
17
  Plezi.cache_data fn, Slim::Template.new( fn ) unless Plezi.cached? fn
18
18
  return send_raw_data request, response, Plezi.get_cached( fn ).render( self, request: request ), 'text/html', code, headers
19
19
  elsif defined?(::Haml) && Plezi.file_exists?(fn = File.join(base_code_path, "#{code}.html.haml"))
20
- Plezi.cache_data fn, Haml::Engine.new( IO.read( fn ) ) unless Plezi.cached? fn
20
+ Plezi.cache_data fn, Haml::Engine.new( IO.binread( fn ) ) unless Plezi.cached? fn
21
21
  return send_raw_data request, response, Plezi.get_cached( File.join(base_code_path, "#{code}.html.haml") ).render( self ), 'text/html', code, headers
22
22
  elsif defined?(::ERB) && Plezi.file_exists?(fn = File.join(base_code_path, "#{code}.html.erb"))
23
23
  return send_raw_data request, response, ERB.new( Plezi.load_file( fn ) ).result(binding), 'text/html', code, headers
@@ -1,3 +1,3 @@
1
1
  module Plezi
2
- VERSION = "0.10.8"
2
+ VERSION = "0.10.9"
3
3
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "grhttp", "~> 0.0.11"
21
+ spec.add_dependency "grhttp", "~> 0.0.12"
22
22
  spec.add_development_dependency "bundler", "~> 1.7"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
 
@@ -14,7 +14,7 @@
14
14
  </style>
15
15
  <script>
16
16
  var websocket = NaN;
17
- function connect() { websocket = new WebSocket('ws://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) ) + "/" ); }
17
+ function connect() { websocket = new WebSocket( (window.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) ) + "/" ); }
18
18
  function init()
19
19
  {
20
20
  connect()
@@ -175,7 +175,7 @@ input[type=submit]:active
175
175
  </style>
176
176
  <script type="text/javascript">
177
177
  // Your websocket URI should be an absolute path. The following sets the base URI.
178
- var ws_uri = 'ws://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) );
178
+ var ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) );
179
179
  // remember to add the specific controller's path to your websocket URI.
180
180
  ws_uri += "/";
181
181
  // websocket variable.
@@ -246,6 +246,7 @@ module PleziTestTasks
246
246
  ws = GRHttp::WSClient.connect_to("ws://localhost:3000/ws/placebo") {|ws| 'ME?'}
247
247
  ws << " * Placebo WS connected."
248
248
  sleep 2
249
+ ws.close
249
250
  rescue => e
250
251
  puts " **** Placebo test FAILED TO RUN!!!"
251
252
  puts e
@@ -387,7 +388,7 @@ end
387
388
  r = Plezi::Placebo.new PlaceboCtrl
388
389
  puts " * Create Placebo test: #{PleziTestTasks::RESULTS[r && true]}"
389
390
 
390
- PL.create_logger '/dev/null'
391
+ PL.create_logger nil
391
392
  # PL::Settings.max_threads = 4
392
393
 
393
394
  listen port: 3000
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plezi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.8
4
+ version: 0.10.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.11
19
+ version: 0.0.12
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.11
26
+ version: 0.0.12
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement