zapp 0.2.1 → 0.2.4

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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zapp/configuration.rb +9 -1
  3. data/lib/zapp/http_context/request.rb +2 -2
  4. data/lib/zapp/logger/base.rb +103 -0
  5. data/lib/zapp/logger.rb +20 -57
  6. data/lib/zapp/server.rb +9 -4
  7. data/lib/zapp/socket_pipe/receiver.rb +0 -8
  8. data/lib/zapp/version.rb +1 -1
  9. data/lib/zapp/worker/request_processor.rb +27 -32
  10. data/lib/zapp/worker.rb +5 -6
  11. data/lib/zapp/worker_pool.rb +6 -5
  12. data/lib/zapp.rb +5 -2
  13. metadata +5 -109
  14. data/.circleci/config.yml +0 -21
  15. data/.gitignore +0 -13
  16. data/.rspec +0 -3
  17. data/.rubocop.yml +0 -48
  18. data/.ruby-version +0 -1
  19. data/Gemfile +0 -13
  20. data/Gemfile.lock +0 -112
  21. data/Guardfile +0 -23
  22. data/LICENSE.txt +0 -21
  23. data/README.md +0 -91
  24. data/Rakefile +0 -8
  25. data/examples/rails-app/.browserslistrc +0 -1
  26. data/examples/rails-app/.gitattributes +0 -10
  27. data/examples/rails-app/.gitignore +0 -40
  28. data/examples/rails-app/.ruby-version +0 -1
  29. data/examples/rails-app/Gemfile +0 -58
  30. data/examples/rails-app/Gemfile.lock +0 -255
  31. data/examples/rails-app/Rakefile +0 -8
  32. data/examples/rails-app/app/assets/config/manifest.js +0 -2
  33. data/examples/rails-app/app/assets/images/.keep +0 -0
  34. data/examples/rails-app/app/assets/stylesheets/application.css +0 -15
  35. data/examples/rails-app/app/channels/application_cable/channel.rb +0 -6
  36. data/examples/rails-app/app/channels/application_cable/connection.rb +0 -6
  37. data/examples/rails-app/app/controllers/application_controller.rb +0 -4
  38. data/examples/rails-app/app/controllers/concerns/.keep +0 -0
  39. data/examples/rails-app/app/helpers/application_helper.rb +0 -4
  40. data/examples/rails-app/app/javascript/channels/consumer.js +0 -6
  41. data/examples/rails-app/app/javascript/channels/index.js +0 -5
  42. data/examples/rails-app/app/javascript/packs/application.js +0 -13
  43. data/examples/rails-app/app/jobs/application_job.rb +0 -9
  44. data/examples/rails-app/app/mailers/application_mailer.rb +0 -6
  45. data/examples/rails-app/app/models/application_record.rb +0 -5
  46. data/examples/rails-app/app/models/concerns/.keep +0 -0
  47. data/examples/rails-app/app/views/layouts/application.html.erb +0 -16
  48. data/examples/rails-app/app/views/layouts/mailer.html.erb +0 -13
  49. data/examples/rails-app/app/views/layouts/mailer.text.erb +0 -1
  50. data/examples/rails-app/babel.config.js +0 -82
  51. data/examples/rails-app/bin/bundle +0 -118
  52. data/examples/rails-app/bin/rails +0 -7
  53. data/examples/rails-app/bin/rake +0 -7
  54. data/examples/rails-app/bin/setup +0 -38
  55. data/examples/rails-app/bin/spring +0 -16
  56. data/examples/rails-app/bin/webpack +0 -21
  57. data/examples/rails-app/bin/webpack-dev-server +0 -21
  58. data/examples/rails-app/bin/yarn +0 -19
  59. data/examples/rails-app/bin/zapp +0 -1
  60. data/examples/rails-app/config/application.rb +0 -24
  61. data/examples/rails-app/config/boot.rb +0 -6
  62. data/examples/rails-app/config/cable.yml +0 -10
  63. data/examples/rails-app/config/credentials.yml.enc +0 -1
  64. data/examples/rails-app/config/database.yml +0 -25
  65. data/examples/rails-app/config/environment.rb +0 -7
  66. data/examples/rails-app/config/environments/development.rb +0 -78
  67. data/examples/rails-app/config/environments/production.rb +0 -122
  68. data/examples/rails-app/config/environments/test.rb +0 -62
  69. data/examples/rails-app/config/initializers/application_controller_renderer.rb +0 -9
  70. data/examples/rails-app/config/initializers/assets.rb +0 -16
  71. data/examples/rails-app/config/initializers/backtrace_silencers.rb +0 -10
  72. data/examples/rails-app/config/initializers/content_security_policy.rb +0 -31
  73. data/examples/rails-app/config/initializers/cookies_serializer.rb +0 -7
  74. data/examples/rails-app/config/initializers/filter_parameter_logging.rb +0 -8
  75. data/examples/rails-app/config/initializers/inflections.rb +0 -17
  76. data/examples/rails-app/config/initializers/mime_types.rb +0 -5
  77. data/examples/rails-app/config/initializers/permissions_policy.rb +0 -12
  78. data/examples/rails-app/config/initializers/wrap_parameters.rb +0 -16
  79. data/examples/rails-app/config/locales/en.yml +0 -33
  80. data/examples/rails-app/config/puma.rb +0 -45
  81. data/examples/rails-app/config/routes.rb +0 -5
  82. data/examples/rails-app/config/spring.rb +0 -8
  83. data/examples/rails-app/config/storage.yml +0 -34
  84. data/examples/rails-app/config/webpack/development.js +0 -5
  85. data/examples/rails-app/config/webpack/environment.js +0 -3
  86. data/examples/rails-app/config/webpack/production.js +0 -5
  87. data/examples/rails-app/config/webpack/test.js +0 -5
  88. data/examples/rails-app/config/webpacker.yml +0 -92
  89. data/examples/rails-app/config/zapp.rb +0 -10
  90. data/examples/rails-app/config.ru +0 -7
  91. data/examples/rails-app/db/seeds.rb +0 -8
  92. data/examples/rails-app/lib/assets/.keep +0 -0
  93. data/examples/rails-app/lib/tasks/.keep +0 -0
  94. data/examples/rails-app/log/.keep +0 -0
  95. data/examples/rails-app/package.json +0 -17
  96. data/examples/rails-app/postcss.config.js +0 -12
  97. data/examples/rails-app/public/404.html +0 -67
  98. data/examples/rails-app/public/422.html +0 -67
  99. data/examples/rails-app/public/500.html +0 -66
  100. data/examples/rails-app/public/apple-touch-icon-precomposed.png +0 -0
  101. data/examples/rails-app/public/apple-touch-icon.png +0 -0
  102. data/examples/rails-app/public/favicon.ico +0 -0
  103. data/examples/rails-app/public/robots.txt +0 -1
  104. data/examples/rails-app/storage/.keep +0 -0
  105. data/examples/rails-app/test/application_system_test_case.rb +0 -7
  106. data/examples/rails-app/test/channels/application_cable/connection_test.rb +0 -15
  107. data/examples/rails-app/test/controllers/.keep +0 -0
  108. data/examples/rails-app/test/fixtures/files/.keep +0 -0
  109. data/examples/rails-app/test/helpers/.keep +0 -0
  110. data/examples/rails-app/test/integration/.keep +0 -0
  111. data/examples/rails-app/test/mailers/.keep +0 -0
  112. data/examples/rails-app/test/models/.keep +0 -0
  113. data/examples/rails-app/test/system/.keep +0 -0
  114. data/examples/rails-app/test/test_helper.rb +0 -17
  115. data/examples/rails-app/tmp/.keep +0 -0
  116. data/examples/rails-app/tmp/pids/.keep +0 -0
  117. data/examples/rails-app/vendor/.keep +0 -0
  118. data/examples/rails-app/yarn.lock +0 -6973
  119. data/zapp.gemspec +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '083c3deaea0cc22f0bd269afbccdd556bf66743771aca04f63f125809c934473'
4
- data.tar.gz: cd3a771ca1d0e898ddaa99c71b741412e4be8370286ec484b2059317cb632802
3
+ metadata.gz: d92db6f0faeb0316e5493676b97ed1566b65e14753e39423f8c73e8365aa7908
4
+ data.tar.gz: 253b76825620d5b55840a8e5b6686068bf7049271b093a9efb5a862d5040922d
5
5
  SHA512:
6
- metadata.gz: 227f3dc9ce4c2cac931c89f2a3bca81f90f91031a78998258befb02515ee5eb1af386741646bdecc14e82649cc5cc876f360cbfb8a01bf84e119b062ab3a0eea
7
- data.tar.gz: ffa29c579b1621eca0093e2c3d9a4f02975aa3be6a81aa17348aff7a7f5f54cecf4ea8aeb7829c6a821d4691c2ac9a2cd2d0be33204f2a02b1fd163b5c6990e3
6
+ metadata.gz: 3c1e015b962b63b8b92420746df6c5a6e470d9b9721b2b0ab4967b2b260e1fdce32baad057c048140391f3155f723626a0b959e86620d66a2318bea2c7beac81
7
+ data.tar.gz: 24967c889e62d3235fd162a1b6568bd63b6a72755b63e73910ac4b326fd92a5dd4026291d3f1e847e62f6b06cb9fc5e377c5061632651323576c52088c778dcc
@@ -12,6 +12,7 @@ module Zapp
12
12
  :parallelism,
13
13
  :threads_per_worker,
14
14
  :logger_class,
15
+ :logger_out_io,
15
16
  :log_requests,
16
17
  :log_uncaught_errors,
17
18
  :host,
@@ -33,6 +34,7 @@ module Zapp
33
34
 
34
35
  # Default logging behavior
35
36
  logger_class: Zapp::Logger,
37
+ logger_out_io: $stdout,
36
38
  log_requests: true,
37
39
  log_uncaught_errors: true,
38
40
 
@@ -72,7 +74,7 @@ module Zapp
72
74
  @app = new unless new.nil?
73
75
 
74
76
  @app ||= begin
75
- raise(Zapp::ZapError, "Missing rackup file '#{rackup_file}'") unless File.exist?(rackup_file)
77
+ raise(Zapp::ZappError, "Missing rackup file '#{rackup_file}'") unless File.exist?(rackup_file)
76
78
 
77
79
  rack_app, = rack_builder.parse_file(rackup_file)
78
80
 
@@ -98,6 +100,12 @@ module Zapp
98
100
  @logger_class = new
99
101
  end
100
102
 
103
+ def logger_out_io(new = nil)
104
+ return @logger_out_io if new.nil?
105
+
106
+ @logger_out_io = new
107
+ end
108
+
101
109
  def log_requests(new = nil)
102
110
  return @log_requests if new.nil?
103
111
 
@@ -9,7 +9,7 @@ module Zapp
9
9
  attr_reader(:raw, :data, :body)
10
10
 
11
11
  # Request parsing is done threaded, but not in separate Ractors.
12
- # So we allocate an HTTP parser per thread and assigns it to this hash key on Thread.current
12
+ # So we allocate an HTTP parser per thread and assign it to this hash key in Thread.current
13
13
  PARSER_THREAD_HASH_KEY = "PUMA_PARSER_INSTANCE"
14
14
 
15
15
  def initialize(socket:)
@@ -19,7 +19,7 @@ module Zapp
19
19
 
20
20
  parser.execute(data, raw, 0)
21
21
 
22
- @body = Zapp::InputStream.new(string: "parser.body")
22
+ @body = Zapp::InputStream.new(string: parser.body)
23
23
 
24
24
  parser.reset
25
25
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zapp
4
+ class Logger
5
+ # Base contains all the logging functionality and is included both as class and instance methods of Zap::Logger
6
+ # This allows logging without creating new instances,
7
+ # while allowing Ractors to create their own instances for thread safety
8
+ module Base
9
+ attr_writer(:level, :prefix)
10
+
11
+ LEVELS = { TRACE: 0, DEBUG: 1, INFO: 2, WARN: 3, ERROR: 4 }.freeze
12
+
13
+ FROZEN_ENV = ENV.map { |k, v| [k.freeze, v.freeze] }
14
+ .to_h.freeze
15
+
16
+ # The hash key in Ractor.current that stores the mutex for writing to output
17
+ OUT_IO_MUTEX_KEY = "ZAPP_LOGGER_OUT_IO_MUTEX"
18
+
19
+ def trace(msg) = log("TRACE", msg)
20
+
21
+ def debug(msg) = log("DEBUG", msg)
22
+
23
+ def info(msg) = log("INFO", msg)
24
+
25
+ def warn(msg) = log("WARN", msg)
26
+
27
+ def error(msg) = log("ERROR", msg)
28
+
29
+ def level
30
+ @level ||= begin
31
+ log_level = FROZEN_ENV["LOG_LEVEL"]
32
+
33
+ if log_level == "" || log_level.nil?
34
+ LEVELS[:DEBUG]
35
+ else
36
+ resolved_level = LEVELS[log_level.upcase.to_sym]
37
+
38
+ if resolved_level.nil?
39
+ raise(
40
+ Zapp::ZappError,
41
+ "Invalid log level '#{log_level.upcase}', must be one of [#{LEVELS.keys.join(', ')}]"
42
+ )
43
+ end
44
+
45
+ resolved_level
46
+ end
47
+ end
48
+ end
49
+
50
+ def log(current_level, msg, **_tags)
51
+ return unless level <= LEVELS[current_level.to_sym]
52
+
53
+ write("--- #{prefix} [#{current_level}] #{msg}\n")
54
+ end
55
+
56
+ def flush
57
+ writing_thread_pool.wait_for_termination(0.1)
58
+
59
+ out_io_mutex.synchronize do
60
+ out.flush
61
+ end
62
+ end
63
+
64
+ # @param new_out [IO]
65
+ def out=(new_out)
66
+ @out = new_out
67
+ end
68
+
69
+ protected
70
+
71
+ # @return [IO]
72
+ def out
73
+ @out ||= Zapp.config.logger_out_io
74
+ end
75
+
76
+ # @return [String]
77
+ def prefix = @prefix ||= Ractor.current.name
78
+
79
+ def write(msg)
80
+ writing_thread_pool.post do
81
+ out_io_mutex.synchronize do
82
+ out.print(msg)
83
+ end
84
+ end
85
+ end
86
+
87
+ # We really just use this as a queue
88
+ # TODO: There's probably a smarter way of doing this with less overhead,
89
+ # TODO: or maybe we should just actually write logs multi-threaded
90
+ def writing_thread_pool
91
+ @writing_thread_pool ||= Concurrent::ThreadPoolExecutor.new(
92
+ min_threads: 1,
93
+ max_threads: 1,
94
+ max_queue: 100
95
+ )
96
+ end
97
+
98
+ def out_io_mutex
99
+ Ractor.current[OUT_IO_MUTEX_KEY] ||= Thread::Mutex.new
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/zapp/logger.rb CHANGED
@@ -1,74 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative("logger/base")
4
+
3
5
  module Zapp
4
- # The default logger for zap
6
+ # The default logger for Zapp
5
7
  class Logger
6
- # Base contains all the logging functionality and is included both as class and instance methods of Zap::Logger
7
- # This allows logging without creating new instances,
8
- # while allowing Ractors to create their own instances for thread safety
9
- module Base
10
- attr_writer(:level, :prefix)
11
-
12
- LEVELS = { TRACE: 0, DEBUG: 1, INFO: 2, WARN: 3, ERROR: 4 }.freeze
13
-
14
- FROZEN_ENV = ENV.map { |k, v| [k.freeze, v.freeze] }
15
- .to_h.freeze
16
-
17
- def trace(msg)
18
- log("TRACE", msg)
19
- end
20
-
21
- def debug(msg)
22
- log("DEBUG", msg)
23
- end
8
+ include(Zapp::Logger::Base)
24
9
 
25
- def info(msg)
26
- log("INFO", msg)
27
- end
10
+ def initialize
11
+ yield(self) if block_given?
12
+ end
28
13
 
29
- def warn(msg)
30
- log("WARN", msg)
31
- end
14
+ class << self
15
+ # The hash key in Ractor.current that stores the global Zapp::Logger instance
16
+ GLOBAL_INSTANCE_KEY = "ZAPP_LOGGER_INSTANCE"
32
17
 
33
- def error(msg)
34
- log("ERROR", msg)
18
+ def instance
19
+ Ractor.current[GLOBAL_INSTANCE_KEY] ||= new
35
20
  end
36
21
 
37
- def level
38
- @level ||= begin
39
- log_level = FROZEN_ENV["LOG_LEVEL"]
40
-
41
- if log_level == "" || log_level.nil?
42
- LEVELS[:DEBUG]
43
- else
44
- resolved_level = LEVELS[log_level.upcase.to_sym]
45
-
46
- if resolved_level.nil?
47
- raise(
48
- Zapp::ZappError,
49
- "Invalid log level '#{log_level.upcase}', must be one of [#{LEVELS.keys.join(', ')}]"
50
- )
51
- end
22
+ private
52
23
 
53
- resolved_level
54
- end
24
+ def method_missing(symbol, *args)
25
+ if respond_to_missing?(symbol)
26
+ instance.public_send(symbol, *args)
27
+ else
28
+ super
55
29
  end
56
30
  end
57
31
 
58
- def log(current_level, msg, **_tags)
59
- puts("--- #{@prefix} [#{current_level}] #{msg}") if level <= LEVELS[current_level.to_sym]
32
+ def respond_to_missing?(symbol, include_private = false)
33
+ instance.respond_to?(symbol) || super(symbol, include_private)
60
34
  end
61
35
  end
62
- include(Zapp::Logger::Base)
63
-
64
- def initialize
65
- yield(self) if block_given?
66
- end
67
-
68
- class << self
69
- include(Zapp::Logger::Base)
70
- end
71
36
  end
72
37
  end
73
-
74
- Zapp::Logger.prefix = "Zapp"
data/lib/zapp/server.rb CHANGED
@@ -6,12 +6,15 @@ module Zapp
6
6
  attr_reader(:worker_pool, :socket_pipe_receiver)
7
7
 
8
8
  def initialize
9
+ # Ensure config.ru file is loaded just once by main ractor
10
+ Zapp.config.app
11
+
9
12
  @socket_pipe = Zapp::Pipe.new
10
13
  @context_pipe = Zapp::Pipe.new
11
14
 
12
15
  @socket_pipe_receiver = Zapp::SocketPipe::Receiver.new(pipe: @socket_pipe)
13
16
 
14
- @worker_pool = Zapp::WorkerPool.new(app: Zapp.config.app, socket_pipe: @socket_pipe, context_pipe: @context_pipe)
17
+ @worker_pool = Zapp::WorkerPool.new(socket_pipe: @socket_pipe, context_pipe: @context_pipe)
15
18
  end
16
19
 
17
20
  def run
@@ -38,16 +41,17 @@ module Zapp
38
41
  Zapp::Logger.info("Received signal #{err.class.name}") unless err.nil?
39
42
  Zapp::Logger.info("Gracefully shutting down workers, allowing request processing to finish")
40
43
 
41
- socket_pipe_receiver.drain
42
44
  worker_pool.drain
43
45
 
44
46
  Zapp::Logger.info("Done. See you next time!")
47
+ Zapp::Logger.flush
45
48
  end
46
49
 
47
50
  private
48
51
 
49
52
  def log_start
50
- Zapp::Logger.info("
53
+ Zapp::Logger.info(
54
+ "
51
55
  ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡
52
56
  ⚡ ███████╗ █████╗ ██████╗ ██████╗ ⚡
53
57
  ⚡ ╚══███╔╝██╔══██╗██╔══██╗██╔══██╗ ⚡
@@ -56,7 +60,8 @@ module Zapp
56
60
  ⚡ ███████╗██║ ██║██║ ██║ ⚡
57
61
  ⚡ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ⚡
58
62
  ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡
59
- ")
63
+ "
64
+ )
60
65
  Zapp::Logger.info("Zapp version: #{Zapp::VERSION}")
61
66
  Zapp::Logger.info("Environment: #{Zapp.config.mode}")
62
67
  Zapp::Logger.info("Serving: #{Zapp.config.env[Rack::RACK_URL_SCHEME]}://#{Zapp.config.host}:#{Zapp.config.port}")
@@ -19,14 +19,6 @@ module Zapp
19
19
  def take
20
20
  Ractor.select(pipe, raw_tcp_pipe)[1]
21
21
  end
22
-
23
- def drain
24
- Thread.new do
25
- loop do
26
- take
27
- end
28
- end
29
- end
30
22
  end
31
23
  end
32
24
  end
data/lib/zapp/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zapp
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.4"
5
5
  end
@@ -4,11 +4,9 @@ module Zapp
4
4
  class Worker < Ractor
5
5
  # Processes HTTP requests
6
6
  class RequestProcessor
7
- attr_reader(:app, :config, :socket_pipe_sender, :context_pipe)
7
+ attr_reader(:socket_pipe_sender, :context_pipe)
8
8
 
9
- def initialize(context_pipe:, socket_pipe:, app:, config:)
10
- @app = app
11
- @config = config
9
+ def initialize(context_pipe:, socket_pipe:)
12
10
  @socket_pipe_sender = Zapp::SocketPipe::Sender.new(pipe: socket_pipe)
13
11
  @context_pipe = context_pipe
14
12
  end
@@ -16,26 +14,24 @@ module Zapp
16
14
  def loop
17
15
  while (context = context_pipe.take)
18
16
  if context == Zapp::WorkerPool::SIGNALS[:EXIT]
19
- logger.trace("Received exit signal, shutting down")
20
- thread_pool.shutdown
17
+ Zapp::Logger.trace("Received exit signal, shutting down")
18
+ shutdown
21
19
  break
22
20
  end
23
21
 
22
+ process = lambda {
23
+ process(context: context)
24
+ }
24
25
 
25
- process = lambda {
26
- process(context: context)
27
- }
28
-
29
- if config.log_requests
30
- log_request_time(context: context, &process)
31
- else
32
- process.call
33
- end
34
-
35
- # We send sockets that the client hasn't closed yet,
36
- # back to the main ractor for HTTP request parsing again
37
- socket_pipe_sender.push(context.socket) unless context.client_closed?
26
+ if Zapp.config.log_requests
27
+ log_request_time(context: context, &process)
28
+ else
29
+ process.call
30
+ end
38
31
 
32
+ # We send sockets that the client hasn't closed yet,
33
+ # back to the main ractor for HTTP request parsing again
34
+ socket_pipe_sender.push(context.socket) unless context.client_closed?
39
35
  end
40
36
  end
41
37
 
@@ -43,16 +39,16 @@ module Zapp
43
39
 
44
40
  # Processes an HTTP request
45
41
  def process(context:)
46
- env = prepare_env(data: context.req.data, body: context.req.body, env: config.env.dup)
42
+ env = prepare_env(data: context.req.data, body: context.req.body, env: Zapp.config.env.dup)
47
43
 
48
- status, headers, response_body_stream = @app.call(env)
44
+ status, headers, response_body_stream = Zapp.config.app.call(env)
49
45
 
50
46
  response_body = body_stream_to_string(response_body_stream)
51
47
 
52
48
  context.res.write(data: response_body, status: status, headers: headers)
53
49
  rescue StandardError => e
54
50
  context.res.write(data: "An unexpected error occurred", status: 500, headers: {})
55
- logger.error("#{e}\n\n#{e.backtrace&.join(",\n")}") if config.log_uncaught_errors
51
+ Zapp::Logger.error("#{e}\n\n#{e.backtrace&.join(",\n")}") if Zapp.config.log_uncaught_errors
56
52
  end
57
53
 
58
54
  # Merges HTTP data and body into the env to be passed to the rack app
@@ -79,7 +75,7 @@ module Zapp
79
75
  path = context.req.data["PATH_INFO"]
80
76
  status = context.res.status
81
77
 
82
- logger.info(
78
+ Zapp::Logger.info(
83
79
  "#{method} #{path} - Completed in #{request_time}ms with status #{status}"
84
80
  )
85
81
  end
@@ -96,19 +92,18 @@ module Zapp
96
92
  response_body
97
93
  end
98
94
 
95
+ def shutdown
96
+ Zapp::Logger.flush
97
+ thread_pool.shutdown
98
+ end
99
+
99
100
  def thread_pool
100
101
  @thread_pool ||= Concurrent::ThreadPoolExecutor.new(
101
- min_threads: config.threads_per_worker,
102
- max_threads: config.threads_per_worker,
103
- max_queue: 1000,
102
+ min_threads: Zapp.config.threads_per_worker,
103
+ max_threads: Zapp.config.threads_per_worker,
104
+ max_queue: 1000
104
105
  )
105
106
  end
106
-
107
- def logger
108
- @logger ||= config.logger_class.new do |l|
109
- l.prefix = Ractor.current.name
110
- end
111
- end
112
107
  end
113
108
  end
114
109
  end
data/lib/zapp/worker.rb CHANGED
@@ -6,19 +6,18 @@ module Zapp
6
6
  # One worker processing requests in parallel
7
7
  class Worker < Ractor
8
8
  class << self
9
- def new(context_pipe:, socket_pipe:, app:, index:)
9
+ def new(context_pipe:, socket_pipe:, index:)
10
10
  super(
11
11
  context_pipe,
12
12
  socket_pipe,
13
- app,
14
13
  Zapp.config.dup,
15
14
  name: name(index)
16
- ) do |context_pipe, socket_pipe, app, config|
15
+ ) do |context_pipe, socket_pipe, config|
16
+ Ractor.current[Zapp::RACTOR_CONFIG_KEY] = config
17
+
17
18
  processor = Zapp::Worker::RequestProcessor.new(
18
19
  socket_pipe: socket_pipe,
19
- context_pipe: context_pipe,
20
- app: app,
21
- config: config
20
+ context_pipe: context_pipe
22
21
  )
23
22
 
24
23
  processor.loop
@@ -9,14 +9,13 @@ module Zapp
9
9
  EXIT: :exit
10
10
  }.freeze
11
11
 
12
- def initialize(app:, context_pipe:, socket_pipe:)
12
+ def initialize(context_pipe:, socket_pipe:)
13
13
  @context_pipe = context_pipe
14
14
  @workers = []
15
15
  Zapp.config.parallelism.times do |i|
16
16
  @workers << Worker.new(
17
17
  context_pipe: context_pipe,
18
18
  socket_pipe: socket_pipe,
19
- app: app,
20
19
  index: i
21
20
  )
22
21
  end
@@ -30,9 +29,11 @@ module Zapp
30
29
  # Finishes processing of all requests and shuts down workers
31
30
  def drain
32
31
  Zapp.config.parallelism.times { process(context: SIGNALS[:EXIT]) }
33
- workers.map(&:terminate)
34
- rescue Ractor::ClosedError
35
- # Ractor has already exited
32
+ workers.map do |w|
33
+ w.terminate
34
+ rescue Ractor::ClosedError
35
+ # Ractor has already exited
36
+ end
36
37
  end
37
38
  end
38
39
  end
data/lib/zapp.rb CHANGED
@@ -11,11 +11,14 @@ require("rack")
11
11
  module Zapp
12
12
  class ZappError < StandardError; end
13
13
 
14
+ # The hash key in Ractor.current that stores the global Zapp::Configuration instance
15
+ RACTOR_CONFIG_KEY = "ZAPP_CONFIG"
16
+
14
17
  class << self
15
18
  def config(reset: false)
16
- @config = Zapp::Configuration.new if reset
19
+ Ractor.current[RACTOR_CONFIG_KEY] = Zapp::Configuration.new if reset
17
20
 
18
- @config ||= Zapp::Configuration.new
21
+ Ractor.current[RACTOR_CONFIG_KEY] ||= Zapp::Configuration.new
19
22
  end
20
23
 
21
24
  def configure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias H Steffensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-10 00:00:00.000000000 Z
11
+ date: 2022-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -97,116 +97,12 @@ dependencies:
97
97
  description:
98
98
  email:
99
99
  - mathiashsteffensen@protonmail.com
100
- executables: []
100
+ executables:
101
+ - zapp
101
102
  extensions: []
102
103
  extra_rdoc_files: []
103
104
  files:
104
- - ".circleci/config.yml"
105
- - ".gitignore"
106
- - ".rspec"
107
- - ".rubocop.yml"
108
- - ".ruby-version"
109
- - Gemfile
110
- - Gemfile.lock
111
- - Guardfile
112
- - LICENSE.txt
113
- - README.md
114
- - Rakefile
115
105
  - bin/zapp
116
- - examples/rails-app/.browserslistrc
117
- - examples/rails-app/.gitattributes
118
- - examples/rails-app/.gitignore
119
- - examples/rails-app/.ruby-version
120
- - examples/rails-app/Gemfile
121
- - examples/rails-app/Gemfile.lock
122
- - examples/rails-app/Rakefile
123
- - examples/rails-app/app/assets/config/manifest.js
124
- - examples/rails-app/app/assets/images/.keep
125
- - examples/rails-app/app/assets/stylesheets/application.css
126
- - examples/rails-app/app/channels/application_cable/channel.rb
127
- - examples/rails-app/app/channels/application_cable/connection.rb
128
- - examples/rails-app/app/controllers/application_controller.rb
129
- - examples/rails-app/app/controllers/concerns/.keep
130
- - examples/rails-app/app/helpers/application_helper.rb
131
- - examples/rails-app/app/javascript/channels/consumer.js
132
- - examples/rails-app/app/javascript/channels/index.js
133
- - examples/rails-app/app/javascript/packs/application.js
134
- - examples/rails-app/app/jobs/application_job.rb
135
- - examples/rails-app/app/mailers/application_mailer.rb
136
- - examples/rails-app/app/models/application_record.rb
137
- - examples/rails-app/app/models/concerns/.keep
138
- - examples/rails-app/app/views/layouts/application.html.erb
139
- - examples/rails-app/app/views/layouts/mailer.html.erb
140
- - examples/rails-app/app/views/layouts/mailer.text.erb
141
- - examples/rails-app/babel.config.js
142
- - examples/rails-app/bin/bundle
143
- - examples/rails-app/bin/rails
144
- - examples/rails-app/bin/rake
145
- - examples/rails-app/bin/setup
146
- - examples/rails-app/bin/spring
147
- - examples/rails-app/bin/webpack
148
- - examples/rails-app/bin/webpack-dev-server
149
- - examples/rails-app/bin/yarn
150
- - examples/rails-app/bin/zapp
151
- - examples/rails-app/config.ru
152
- - examples/rails-app/config/application.rb
153
- - examples/rails-app/config/boot.rb
154
- - examples/rails-app/config/cable.yml
155
- - examples/rails-app/config/credentials.yml.enc
156
- - examples/rails-app/config/database.yml
157
- - examples/rails-app/config/environment.rb
158
- - examples/rails-app/config/environments/development.rb
159
- - examples/rails-app/config/environments/production.rb
160
- - examples/rails-app/config/environments/test.rb
161
- - examples/rails-app/config/initializers/application_controller_renderer.rb
162
- - examples/rails-app/config/initializers/assets.rb
163
- - examples/rails-app/config/initializers/backtrace_silencers.rb
164
- - examples/rails-app/config/initializers/content_security_policy.rb
165
- - examples/rails-app/config/initializers/cookies_serializer.rb
166
- - examples/rails-app/config/initializers/filter_parameter_logging.rb
167
- - examples/rails-app/config/initializers/inflections.rb
168
- - examples/rails-app/config/initializers/mime_types.rb
169
- - examples/rails-app/config/initializers/permissions_policy.rb
170
- - examples/rails-app/config/initializers/wrap_parameters.rb
171
- - examples/rails-app/config/locales/en.yml
172
- - examples/rails-app/config/puma.rb
173
- - examples/rails-app/config/routes.rb
174
- - examples/rails-app/config/spring.rb
175
- - examples/rails-app/config/storage.yml
176
- - examples/rails-app/config/webpack/development.js
177
- - examples/rails-app/config/webpack/environment.js
178
- - examples/rails-app/config/webpack/production.js
179
- - examples/rails-app/config/webpack/test.js
180
- - examples/rails-app/config/webpacker.yml
181
- - examples/rails-app/config/zapp.rb
182
- - examples/rails-app/db/seeds.rb
183
- - examples/rails-app/lib/assets/.keep
184
- - examples/rails-app/lib/tasks/.keep
185
- - examples/rails-app/log/.keep
186
- - examples/rails-app/package.json
187
- - examples/rails-app/postcss.config.js
188
- - examples/rails-app/public/404.html
189
- - examples/rails-app/public/422.html
190
- - examples/rails-app/public/500.html
191
- - examples/rails-app/public/apple-touch-icon-precomposed.png
192
- - examples/rails-app/public/apple-touch-icon.png
193
- - examples/rails-app/public/favicon.ico
194
- - examples/rails-app/public/robots.txt
195
- - examples/rails-app/storage/.keep
196
- - examples/rails-app/test/application_system_test_case.rb
197
- - examples/rails-app/test/channels/application_cable/connection_test.rb
198
- - examples/rails-app/test/controllers/.keep
199
- - examples/rails-app/test/fixtures/files/.keep
200
- - examples/rails-app/test/helpers/.keep
201
- - examples/rails-app/test/integration/.keep
202
- - examples/rails-app/test/mailers/.keep
203
- - examples/rails-app/test/models/.keep
204
- - examples/rails-app/test/system/.keep
205
- - examples/rails-app/test/test_helper.rb
206
- - examples/rails-app/tmp/.keep
207
- - examples/rails-app/tmp/pids/.keep
208
- - examples/rails-app/vendor/.keep
209
- - examples/rails-app/yarn.lock
210
106
  - lib/rack/handler/zapp.rb
211
107
  - lib/zapp.rb
212
108
  - lib/zapp/cli.rb
@@ -216,6 +112,7 @@ files:
216
112
  - lib/zapp/http_context/response.rb
217
113
  - lib/zapp/input_stream.rb
218
114
  - lib/zapp/logger.rb
115
+ - lib/zapp/logger/base.rb
219
116
  - lib/zapp/parser.rb
220
117
  - lib/zapp/pipe.rb
221
118
  - lib/zapp/server.rb
@@ -225,7 +122,6 @@ files:
225
122
  - lib/zapp/worker.rb
226
123
  - lib/zapp/worker/request_processor.rb
227
124
  - lib/zapp/worker_pool.rb
228
- - zapp.gemspec
229
125
  homepage: https://github.com/mathiashsteffensen/zapp
230
126
  licenses:
231
127
  - MIT