umlaut 3.0.0alpha13 → 3.0.0alpha14
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -0
- data/app/models/#Untitled-1# +0 -0
- data/app/models/collection.rb +30 -28
- data/app/models/request.rb +2 -4
- data/app/models/service_wave.rb +8 -17
- data/app/views/admin/service_errors/_dispatched_service.html.erb +1 -1
- data/config/initializers/extensions/connection_pool.rb +97 -0
- data/lib/generators/umlaut/install_generator.rb +4 -3
- data/lib/umlaut/version.rb +1 -1
- data/test/dummy/config/umlaut_services.yml +1 -1
- data/test/dummy/tmp/cache/assets/C2A/410/sprockets%2Fd654b74912b4773a2534616863fb6565 +0 -0
- data/test/dummy/tmp/cache/assets/C2A/F60/sprockets%2F0168619e0479b449df21a96d81128446 +0 -0
- data/test/dummy/tmp/cache/assets/C45/A30/sprockets%2F39494895e462697b478d3d0c79298a26 +0 -0
- data/test/dummy/tmp/cache/assets/C5F/340/sprockets%2F99692920160b7a279b86a80415b79db7 +0 -0
- data/test/dummy/tmp/cache/assets/C70/4D0/sprockets%2F034ad2036e623081bd352800786dfe80 +0 -0
- data/test/dummy/tmp/cache/assets/C73/3A0/sprockets%2F4ec6216ea5b16813058f6a5800120b88 +0 -0
- data/test/dummy/tmp/cache/assets/C80/980/sprockets%2Fc94807409c1523d43e18d25f35d93c41 +0 -0
- data/test/dummy/tmp/cache/assets/C83/090/sprockets%2F88d056629d259318a6140e1b4c669ad2 +0 -0
- data/test/dummy/tmp/cache/assets/CA8/CA0/sprockets%2F706261702662dd54ec295c7d4a080e2d +0 -0
- data/test/dummy/tmp/cache/assets/CB0/B00/sprockets%2F1996cad394110de2d13f96639b4745a0 +0 -0
- data/test/dummy/tmp/cache/assets/CB2/DA0/sprockets%2Fa1808990b72376256db2ae3818c0e9b5 +0 -0
- data/test/dummy/tmp/cache/assets/CBD/730/sprockets%2F034c1086748b981c36672d5a56e7fed6 +0 -0
- data/test/dummy/tmp/cache/assets/CBF/B60/sprockets%2F08ca89671549936265dcb673bf02e36f +0 -0
- data/test/dummy/tmp/cache/assets/CC9/9F0/sprockets%2F306166316e2cafd13c15e62b51a2339d +0 -0
- data/test/dummy/tmp/cache/assets/CD6/300/sprockets%2F397ec39d3d883789effe506c38760368 +0 -0
- data/test/dummy/tmp/cache/assets/CD7/DD0/sprockets%2F4f1fe68aa2042a0970bde9b185530646 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/9B0/sprockets%2F973e0704e043597c480c8b2a1aae8d05 +0 -0
- data/test/dummy/tmp/cache/assets/CDE/010/sprockets%2F132e7b37dd472988500f625bb2cfe361 +0 -0
- data/test/dummy/tmp/cache/assets/CF6/F20/sprockets%2F5b2ffa1103079dfd555197838f87a99f +0 -0
- data/test/dummy/tmp/cache/assets/CF7/2B0/sprockets%2F25a7c73655bd3598173b39d9f98bcd46 +0 -0
- data/test/dummy/tmp/cache/assets/CFE/080/sprockets%2F37fe9f4255baddbd549a659914929398 +0 -0
- data/test/dummy/tmp/cache/assets/D10/420/sprockets%2F74579cafb0286be0c9fc13d680057b62 +0 -0
- data/test/dummy/tmp/cache/assets/D15/0D0/sprockets%2F909d1bd78126ba69c71cf95b907f006b +0 -0
- data/test/dummy/tmp/cache/assets/D16/3F0/sprockets%2F0d9672ae10739f5f15c88322db3cfc77 +0 -0
- data/test/dummy/tmp/cache/assets/D16/F90/sprockets%2F5fe3c021048c6f9a6086bed7736d87b1 +0 -0
- data/test/dummy/tmp/cache/assets/D18/830/sprockets%2F02fc21e6f358097b46fe04464a79ea8e +0 -0
- data/test/dummy/tmp/cache/assets/D24/360/sprockets%2F6987b047a96dc685ba3cf39b31477f6d +0 -0
- data/test/dummy/tmp/cache/assets/D2B/210/sprockets%2F0bda6c96f2e20aad805971cb315b1471 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D33/FD0/sprockets%2F2ba0b4e6334a77b923e5f770381bb2bf +0 -0
- data/test/dummy/tmp/cache/assets/D37/2B0/sprockets%2F40834fb07d7318c1fddd5003bd9e04f6 +0 -0
- data/test/dummy/tmp/cache/assets/D3D/F10/sprockets%2F4e32eadce0089c6e115f77ee103259e4 +0 -0
- data/test/dummy/tmp/cache/assets/D3E/E10/sprockets%2F4f3737656954cfde3b15406b2ca51aef +0 -0
- data/test/dummy/tmp/cache/assets/D3E/F40/sprockets%2F17acd2daf65e84066a96e7e0d155174a +0 -0
- data/test/dummy/tmp/cache/assets/D40/730/sprockets%2F61beb3b64b0952c1fda637692c4d9a68 +0 -0
- data/test/dummy/tmp/cache/assets/D43/0D0/sprockets%2F682843a8d0795a5fbcfeb2f0c81727d0 +0 -0
- data/test/dummy/tmp/cache/assets/D4D/F00/sprockets%2F106eda2f02d4ae70503e274a0f1e2d3a +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D50/A30/sprockets%2F7d8b294ac433db5d056538f8cf7c66b9 +0 -0
- data/test/dummy/tmp/cache/assets/D59/CF0/sprockets%2F65f4c7b1b394eb41440aaa6417bde12b +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D64/CE0/sprockets%2F27ee7882a56c67271b0e132babaf2ba8 +0 -0
- data/test/dummy/tmp/cache/assets/D69/E00/sprockets%2F80bfeb1aac21f5e43f6768c336181bb8 +0 -0
- data/test/dummy/tmp/cache/assets/D6C/7D0/sprockets%2F8a05d6981ec0d38c51739bef0b3a9c2b +0 -0
- data/test/dummy/tmp/cache/assets/D6E/AB0/sprockets%2F0845d812eda2307baccf7eeb6a974294 +0 -0
- data/test/dummy/tmp/cache/assets/D72/DE0/sprockets%2F8b625cb50d7bdc8c5e9084b43b55a7e5 +0 -0
- data/test/dummy/tmp/cache/assets/D74/4C0/sprockets%2F64fdf30f75592d6e45fcfc45a48d20a2 +0 -0
- data/test/dummy/tmp/cache/assets/D76/870/sprockets%2F55bf0acc7df37e060fdb8f72098a5656 +0 -0
- data/test/dummy/tmp/cache/assets/D7A/9A0/sprockets%2Fb195d86f759cccb657b057b56aaed193 +0 -0
- data/test/dummy/tmp/cache/assets/D8F/A30/sprockets%2Fd2be584fda972df9077d964ec8779c5a +0 -0
- data/test/dummy/tmp/cache/assets/D94/FF0/sprockets%2F3b56a1aa77de0d570c38a4a9d5f4b1d6 +0 -0
- data/test/dummy/tmp/cache/assets/D97/6B0/sprockets%2Fb070e8c799d1a4ad5e62e0a1ae3b83e6 +0 -0
- data/test/dummy/tmp/cache/assets/D9B/690/sprockets%2F8ade6607042fc147eecfde5a56445a0d +0 -0
- data/test/dummy/tmp/cache/assets/D9D/5D0/sprockets%2Fa7dee16d6f6c5b87a32716acb036f2a9 +0 -0
- data/test/dummy/tmp/cache/assets/DA6/A80/sprockets%2F92e26d8e58d5bcc8b8f6c25d1b05b9c1 +0 -0
- data/test/dummy/tmp/cache/assets/DA7/020/sprockets%2F3f8819c12039b3f6f635eacc6cffc6a6 +0 -0
- data/test/dummy/tmp/cache/assets/DB8/780/sprockets%2Ffc6ed563a3f488e5e7caeee04e556976 +0 -0
- data/test/dummy/tmp/cache/assets/DBB/770/sprockets%2F4fb7132f4df022bfecc2adcc277b8220 +0 -0
- data/test/dummy/tmp/cache/assets/DC0/D20/sprockets%2F1ccf7405cd252dcec4bf23af82e2563a +0 -0
- data/test/dummy/tmp/cache/assets/DD2/D80/sprockets%2Fc66d103807d0f971fbbcf9aa8b8b27ee +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/DE8/790/sprockets%2Fd1333bde2b9aafcc712d11dd09ab35d8 +0 -0
- data/test/dummy/tmp/cache/assets/DF5/5E0/sprockets%2F8e64a37c73cdc0b37a4ccfcb42ab45d8 +0 -0
- data/test/dummy/tmp/cache/assets/DF7/960/sprockets%2F99ac6db10b44a64fbba4ee847b35ba8b +0 -0
- data/test/dummy/tmp/cache/assets/DFC/040/sprockets%2F15ea81cf915c0cb1dfc9cc04c9fef364 +0 -0
- data/test/dummy/tmp/cache/assets/DFD/300/sprockets%2Fabac9489cf7f1db8ef00d72a1571ee1e +0 -0
- data/test/dummy/tmp/cache/assets/E02/D50/sprockets%2Fb85f8ca2fbb4dd506c7c0b8583d6ec8a +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E21/C90/sprockets%2F7621efdebb206edc6fd3cbf0192f2a0f +0 -0
- data/test/dummy/tmp/cache/assets/E26/C40/sprockets%2Fee819a444e9cfdf0c6a3bdd1baa2f525 +0 -0
- data/test/dummy/tmp/cache/assets/E38/FE0/sprockets%2Fe1fc875efa817cbb94a5d8de25ea4e6b +0 -0
- data/test/dummy/tmp/cache/assets/E5F/960/sprockets%2Fdc007b6cad5c7ef08e33ec28cfff0ef6 +0 -0
- data/test/dummy/tmp/cache/assets/EBB/5E0/sprockets%2F35461d449f3adeeafb09beebd1defeea +0 -0
- data/test/integration/request_reuse_test.rb +13 -4
- data/test/integration/request_test.rb +25 -0
- data/test/performance/browsing_test.rb +3 -3
- data/test/test_helper.rb +4 -0
- data/test/unit/active_record_connection_pool_test.rb +35 -0
- data/test/unit/google_book_search_test.rb +1 -1
- metadata +135 -45
- data/test/dummy/tmp/cache/assets/CEA/2A0/sprockets%2F9c8607157b998108ce08f4aca39f810a +0 -0
- data/test/dummy/tmp/cache/assets/D5D/AD0/sprockets%2Fbdb053d9a6a967788f09fbc555d69f58 +0 -0
- data/test/dummy/tmp/cache/assets/D66/890/sprockets%2F06287a78ed20d8214197eab03bfca5dd +0 -0
- data/test/dummy/tmp/cache/assets/D6B/2A0/sprockets%2F81f17ab0ed20f4a8d9355f7a1d872eb2 +0 -0
- data/test/dummy/tmp/cache/assets/E09/850/sprockets%2F4bf497a38ecfef660b2f0ebb852d5e9c +0 -0
- data/test/dummy/tmp/cache/assets/E6F/A00/sprockets%2Fd32bcea45ea04a6aaee95b3aa840cbab +0 -0
- data/test/integration/#request_reuse_test.rb# +0 -55
data/Rakefile
CHANGED
Binary file
|
data/app/models/collection.rb
CHANGED
@@ -100,38 +100,40 @@ class Collection
|
|
100
100
|
# we're going to let it keep doing it's thing in the background after
|
101
101
|
# we return a response to the browser
|
102
102
|
backgroundThread = Thread.new(self, umlaut_request) do | t_collection, t_request|
|
103
|
+
|
103
104
|
# Tell our AR extension not to allow implicit checkouts
|
104
105
|
ActiveRecord::Base.forbid_implicit_checkout_for_thread! if ActiveRecord::Base.respond_to?("forbid_implicit_checkout_for_thread!")
|
105
106
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# bg threads to a lower priority so they don't interfere with fg
|
112
|
-
# threads.
|
113
|
-
Thread.current.priority = -1
|
107
|
+
begin
|
108
|
+
# Set priority to lower for background thread; may or may not
|
109
|
+
# actually have an effect in MRI, unclear, but can't hurt.
|
110
|
+
prior = Thread.current.priority
|
111
|
+
Thread.current.priority = prior - 1
|
114
112
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
113
|
+
# Try to give the thread scheduler another hint, really, get
|
114
|
+
# other stuff done before this thread.
|
115
|
+
Thread.pass
|
116
|
+
|
117
|
+
|
118
|
+
('a'..'z').each do | priority |
|
119
|
+
services_to_run = self.instantiate_services!(:level => priority, :ids => queued_service_ids)
|
120
|
+
next if services_to_run.empty?
|
121
|
+
ServiceWave.new(services_to_run , priority).handle(umlaut_request, umlaut_request.session_id)
|
122
|
+
end
|
123
|
+
rescue Exception => e
|
124
|
+
# We are divorced from any HTTP request at this point, and may not
|
125
|
+
# have access to an ActiveRecord connection. Not much
|
126
|
+
# we can do except log it.
|
127
|
+
# If we're catching an exception here, service processing was
|
128
|
+
# probably interrupted, which is bad. You should not intentionally
|
129
|
+
# raise exceptions to be caught here.
|
130
|
+
#
|
131
|
+
# Normally even unexpected exceptions were caught inside the ServiceWave,
|
132
|
+
# and logged to db as well as logfile if possible, only bugs in ServiceWave
|
133
|
+
# itself should wind up caught here.
|
134
|
+
Thread.current[:exception] = e
|
135
|
+
logger.error("Background Service execution exception: #{e}\n\n " + clean_backtrace(e).join("\n"))
|
136
|
+
end
|
135
137
|
end
|
136
138
|
end
|
137
139
|
|
data/app/models/request.rb
CHANGED
@@ -50,18 +50,17 @@ class Request < ActiveRecord::Base
|
|
50
50
|
# up in the db to see if we've seen it before.
|
51
51
|
param_fingerprint = self.co_params_fingerprint( co_params )
|
52
52
|
client_ip = params['req.ip'] || a_rails_request.remote_ip()
|
53
|
+
|
53
54
|
unless (req || params["umlaut.force_new_request"] == "true" || param_fingerprint.blank? )
|
54
55
|
# If not found yet, then look for an existing request that had the same
|
55
56
|
# openurl params as this one, in the same session. In which case, reuse.
|
56
57
|
# Here we do require same session, since we don't have an explicit
|
57
58
|
# request_id given.
|
58
|
-
|
59
59
|
req = Request.where(
|
60
60
|
:session_id => a_rails_request.session_options[:id],
|
61
61
|
:contextobj_fingerprint => param_fingerprint,
|
62
62
|
:client_ip_addr => client_ip ).
|
63
|
-
|
64
|
-
|
63
|
+
order("created_at DESC, id DESC").first
|
65
64
|
end
|
66
65
|
|
67
66
|
# Okay, if we found a req, it might NOT have a referent, it might
|
@@ -74,7 +73,6 @@ class Request < ActiveRecord::Base
|
|
74
73
|
# didn't find an existing one at all, just create one
|
75
74
|
req = self.create_new_request!( :params => params, :session => session, :rails_request => a_rails_request, :contextobj_fingerprint => param_fingerprint, :context_object => context_object )
|
76
75
|
end
|
77
|
-
|
78
76
|
return req
|
79
77
|
end
|
80
78
|
|
data/app/models/service_wave.rb
CHANGED
@@ -25,7 +25,7 @@ class ServiceWave
|
|
25
25
|
def prepare_dispatch!(request, service, session_id)
|
26
26
|
can_dispatch = false
|
27
27
|
|
28
|
-
|
28
|
+
Request.connection_pool.with_connection do
|
29
29
|
if request.can_dispatch?( service)
|
30
30
|
# Mark this service as in progress in the dispatch table.
|
31
31
|
request.dispatched( service, DispatchedService::InProgress )
|
@@ -69,8 +69,9 @@ class ServiceWave
|
|
69
69
|
|
70
70
|
# Tell our AR extension not to allow implicit checkouts
|
71
71
|
ActiveRecord::Base.forbid_implicit_checkout_for_thread! if ActiveRecord::Base.respond_to?("forbid_implicit_checkout_for_thread!")
|
72
|
+
|
72
73
|
begin
|
73
|
-
local_request =
|
74
|
+
local_request = Request.connection_pool.with_connection do
|
74
75
|
# pre-load all relationships so no ActiveRecord activity will be
|
75
76
|
# needed later to see em.
|
76
77
|
Request.includes(:referent, :service_responses, :dispatched_services).find(request_id)
|
@@ -119,14 +120,9 @@ class ServiceWave
|
|
119
120
|
# Wait for all the threads to complete, if any.
|
120
121
|
threads.each do |aThread|
|
121
122
|
aThread.join
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
|
126
124
|
if aThread[:exception]
|
127
125
|
debugger
|
128
|
-
# mark it finished in the db, we should have a connection already, we're
|
129
|
-
# in main request thread.
|
130
126
|
begin
|
131
127
|
request.dispatched(aThread[:service], DispatchedService::FailedFatal, aThread[:exception])
|
132
128
|
rescue Exception => e
|
@@ -134,21 +130,16 @@ class ServiceWave
|
|
134
130
|
raise e
|
135
131
|
end
|
136
132
|
end
|
137
|
-
|
133
|
+
|
138
134
|
# Okay, raise if exception, if desired.
|
139
135
|
if ( aThread[:exception] && self.forward_exceptions? )
|
140
136
|
raise aThread[:exception]
|
141
137
|
end
|
142
138
|
end
|
143
|
-
|
139
|
+
|
144
140
|
threads.clear # more paranoia
|
145
|
-
|
146
|
-
|
147
|
-
#ActiveRecord::Base.clear_active_connections!
|
148
|
-
# Sadly, we aren't allowed/ought not to call this method manually
|
149
|
-
# anymore, just have to hope we haven't left any unclosed.
|
150
|
-
# https://github.com/rails/rails/pull/1200
|
151
|
-
#ActiveRecord::Base.connection_pool.clear_stale_cached_connections!
|
141
|
+
|
142
|
+
|
152
143
|
Rails.logger.info(TermColor.color("Umlaut: Completed service wave #{@priority_level}", :yellow) + ", request #{request.id}: in #{Time.now - bundle_start}") if some_service_executed && @log_timing
|
153
144
|
end
|
154
145
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<td><%= dispatched_service.updated_at.to_s(:short) %></td>
|
3
3
|
<td><%= dispatched_service.service_id %></td>
|
4
4
|
<td><%= dispatched_service.status %></td>
|
5
|
-
<td><%= link_to "[Re-request live]", url_for_with_co({:controller => "/resolve", :action => :index}, dispatched_service.request.to_context_object) %></td>
|
5
|
+
<td><%= link_to "[Re-request live]", url_for_with_co({:controller => "/resolve", :action => :index, "umlaut.force_new_request" => "true"}, dispatched_service.request.to_context_object) %></td>
|
6
6
|
<td><%= link_to "[View cached request]", url_for(:controller => "/resolve", :action => :index, "umlaut.request_id" => dispatched_service.request_id ) %></td>
|
7
7
|
</tr>
|
8
8
|
<tr>
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# NOTE: THIS NEEDS TO BE REMOVED WHEN RAILS IS FIXED!
|
2
|
+
# We expect it will be fixed in rails 3.2.3 (and broken again in 4, sorry)
|
3
|
+
# We require at least 3.2.2, so patch only if we're 3.2.2
|
4
|
+
|
5
|
+
if Rails.version == "3.2.2"
|
6
|
+
|
7
|
+
|
8
|
+
class ActiveRecord::ConnectionAdapters::ConnectionPool
|
9
|
+
|
10
|
+
##########################
|
11
|
+
# Monkey patch to fix disastrous concurrency bug in
|
12
|
+
# ActiveRecord ConnectionPool#with_concurrency
|
13
|
+
#
|
14
|
+
# See https://github.com/rails/rails/issues/5330
|
15
|
+
##########################
|
16
|
+
|
17
|
+
# New method we're adding viz a viz rails 3.2.2
|
18
|
+
# Check to see if there is an active connection for
|
19
|
+
# current_connection_id, that is by default the current
|
20
|
+
# thread.
|
21
|
+
def current_connection?
|
22
|
+
@reserved_connections.has_key?(current_connection_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Redefine with_connection viz a viz rails 3.2.2 to
|
26
|
+
# properly check back in connections.
|
27
|
+
# If a connection already exists yield it to the block. If no connection
|
28
|
+
# exists checkout a connection, yield it to the block, and checkin the
|
29
|
+
# connection when finished.
|
30
|
+
def with_connection
|
31
|
+
connection_id = current_connection_id
|
32
|
+
fresh_connection = true unless current_connection?
|
33
|
+
yield connection
|
34
|
+
ensure
|
35
|
+
release_connection(connection_id) if fresh_connection
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
###################################
|
40
|
+
#
|
41
|
+
# Monkey patch to fix bug with threads waiting
|
42
|
+
# on connection waking up, not succesfuly getting
|
43
|
+
# a connection, and giving up too early.
|
44
|
+
#
|
45
|
+
# https://github.com/rails/rails/pull/5422
|
46
|
+
#
|
47
|
+
# yeah, we got to replace all of #checkout.
|
48
|
+
# that's why we only apply this patch in 3.2.2, not
|
49
|
+
# in future rails versions.
|
50
|
+
#####################################
|
51
|
+
def checkout
|
52
|
+
synchronize do
|
53
|
+
waited_time = 0
|
54
|
+
|
55
|
+
loop do
|
56
|
+
conn = @connections.find { |c| c.lease }
|
57
|
+
|
58
|
+
unless conn
|
59
|
+
if @connections.size < @size
|
60
|
+
conn = checkout_new_connection
|
61
|
+
conn.lease
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if conn
|
66
|
+
checkout_and_verify conn
|
67
|
+
return conn
|
68
|
+
end
|
69
|
+
|
70
|
+
if waited_time >= @timeout
|
71
|
+
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout} (waited #{waited_time} seconds). The max pool size is currently #{@size}; consider increasing it."
|
72
|
+
end
|
73
|
+
|
74
|
+
# Sometimes our wait can end because a connection is available,
|
75
|
+
# but another thread can snatch it up first. If timeout hasn't
|
76
|
+
# passed but no connection is avail, looks like that happened --
|
77
|
+
# loop and wait again, for the time remaining on our timeout.
|
78
|
+
before_wait = Time.now
|
79
|
+
@queue.wait( [@timeout - waited_time, 0].max )
|
80
|
+
waited_time += (Time.now - before_wait)
|
81
|
+
|
82
|
+
# Will go away in Rails 4, when we don't clean up
|
83
|
+
# after leaked connections automatically anymore. Right now, clean
|
84
|
+
# up after we've returned from a 'wait' if it looks like it's
|
85
|
+
# needed, then loop and try again.
|
86
|
+
if(active_connections.size >= @connections.size)
|
87
|
+
clear_stale_cached_connections!
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -36,8 +36,9 @@ module Umlaut
|
|
36
36
|
# production and development. sqlite3 has unclear semantics under threaded
|
37
37
|
# concurrency which umlaut uses, and in many cases simply does not work.
|
38
38
|
#
|
39
|
-
# A
|
40
|
-
#
|
39
|
+
# A higher pool size than ordinary is recommended because of umlaut's
|
40
|
+
# use of concurrency. Perhaps as large as the number of services
|
41
|
+
# you have configured to run in the same wave, plus another few.
|
41
42
|
#
|
42
43
|
# development:
|
43
44
|
# adapter: mysql2
|
@@ -45,7 +46,7 @@ module Umlaut
|
|
45
46
|
# username:
|
46
47
|
# password:
|
47
48
|
# database:
|
48
|
-
# pool:
|
49
|
+
# pool: 15
|
49
50
|
|
50
51
|
eos
|
51
52
|
end
|
data/lib/umlaut/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,7 +1,16 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class RequestReuseTest < ActionDispatch::IntegrationTest
|
4
|
+
def setup
|
5
|
+
# for these tests, we don't want to actually execute any services, zero it out.
|
6
|
+
@orig_service_store_config = ServiceStore.config["default"]["services"]
|
7
|
+
ServiceStore.config["default"]["services"] = {}
|
8
|
+
end
|
4
9
|
|
10
|
+
def teardown
|
11
|
+
# restore original services, see setup
|
12
|
+
ServiceStore.config["default"]["services"] = @orig_service_store_config
|
13
|
+
end
|
5
14
|
|
6
15
|
test "reuse_of_request_in_session" do
|
7
16
|
sess = open_session
|
@@ -33,7 +42,8 @@ class RequestReuseTest < ActionDispatch::IntegrationTest
|
|
33
42
|
end
|
34
43
|
|
35
44
|
test "umlaut.force_new_request" do
|
36
|
-
|
45
|
+
|
46
|
+
request_params = { :issn => "012345679" }
|
37
47
|
|
38
48
|
sess1 = open_session
|
39
49
|
sess1.get "/resolve", request_params
|
@@ -43,15 +53,14 @@ class RequestReuseTest < ActionDispatch::IntegrationTest
|
|
43
53
|
sess1.get "/resolve", request_params.merge("umlaut.force_new_request" => "true")
|
44
54
|
request_after_forced = sess1.assigns[:user_request].id
|
45
55
|
|
46
|
-
|
47
56
|
assert_not_equal( request_after_forced, created_request_id )
|
48
|
-
|
57
|
+
|
49
58
|
# Make a request again without force param, still get the latter request,
|
50
59
|
# the one created when we forced it.
|
51
60
|
sess1.get "/resolve", request_params
|
52
61
|
assert_equal( sess1.assigns[:user_request].id, request_after_forced )
|
53
62
|
end
|
54
63
|
|
55
|
-
|
64
|
+
|
56
65
|
|
57
66
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RequestReuseTest < ActionDispatch::IntegrationTest
|
4
|
+
|
5
|
+
|
6
|
+
test "simple request" do
|
7
|
+
sess = open_session
|
8
|
+
|
9
|
+
request_params = { :issn => "012345678" }
|
10
|
+
|
11
|
+
sess.get "/resolve", request_params
|
12
|
+
|
13
|
+
|
14
|
+
# TODO: We ought to be waiting for all bg services in other
|
15
|
+
# threads before ending test. Tricky to figure out
|
16
|
+
# how to do cleanly, we don't even know the request id at the
|
17
|
+
# integration level, unless we do an API request instead of
|
18
|
+
# an HTML request. We'll just wait, sorry.
|
19
|
+
puts "sleeping"
|
20
|
+
sleep 4
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -11,6 +11,9 @@ Rails.backtrace_cleaner.remove_silencers!
|
|
11
11
|
# Load support files
|
12
12
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
13
13
|
|
14
|
+
# Complete stack trace with deprecation warnings from rails
|
15
|
+
ActiveSupport::Deprecation.debug = true
|
16
|
+
|
14
17
|
# Custom method for NYU-only tests. We still have a bunch of tests for aleph/
|
15
18
|
# primo that work against live nyu services and can only succeed if you are
|
16
19
|
# nyu. Oops. We provide this convenience function to wrap test_* class
|
@@ -44,3 +47,4 @@ def nyu_only_tests(test_name="Some")
|
|
44
47
|
yield
|
45
48
|
end
|
46
49
|
end
|
50
|
+
|