No commit activity in last 3 years
No release in over 3 years
A Rails Session Store based on CouchRest Model
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0

Runtime

~> 2.0.0.rc3
~> 2.1.0.beta2
 Project Readme

CouchRest::Session::Store

A simple session store based on CouchRest Model.

Setup

CouchRest::Session::Store will automatically pick up the config/couch.yml file used by CouchRest Model.

Cleaning up sessions requires a design document in the sessions database that enables querying by expiry. See design/Session.json for an example. This design document is loaded for tests, but you will need to load it on your own in a production environment. For example:

curl -X PUT username:password@localhost:5984/couchrest_sessions/_design/Session --data @design/Session.json

Options

  • marshal_data: (defaults true) - if set to false session data will be stored directly in the couch document. Otherwise it's marshalled and base64 encoded to enable restoring ruby data structures.
  • database: database to use combined with config prefix and suffix
  • expire_after: lifetime of a session in seconds.

Dynamic Databases

This gem also includes the module CouchRest::Model::DatabaseMethod, which allow a Model to dynamically choose what database to use.

An example of specifying database dynamically:

class Token < CouchRest::Model::Base
  include CouchRest::Model::DatabaseMethod

  use_database_method :database_name

  def self.database_name
    time = Time.now.utc
    "tokens_#{time.year}_#{time.month}"
  end
end

A couple notes:

Once you include CouchRest::Model::DatabaseMethod, the database is no longer automatically created. In this example, you would need to run Token.database.create! or Token.database! in order to create the database.

The symbol passed to database_method must match the name of a class method, but if there is also an instance method with the same name then this instance method will be called when appropriate. To state the obvious, tread lightly: there be dragons when generating database names that depend on properties of the instance.

Database Rotation

The module CouchRest::Model::Rotation can be included in a Model in order to use dynamic databases to perform database rotation.

CouchDB is not good for ephemeral data because old documents are never really deleted: when you deleted a document, it just appends a new revision. The bulk of the old data is not stored, but it does store a record for each doc id and revision id for the document. In the case of ephemeral data, like tokens, sessions, or statistics, this will quickly bloat the database with a ton of useless deleted documents. The proper solution is to rotate the databases: create a new one regularly and delete the old one entirely. This will allow you to recover the storage space.

A better solution might be to just use a different database for all ephemeral data, like MariaDB or Redis. But, if you really want to use CouchDB, this is how you can do it.

An example of specifying database rotation:

class Token < CouchRest::Model::Base
  include CouchRest::Model::Rotation

  rotate_database 'tokens', :every => 30.days
end

Then, in a task triggered by a cron job:

CouchRest::Model::Base.configure do |conf|
  conf.environment = Rails.env
  conf.connection_config_file = File.join(Rails.root, 'config', 'couchdb.admin.yml')
end
Token.rotate_database_now(:window => 1.day)

Or perhaps:

Rails.application.eager_load!
CouchRest::Model::Rotation.descendants.each do |model|
  model.rotate_database_now
end

The :window argument to rotate_database_now specifies how far in advance we should create the new database (default 1.day). For ideal behavior, this value should be GREATER than or equal to the frequency with which the cron job is run. For example, if the cron job is run every hour, the argument can be 1.hour, 2.hours, 1.day, but not 20.minutes.

The method rotate_database_now will do nothing if the database has already been rotated. Otherwise, as needed, it will create the new database, create the design documents, set up replication between the old and new databases, and delete the old database (once it is not used anymore).

These actions will require admin access, so if your application normally runs without admin rights you will need specify a different configuration for CouchRest::Model before rotate_database_now is called.

Known issues:

  • If you change the rotation period, there will be a break in the rotation (old documents will not get replicated to the new rotated db) and the old db will not get automatically deleted.

  • Calling Model.database.delete! will not necessarily remove all the relevant databases because of the way prior and future databases are kept for the 'window' period.

Changes

0.3.0

  • Added support for dynamic and rotating databases.

0.2.4

  • Do not crash if can't connect to CouchDB

0.2.3

  • Better retry and conflict catching.d