unicorn-cuba-base 1.0.0 → 1.1.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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -21,6 +21,7 @@ class Controler < Cuba
21
21
  end
22
22
 
23
23
  require_relative 'unicorn-cuba-base/stats_reporter'
24
+ require_relative 'unicorn-cuba-base/default_error_reporter'
24
25
 
25
26
  class Application
26
27
  def cli(&block)
@@ -90,9 +91,9 @@ class Application
90
91
  access_log_file = @settings.access_log_file.open('a+')
91
92
  access_log_file.sync = true
92
93
  main_controler.use Rack::CommonLogger, access_log_file
94
+ main_controler.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
93
95
  main_controler.use Rack::ErrorHandling
94
96
  main_controler.use Rack::UnhandledRequest
95
- main_controler.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
96
97
 
97
98
  Unicorn::HttpServer.new(main_controler, unicorn_settings).start.join
98
99
  end
@@ -0,0 +1,24 @@
1
+ class DefaultErrorReporter < Controler
2
+ self.define do
3
+ on error Rack::UnhandledRequest::UnhandledRequestError do |error|
4
+ write_error 404, error
5
+ end
6
+
7
+ on error Unicorn::ClientShutdown do |error|
8
+ log.warn 'client disconnected prematurely', error
9
+ raise error
10
+ end
11
+
12
+ on error StandardError do |error|
13
+ log.error "unhandled error while processing request: #{env['REQUEST_METHOD']} #{env['SCRIPT_NAME']}[#{env["PATH_INFO"]}]", error
14
+ log.debug {
15
+ out = StringIO.new
16
+ PP::pp(env, out, 200)
17
+ "Request: \n" + out.string
18
+ }
19
+
20
+ write_error 500, error
21
+ end
22
+ end
23
+ end
24
+
@@ -15,7 +15,7 @@ class MemoryLimit
15
15
  end
16
16
 
17
17
  def read(bytes = nil)
18
- data = @root_limit.get do |max_read_bytes|
18
+ data = @root_limit.get("#{self.class.name} IO read") do |max_read_bytes|
19
19
  if not bytes or bytes > max_read_bytes
20
20
  data = super max_read_bytes
21
21
  raise MemoryLimitedExceededError unless eof?
@@ -28,27 +28,36 @@ class MemoryLimit
28
28
  end
29
29
 
30
30
  def initialize(bytes = 256 * 1024 ** 2)
31
- log.info "using memory limit of #{bytes} bytes" if bytes
31
+ log.info "setting up new memory limit of #{bytes} bytes" if bytes
32
32
  @limit = bytes
33
33
  end
34
34
 
35
35
  attr_reader :limit
36
36
 
37
- def get
37
+ def get(reason = nil)
38
38
  yield(@limit).tap do |data|
39
- borrow data.bytesize if data
39
+ borrow(data.bytesize, reason) if data
40
40
  end
41
41
  end
42
42
 
43
- def borrow(bytes)
44
- log.debug "borrowing #{bytes} from #{@limit} bytes of limit"
43
+ def borrow(bytes, reason = nil)
44
+ if reason
45
+ log.debug "borrowing #{bytes} from #{@limit} bytes of limit for #{reason}"
46
+ else
47
+ log.debug "borrowing #{bytes} from #{@limit} bytes of limit"
48
+ end
49
+
45
50
  bytes > @limit and raise MemoryLimitedExceededError
46
51
  @limit -= bytes
47
52
  bytes
48
53
  end
49
54
 
50
- def return(bytes)
51
- log.debug "returning #{bytes} to #{@limit} bytes of limit"
55
+ def return(bytes, reason = nil)
56
+ if reason
57
+ log.debug "returning #{bytes} to #{@limit} bytes of limit used for #{reason}"
58
+ else
59
+ log.debug "returning #{bytes} to #{@limit} bytes of limit"
60
+ end
52
61
  @limit += bytes
53
62
  bytes
54
63
  end
@@ -1,4 +1,5 @@
1
1
  require 'securerandom'
2
+ require 'json'
2
3
  require 'unicorn-cuba-base/stats'
3
4
 
4
5
  module Plugin
@@ -12,33 +13,39 @@ module Plugin
12
13
  :total_write_error_part
13
14
  )
14
15
 
