How do I store/access/update a thread-safe variable in an Sinatra app (+unicorn)?

删除回忆录丶 提交于 2019-12-14 03:24:41

问题


I want to store and update an Enum in an thread-safe way in my sinatra app. I use unicorn. I tried the following:

#!/usr/bin/ruby

require 'sinatra'

$locked = false
$num = 0
class App < Sinatra::Base
  before do
    while $locked do end
    $locked = true
  end

  after do
    $locked = false
  end

  get "/wait" do
    sleep 10
    $num += 1
    erb :display
  end

  get "/winner" do
    $num += 1
    erb :display
  end
end

The view just shows $num ;)

I started the app with unicorn (4 workers) and visited http://localhost:8080/winner with my browser. I clicked on refresh several times, but the app didn't show the expected behaviour (1,2,3,4,5,...) it instead showed random numbers (1,1,2,1,2,3,2,3,2,3,4,...)

so how do I get this thread-safe? :D (sorry for my bad english)


回答1:


Your issue isn't so much thread safety (although there is a slight race condition here - use a mutex rather than your $locked variable) as the fact that each unicorn worker is a separate process.

Each of these processes has a separate set of global variables, so the code you've written fundamentally can't work, no matter how much synchronisation you add to each process.

The ususal way to approach this would be to store the number in some shared datastore, for example a database like mysql, mongo, redis or even memcached. The last 3 of those have a specific atomic create or increment operation, but you can do this in a relational database too.



来源:https://stackoverflow.com/questions/12785108/how-do-i-store-access-update-a-thread-safe-variable-in-an-sinatra-app-unicorn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!