0

我用 Ruby + MongoMapper 创建了一个 url 缩短算法

这是一个简单的 url 缩短算法,最多 3 位数 http://pablocantero.com/###

其中每个 # 可以是 [az] 或 [AZ] 或 [0-9]

对于这个算法,我需要在 MongoDB 上持久化四个属性(通过 MongoMapper)

class ShortenerData
  include MongoMapper::Document
  VALUES = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
  key :col_a, Integer
  key :col_b, Integer
  key :col_c, Integer
  key :index, Integer
end

我创建了另一个类来管理 ShortenerData 并生成唯一标识符

class Shortener
  include Singleton

  def get_unique
    unique = nil
    @shortener_data.reload 
    # some operations that can increment the attributes col_a, col_b, col_c and index
    # ...
    @shortener_data.save
    unique
  end
end

缩短器用法

Shortener.instance.get_unique

我的疑问是如何使 get_unique 同步,我的应用程序将部署在 heroku 上,并发请求可以调用 Shortener.instance.get_unique

4

1 回答 1

2

我改变了行为以获取 base62 id。我为 MongoMapper 创建了一个自动增量 gem

使用自动递增的 id 我编码为 base62

gem 在 GitHub https://github.com/phstc/mongomapper_id2上可用

# app/models/movie.rb
class Movie
  include MongoMapper::Document

  key :title, String
  # Here is the mongomapper_id2
  auto_increment!
end

用法

movie = Movie.create(:title => 'Tropa de Elite')
movie.id # BSON::ObjectId('4d1d150d30f2246bc6000001')
movie.id2 # 3
movie.to_base62 # d

短网址

# app/helpers/application_helper.rb
def get_short_url model
    "http://pablocantero.com/#{model.class.name.downcase}/#{model.to_base62}"
end

我用 MongoDB find_and_modify http://www.mongodb.org/display/DOCS/findAndModify+Command解决了竞争条件

model = MongoMapper.database.collection(:incrementor).
   find_and_modify(
   :query => {'model_name' => 'movies'}, 
   :update => {'$inc' => {:id2 => 1}}, :new => true)

model[:id2] # returns the auto incremented_id

如果这个新行为我解决了竞争条件问题!

如果您喜欢这个宝石,请帮助改进它。欢迎您做出贡献并将它们作为拉取请求发送,或者只是给我发送消息http://pablocantero.com/blog/contato

于 2010-12-30T23:57:44.790 回答