quilt_rails 1.6.0 → 1.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cb007cf5708ce9cc49b8eea19e79e8922faeaddf91223348962242c1ce03a8f
4
- data.tar.gz: d351101e370001003ce4f75c613922c72263998fad1d449f29ac023584112284
3
+ metadata.gz: 7327df33398c0cf113388e765ed893ba61d6d90c0eeec85989a52f0974da4d77
4
+ data.tar.gz: c99c5ae5c7cfc371e7687741fcd36fed8dfa002d64d9f52eeacb8d27598c5c08
5
5
  SHA512:
6
- metadata.gz: dc19e93667fc50d44613cc76d6a63ede39cd7b855850ab9c6e3257637754b066969351d17421f244ac5c6ffe75ee33f9e9363ab546f89bf80269ad3ffecb2840
7
- data.tar.gz: 61c9d32098b159d7a0b940b96ba02eb274e53dae54e252a25a6ed430c9446cbda9859e9e7ca15808f464833f015a1e32c6bf6e23d5addcdcc0a9c70bb5c49b62
6
+ metadata.gz: '09c0e63254e5c3e18ac56a52eb28470fd5994a8c1887052d26c2b385391f5fe9ba294f3afd43e8942a039bb5a4d12fab2746e38a1f924de8c920f08c67e1176c'
7
+ data.tar.gz: d97df6949379a1ec9a6f7ae9636f7008f0a791065a37ba6e5715bf0f489ce7bb7135a44817f6fb5ea4915b1cfea7810fe75f9f54db807b79f5d14c3fbd014315
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require 'rails'
3
+
4
+ # The default ActiveSupport::Reloader memoizes `@should_reload` for the
5
+ # lifetime of each request. This is a problem for quilt_rails apps because:
6
+ # - QuiltRails::ReactRenderable#render holds an exclusive lock until the Node
7
+ # server returns a result
8
+ # - Any controller calls during Node rendering (e.g., GraphQL fetches) will
9
+ # hang if they try to obtain a lock
10
+ # - Class unloading needs a lock, and so nested controller calls risk
11
+ # deadlocking whenever @should_reload is true
12
+ #
13
+ # Forcing `@should_reload` evaluation at the start of each thread prevents
14
+ # nested controller calls from attempting class unloading. This eliminates
15
+ # one source of lock contention.
16
+ #
17
+ # The affected flow is:
18
+ # - A developer saves a change to a Ruby file
19
+ # - The developer refreshes their browser
20
+ #
21
+ # Rails processes the request:
22
+ # - Thread0 - ActiveSupport::Reloader is called by middleware
23
+ # - Thread0 - An exclusive class unloader lock is obtained, classes are
24
+ # unloaded, and the lock is released
25
+ # - Thread0 - `Quilt::ReactRenderable#render_react` calls `reverse_proxy`,
26
+ # which grabs a general exclusive lock
27
+ # - Node - starts rendering, and calls out to a Rails controller for data
28
+ # - Thread1 - ActiveSupport::Reloader is called by the second controller's
29
+ # middleware
30
+ # - Thread1 - `@should_reload` is still true, so an attempt is made to grab an
31
+ # exclusive class unloader lock
32
+ # - Thread1 - waits for Thread0 to release its lock; Thread0 never unlocks
33
+ # because it needs Thread1's result
34
+ #
35
+ module ActiveSupport
36
+ class Reloader
37
+ def self.check! # :nodoc:
38
+ @should_reload = check.call
39
+ end
40
+ end
41
+ end
@@ -9,6 +9,16 @@ module Quilt
9
9
  def render_react
10
10
  raise DoNotIntegrationTestError if Rails.env.test?
11
11
 
12
+ # Allow concurrent loading to prevent this thread from blocking class
13
+ # loading in controllers called by the Node server.
14
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
15
+ call_proxy
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def call_proxy
12
22
  if defined? ShopifySecurityBase
13
23
  ShopifySecurityBase::HTTPHostRestriction.whitelist([Quilt.configuration.react_server_host]) do
14
24
  proxy
@@ -18,8 +28,6 @@ module Quilt
18
28
  end
19
29
  end
20
30
 
21
- private
22
-
23
31
  def proxy
24
32
  url = "#{Quilt.configuration.react_server_protocol}://#{Quilt.configuration.react_server_host}"
25
33
  Quilt::Logger.log("[ReactRenderable] proxying to React server at #{url}")
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Quilt
3
- VERSION = "1.6.0"
3
+ VERSION = "1.7.0"
4
4
  end
data/lib/quilt_rails.rb CHANGED
@@ -8,3 +8,4 @@ require "quilt_rails/logger"
8
8
  require "quilt_rails/configuration"
9
9
  require "quilt_rails/react_renderable"
10
10
  require "quilt_rails/trusted_ui_server_csrf_strategy"
11
+ require "quilt_rails/monkey_patches/active_support_reloader" if Rails.env.development?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quilt_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathew Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-18 00:00:00.000000000 Z
11
+ date: 2019-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -89,6 +89,7 @@ files:
89
89
  - lib/quilt_rails/configuration.rb
90
90
  - lib/quilt_rails/engine.rb
91
91
  - lib/quilt_rails/logger.rb
92
+ - lib/quilt_rails/monkey_patches/active_support_reloader.rb
92
93
  - lib/quilt_rails/react_renderable.rb
93
94
  - lib/quilt_rails/trusted_ui_server_csrf_strategy.rb
94
95
  - lib/quilt_rails/version.rb