15
- def write(code, content_type, body)
16
+ def write(code, content_type, body, headers = {})
16
17
  req.body.read # read all remaining upload before we send response so that client will read it
17
18
  res.status = code
18
19
  res["Content-Type"] = content_type
20
+ headers.each do |key, value|
21
+ res[key] = value
22
+ end
19
23
  ResponseHelpers.stats.incr_total_write
20
24
  res.write body
21
25
  end
22
26
 
23
- def write_plain(code, msg)
27
+ def write_text(code, content_type, msg, headers = {})
24
28
  msg = msg.join("\r\n") if msg.is_a? Array
25
- write code, 'text/plain', msg.gsub(/(?<!\r)\n/, "\r\n") + "\r\n"
29
+ write code, content_type, (msg.gsub(/(?<!\r)\n/, "\r\n") + "\r\n"), headers
26
30
  end
27
31
 
28
- def write_url_list(code, msg)
29
- msg = msg.join("\r\n") if msg.is_a? Array
30
- write code, 'text/uri-list', msg.gsub(/(?<!\r)\n/, "\r\n") + "\r\n"
32
+ def write_plain(code, msg, headers = {})
33
+ write_text code, 'text/plain', msg, headers
34
+ end
35
+
36
+ def write_url_list(code, msg, headers = {})
37
+ write_text code, 'text/uri-list', msg, headers
31
38
  end
32
39
 
33
- def write_error(code, error)
40
+ def write_error(code, error, headers = {})
34
41
  msg = error.message
35
42
  log.warn "sending #{code} error response: #{msg}"
36
43
  ResponseHelpers.stats.incr_total_write_error
37
- write_plain code, msg
44
+ write_plain code, msg, headers
38
45
  end
39
46
 
40
- def write_url_list(code, urls)
41
- write code, 'text/uri-list', urls.join("\r\n") + "\r\n"
47
+ def write_json(code, obj, headers = {})
48
+ write code, 'application/json', obj.to_json, headers
42
49
  end
43
50
 
44
51
  # Multipart
@@ -68,11 +75,11 @@ module Plugin
68
75
  write_part 'text/plain', msg.to_s.gsub("\n", "\r\n"), headers
69
76
  end
70
77
 
71
- def write_error_part(code, error)
78
+ def write_error_part(code, error, headers = {})
72
79
  msg = error.message
73
80
  log.warn "sending error in multipart response part: #{msg}"
74
81
  ResponseHelpers.stats.incr_total_write_error_part
75
- write_plain_part msg, 'Status' => code
82
+ write_plain_part msg, headers.merge('Status' => code)
76
83
  end
77
84
 
78
85
  def write_epilogue
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "unicorn-cuba-base"
8
- s.version = "1.0.0"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakub Pastuszek"]
12
- s.date = "2013-07-16"
12
+ s.date = "2013-09-11"
13
13
  s.description = "web application base powered by Unicorn HTTP server and based on Cuba framework extended with additional Rack middleware and Cuba plugins"
14
14
  s.email = "jpastuszek@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "lib/unicorn-cuba-base.rb",
29
+ "lib/unicorn-cuba-base/default_error_reporter.rb",
29
30
  "lib/unicorn-cuba-base/memory_limit.rb",
30
31
  "lib/unicorn-cuba-base/plugin/error_matcher.rb",
31
32
  "lib/unicorn-cuba-base/plugin/logging.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn-cuba-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-16 00:00:00.000000000 Z
12
+ date: 2013-09-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cuba
@@ -173,6 +173,7 @@ files:
173
173
  - Rakefile
174
174
  - VERSION
175
175
  - lib/unicorn-cuba-base.rb
176
+ - lib/unicorn-cuba-base/default_error_reporter.rb
176
177
  - lib/unicorn-cuba-base/memory_limit.rb
177
178
  - lib/unicorn-cuba-base/plugin/error_matcher.rb
178
179
  - lib/unicorn-cuba-base/plugin/logging.rb
@@ -203,7 +204,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
204
  version: '0'
204
205
  segments:
205
206
  - 0
206
- hash: -3548490658984311397
207
+ hash: 463697011492453799
207
208
  required_rubygems_version: !ruby/object:Gem::Requirement
208
209
  none: false
209
210
  requirements: