Skip to content

Commit 8fed5df

Browse files
committed
Tweak caching + apply worker improvements from other branch
1 parent 578b743 commit 8fed5df

File tree

4 files changed

+23
-29
lines changed

4 files changed

+23
-29
lines changed

backend/app/helpers/application_helper.rb

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,26 @@ def with_cache(hash_name, key, json: true)
2929

3030
# If the cache value is currently being computed, we bail out early and expect the client to
3131
# re-request in a bit.
32-
#
33-
# If the value has been computing for longer than the cutoff, we assume the old computation
34-
# failed and compute it ourselves
35-
is_recomputing = false
36-
if cached
37-
if cached.start_with? "__computing__"
38-
date_string = cached.split("__computing__")[1]
39-
date = Date.parse(date_string)
40-
41-
if date < 3.minute.ago.utc
42-
raise ApplicationController::LockError
43-
else
44-
is_recomputing = true
45-
end
46-
else
47-
return cached
48-
end
32+
if cached && !cached.start_with?("__computing__")
33+
return cached
4934
end
35+
# If the value is currently being computed, we fall back to trying to acquire the lock and then
36+
# return the value from there once we have it.
5037

5138
# Lock the cache entry that we're trying to write to in order to ensure that we're not
5239
# computing the same expensive value that some other worker is already computing
5340
lock_key = "#{hash_name}_#{key}"
5441
ret = nil
55-
$lock_manager.lock(lock_key, 18502) do |locked|
42+
$lock_manager.lock(lock_key, 240000) do |locked|
5643
if locked
5744
begin
5845
# It's possible someone else was computing this while we were waiting for the lock. If so, we
5946
# just return that and avoid re-computing
6047
refreshed_cached = get_cache hash_name, key
6148

6249
if cached != refreshed_cached
63-
if refreshed_cached.starts_with? "__computing__"
64-
# Someone else beat us to the lock and is re-computing the value, so we just let them do it
50+
if refreshed_cached.starts_with?("__computing__")
51+
# The 4-minute window for computing that value has expired since their lock ran out. Maybe
6552
$lock_manager.unlock(locked)
6653
raise ApplicationController::LockError
6754
end
@@ -72,14 +59,14 @@ def with_cache(hash_name, key, json: true)
7259
end
7360

7461
# Create a placeholder value in the cache indicating that the value is currently being computed
75-
# and when the computation started
76-
now = Time.new
77-
date_string = now.strftime("%Y-%m-%d %H:%M:%S")
78-
placeholder_val = "__computing__#{date_string}"
79-
put_cache hash_name, key, placeholder_val, false
62+
#
63+
# We have exclusive access to this cache entry currently.
64+
put_cache hash_name, key, "__computing__", false
8065

8166
# Compute the new value while holding the lock, set it in the cache, and then drop the lock
8267
ret = put_cache hash_name, key, yield, json
68+
$lock_manager.unlock(locked)
69+
next
8370
rescue ApplicationController::NotFound
8471
delete_cache hash_name, key
8572
$lock_manager.unlock(locked)
@@ -93,7 +80,6 @@ def with_cache(hash_name, key, json: true)
9380
end
9481
else
9582
p "Failed to acquire a lock for key #{lock_key} in the timeout period"
96-
$lock_manager.unlock(locked)
9783
raise ApplicationController::LockError
9884
end
9985
end

backend/config/environments/development.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
config.cache_store = :null_store
2828
end
2929

30+
config.allow_concurrency = true
31+
3032
# Store uploaded files on the local file system (see config/storage.yml for options)
3133
# config.active_storage.service = :local
3234

backend/config/initializers/mongo.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
Mongo::Logger.level = Logger::FATAL
66
end
77

8-
::MongoClient = Mongo::Client.new(["#{host}:#{port}"], database: "robinhood")
8+
::MongoClient = Mongo::Client.new(["#{host}:#{port}"], database: "robinhood", max_pool_size: 20)

backend/config/puma.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#
77
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
88
threads threads_count, threads_count
9+
workers ENV.fetch("WEB_CONCURRENCY") { 6 }
910

1011
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
1112
#
@@ -27,8 +28,13 @@
2728
# This directive tells Puma to first boot the application and load code
2829
# before forking the application. This takes advantage of Copy On Write
2930
# process behavior so workers use less memory.
30-
#
31-
# preload_app!
31+
32+
preload_app!
33+
34+
on_worker_boot do
35+
MongoClient.close
36+
MongoClient.reconnect
37+
end
3238

3339
# Allow puma to be restarted by `rails restart` command.
3440
plugin :tmp_restart

0 commit comments

Comments
 (0)