unicorn-cuba-base 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: