dandy 0.12.0 → 0.12.1

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: 47781859a32ae38be5a82a4548ee099ce2c745ea
4
- data.tar.gz: b8488633a66da4c980fb3532df442713ae35747c
3
+ metadata.gz: f5fd46a75db6411e264b87e934aff42dd34b2b7e
4
+ data.tar.gz: 681b74058c62074c072f59fab34c98ad21ac3e35
5
5
  SHA512:
6
- metadata.gz: b9ca968a3acd135a2656309c9ca2dd28d4c426b82a7d1b683c502201eeddd2f66772e74e75dfbbb8c1fdd03f50e81323842034e85b59d303da4441bc1a189eb5
7
- data.tar.gz: 7e802942e16d29e0de61a6c501bc62be98d5b1588028f2f1692894d2c633d6822de706d9a693c9d54dce750b317ca9b6aae5b5725f2161db87b8f26b00f0377f
6
+ metadata.gz: a9fc7ea134531646040be3368dcb0745e8bd8d19d4495bd38a0963728f8268c5d46f687f4bc7e0a76c0d55900f80d4ee07dbbbbb211cdce717a7aa809087fb85
7
+ data.tar.gz: 5a2b123dd6e34b828450a519ebb2cbe2bb98b52aa960bb1933956433fdc60d7db6b3166d2db9004ae60ccd4ddb604184e91f6581de7273c7c9ba7b8be0fdb730
@@ -9,9 +9,9 @@ require 'dandy/request'
9
9
  require 'dandy/template_registry'
10
10
  require 'dandy/view_builder_registry'
11
11
  require 'dandy/view_factory'
12
- require 'dandy/chain_factory'
13
12
  require 'dandy/view_builders/json'
14
13
  require 'dandy/routing/routing'
14
+ require 'dandy/safe_executor'
15
15
 
16
16
  module Dandy
17
17
  class App
@@ -27,7 +27,7 @@ module Dandy
27
27
  end
28
28
 
29
29
  def call(env)
30
- request = Request.new(@route_matcher, @container, @chain_factory, @view_factory)
30
+ request = Request.new(@route_matcher, @container, @safe_executor)
31
31
  request.handle(env)
32
32
  end
33
33
 
@@ -61,12 +61,12 @@ module Dandy
61
61
  template_registry: TemplateRegistry,
62
62
  view_builder_registry: ViewBuilderRegistry,
63
63
  view_factory: ViewFactory,
64
- chain_factory: ChainFactory,
65
64
  file_reader: Routing::FileReader,
66
65
  syntax_parser: SyntaxParser,
67
66
  syntax_error_interpreter: Routing::SyntaxErrorInterpreter,
68
67
  routes_builder: Routing::Builder,
69
- route_parser: Routing::Parser
68
+ route_parser: Routing::Parser,
69
+ safe_executor: SafeExecutor
70
70
  }
71
71
 
72
72
  singletons.keys.each do |name|
@@ -76,11 +76,12 @@ module Dandy
76
76
  end
77
77
 
78
78
  def load_basic_dependencies
79
- @chain_factory = @container.resolve(:chain_factory)
79
+ @dandy_config = @container.resolve(:dandy_config)
80
80
  @view_factory = @container.resolve(:view_factory)
81
81
  @dependency_loader = @container.resolve(:dependency_loader)
82
82
  @view_builder_registry = @container.resolve(:view_builder_registry)
83
83
  @route_parser = @container.resolve(:route_parser)
84
+ @safe_executor = @container.resolve(:safe_executor)
84
85
 
85
86
  @dependency_loader.load_components
86
87
  end
@@ -2,46 +2,23 @@ require 'timeout'
2
2
 
3
3
  module Dandy
4
4
  class Chain
5
- def initialize(container, dandy_config, commands, last_command, catch_command = nil)
6
- @commands = commands
7
- @last_command = last_command
5
+ def initialize(container, dandy_config)
8
6
  @container = container
9
- @catch_command = catch_command
10
7
  @async_timeout = dandy_config[:action][:async_timeout]
11
8
  end
12
9
 
13
- def execute
14
- if @catch_command.nil?
15
- run_commands
16
- else
17
- begin
18
- run_commands
19
- rescue Exception => error
20
- @container
21
- .register_instance(error, :dandy_error)
22
- .using_lifetime(:scope)
23
- .bound_to(:dandy_request)
24
-
25
- action = @container.resolve(@catch_command.name.to_sym)
26
- action.call
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def run_commands
10
+ def run_commands(commands, last_command)
34
11
  threads = []
35
12
  Thread.abort_on_exception = true
36
13
 
37
14
  result = nil
38
- @commands.each_with_index do |command, index|
15
+ commands.each_with_index do |command, index|
39
16
  if command.sequential?
40
17
  # all previous parallel commands should be done before the current sequential
41
18
  threads.each {|t| t.join}
42
19
  threads = []
43
20
 
44
- if @last_command && (command.name == @last_command.name)
21
+ if last_command && (command.name == last_command.name)
45
22
  result = run_command(command)
46
23
  else
47
24
  run_command(command)
@@ -49,7 +26,7 @@ module Dandy
49
26
  else
50
27
  thread = Thread.new {
51
28
  Timeout::timeout(@async_timeout) {
52
- if @last_command && (command.name == @last_command.name)
29
+ if last_command && (command.name == last_command.name)
53
30
  result = run_command(command)
54
31
  else
55
32
  run_command(command)
@@ -60,7 +37,7 @@ module Dandy
60
37
  end
61
38
 
62
39
  # if it's last item in chain then wait until parallel commands are done
63
- if index == @commands.length - 1
40
+ if index == commands.length - 1
64
41
  threads.each {|t| t.join}
65
42
  end
66
43
  end
@@ -68,6 +45,8 @@ module Dandy
68
45
  result
69
46
  end
70
47
 
48
+ private
49
+
71
50
  def run_command(command)
72
51
  if command.entity?
73
52
  entity = @container.resolve(command.entity_name.to_sym)
@@ -1,21 +1,19 @@
1
1
  require 'json'
2
+ require 'awrence'
3
+ require 'plissken'
2
4
  require 'rack/multipart'
3
5
  require 'dandy/extensions/hash'
4
- require 'dandy/chain_factory'
5
6
  require 'dandy/view_factory'
6
- require 'awrence'
7
- require 'plissken'
8
-
7
+ require 'dandy/chain'
9
8
 
10
9
  module Dandy
11
10
  class Request
12
11
  include Hypo::Scope
13
12
 
14
- def initialize(route_matcher, container, chain_factory, view_factory)
13
+ def initialize(route_matcher, container, safe_executor)
15
14
  @container = container
16
15
  @route_matcher = route_matcher
17
- @chain_factory = chain_factory
18
- @view_factory = view_factory
16
+ @safe_executor = safe_executor
19
17
  end
20
18
 
21
19
  def handle(rack_env)
@@ -31,36 +29,26 @@ module Dandy
31
29
  .collect {|k, v| [k.split('_').collect(&:capitalize).join('-'), v]}
32
30
  .flatten
33
31
  ]
34
- register_params(headers, :dandy_headers)
32
+
33
+ register_context(headers, :dandy_headers)
35
34
 
36
35
  if match.nil?
37
36
  result = [404, {'Content-Type' => headers['Accept']}, []]
38
37
  else
38
+ status = match.route.http_status || default_http_status(match.route.http_verb)
39
+ register_params(match.params)
40
+ register_status(status)
41
+
39
42
  query = Rack::Utils.parse_nested_query(rack_env['QUERY_STRING']).to_snake_keys.symbolize_keys
40
- register_params(query, :dandy_query)
43
+ register_context(query, :dandy_query)
41
44
 
42
45
  data = rack_env['rack.parser.result'] ? rack_env['rack.parser.result'].to_snake_keys.deep_symbolize_keys! : {}
43
- register_params(data, :dandy_data)
46
+ register_context(data, :dandy_data)
44
47
 
45
48
  multipart = Rack::Multipart.parse_multipart(rack_env) || {}
46
- register_params(multipart.values, :dandy_files)
47
-
48
- chain = @chain_factory.create(match)
49
- chain_result = chain.execute
49
+ register_context(multipart.values, :dandy_files)
50
50
 
51
- if match.route.view
52
- body = @view_factory.create(match.route.view, headers['Accept'], {keys_format: headers['Keys-Format'] || 'snake'})
53
- else
54
- if chain_result.is_a?(String)
55
- body = chain_result
56
- else # generate JSON when nothing other is requested
57
- if headers['Keys-Format'] == 'camel' && chain_result
58
- chain_result = chain_result.to_camelback_keys
59
- end
60
-
61
- body = JSON.generate(chain_result)
62
- end
63
- end
51
+ body = @safe_executor.execute(match.route, headers)
64
52
 
65
53
  status = @container.resolve(:dandy_status)
66
54
  result = [status, {'Content-Type' => headers['Accept']}, [body]]
@@ -80,12 +68,32 @@ module Dandy
80
68
  .bound_to(self)
81
69
  end
82
70
 
83
- def register_params(params, name)
71
+ def register_context(params, name)
84
72
  unless params.nil?
85
73
  @container.register_instance(params, name)
86
74
  .using_lifetime(:scope)
87
75
  .bound_to(:dandy_request)
88
76
  end
89
77
  end
78
+
79
+ def register_params(params)
80
+ params.keys.each do |key|
81
+ @container
82
+ .register_instance(params[key], key.to_sym)
83
+ .using_lifetime(:scope)
84
+ .bound_to(:dandy_request)
85
+ end
86
+ end
87
+
88
+ def register_status(status)
89
+ @container
90
+ .register_instance(status, :dandy_status)
91
+ .using_lifetime(:scope)
92
+ .bound_to(:dandy_request)
93
+ end
94
+
95
+ def default_http_status(http_verb)
96
+ http_verb == 'POST' ? 201 : 200
97
+ end
90
98
  end
91
99
  end
@@ -0,0 +1,41 @@
1
+ module Dandy
2
+ class SafeExecutor
3
+ def initialize(container, dandy_config, view_factory)
4
+ @container = container
5
+ @dandy_config = dandy_config
6
+ @view_factory = view_factory
7
+ end
8
+
9
+ def execute(route, headers)
10
+ chain = Chain.new(@container, @dandy_config)
11
+
12
+ begin
13
+ result = chain.run_commands(route.commands, route.last_command)
14
+ if route.view
15
+ result = @view_factory.create(route.view, headers['Accept'], {keys_format: headers['Keys-Format'] || 'snake'})
16
+ end
17
+
18
+ body = result.is_a?(String) ? result : format_response(result, headers)
19
+ rescue Exception => error
20
+ @container
21
+ .register_instance(error, :dandy_error)
22
+ .using_lifetime(:scope)
23
+ .bound_to(:dandy_request)
24
+
25
+ action = @container.resolve(route.catch.name.to_sym)
26
+ body = format_response(action.call, headers)
27
+ end
28
+
29
+ body
30
+ end
31
+
32
+ private
33
+ def format_response(result, headers)
34
+ if headers['Keys-Format'] == 'camel' && result
35
+ result = result.to_camelback_keys
36
+ end
37
+
38
+ JSON.generate(result)
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module Dandy
2
- VERSION = '0.12.0'.freeze
2
+ VERSION = '0.12.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dandy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Kalinkin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-20 00:00:00.000000000 Z
11
+ date: 2018-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hypo
@@ -230,7 +230,6 @@ files:
230
230
  - lib/dandy/app.rb
231
231
  - lib/dandy/base/handle_errors.rb
232
232
  - lib/dandy/chain.rb
233
- - lib/dandy/chain_factory.rb
234
233
  - lib/dandy/config.rb
235
234
  - lib/dandy/errors/dandy_error.rb
236
235
  - lib/dandy/errors/syntax_error.rb
@@ -288,6 +287,7 @@ files:
288
287
  - lib/dandy/routing/syntax/view.rb
289
288
  - lib/dandy/routing/syntax_error_interpreter.rb
290
289
  - lib/dandy/routing/syntax_grammar.tt
290
+ - lib/dandy/safe_executor.rb
291
291
  - lib/dandy/template_registry.rb
292
292
  - lib/dandy/version.rb
293
293
  - lib/dandy/view_builder.rb
@@ -1,39 +0,0 @@
1
- require 'dandy/chain'
2
-
3
- module Dandy
4
- class ChainFactory
5
- def initialize(container, dandy_config)
6
- @container = container
7
- @dandy_config = dandy_config
8
- end
9
-
10
- def create(match)
11
- status = match.route.http_status || default_http_status(match.route.http_verb)
12
- register_params(match.params)
13
- register_status(status)
14
- Chain.new(@container, @dandy_config, match.route.commands, match.route.last_command, match.route.catch)
15
- end
16
-
17
- private
18
-
19
- def register_params(params)
20
- params.keys.each do |key|
21
- @container
22
- .register_instance(params[key], key.to_sym)
23
- .using_lifetime(:scope)
24
- .bound_to(:dandy_request)
25
- end
26
- end
27
-
28
- def register_status(status)
29
- @container
30
- .register_instance(status, :dandy_status)
31
- .using_lifetime(:scope)
32
- .bound_to(:dandy_request)
33
- end
34
-
35
- def default_http_status(http_verb)
36
- http_verb == 'POST' ? 201 : 200
37
- end
38
- end
39
- end