开发者

Race condition, url shortener algorithm/Rails/MongoDB/MongoMapper

I created a url shortener algorithm with Ruby + MongoMapper

It's a simple url shortener algorithm with max 3 digits http://pablocantero.com/###

Where each # can be [a-z] or [A-Z] or [0-9]

For this algorithm, I need to persist four attributes on MongoDB (through 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

I created another class to manage ShortenerData and to generate the unique identifier

class Shortener
  include Singleton

  def get_unique开发者_如何学Python
    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

The Shortener usage

Shortener.instance.get_unique

My doubt is how can I make get_unique synchronized, my app will be deployed on heroku, concurrent requests can call Shortener.instance.get_unique


I changed the behaviour to get the base62 id. I created an auto increment gem to MongoMapper

With the auto incremented id I encode to base62

The gem is available on 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

Usage

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

Short url

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

I solved the race condition with 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

If this new behaviour I solved the race condition problem!

If you liked this gem, please, help to improve it. You’re welcome to make your contributions and send them as a pull request or just send me a message http://pablocantero.com/blog/contato

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