簡體   English   中英

Rails.cache在不同的線程中不能緩存?

[英]Rails.cache in different threads not caching?

我在Rails項目中使用緩存方法導致問題。

我來到了這段代碼,它模擬了兩個不同的請求:

[  
   Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
   Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

嘗試在Rails控制台中執行它。 如果嘗試在控制台中將其作為輸出運行,則會得到不同的數字。 那怎么可能?

但是例如,此代碼(帶有睡眠)按預期工作:

[  
  Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

在第一段代碼中

[  
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

我認為您的Rails配置正在使用文件進行緩存(為確保這一點,請檢查Rails應用程序中的/ tmp / cache文件夾)。

由於“ Rails.cache”需要執行從文件讀取緩存的操作,因此非常耗時,並且兩個線程中的“獲取”操作大多同時運行,因此“ a”值不存在或已過期。

在第二段代碼中

[  
  Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

當第一個線程嘗試獲取“ a”時,“ a”已經在緩存文件中。 這就是為什么它起作用。

讓我們進行另一個模擬,而不是使用“ Rails.cache”,我們將使用MemoryStore緩存,如下所示:

cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
[
  Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } },
  Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } }
]

它也符合我們的期望!

您可以使用互斥鎖來防止同時運行某些代碼:

mutex = Mutex.new
[  Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } }, Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } } ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM