-
Notifications
You must be signed in to change notification settings - Fork 153
Roadmap Identity Map
DataMapper’s Identity Map allows you to retrieve a Resource from the datastore multiple times, and know that there is only one copy of the Resource in memory at once. The IM is consulted before Model#get and Collection#get actually fetch the results from the datastore, so there are also some performance benefits to using an IM. It may even be possible to consult the IM for #first, #last and #all queries if the key is provided in the Query, but this is not currently being done by DM (but may in the future).
The DataMapper::IdentityMap class inherits from Hash, and DM uses only the #[], #[]= and #delete methods. This is fine for most use cases, but some people have asked about using other backends like Redis, Memcached or Tokyo Cabinet to store their Resources, and we would like to provide this ability.
Moneta provides an interface to key/value datastores that is identical to the DataMapper IM interface. We would like to make it possible to specify an IM class to use on a per-model basis, along with any options that are needed to pass to the IM constructor. If an IM class is not specified, then we would default to DataMapper::IdentityMap.
The exact syntax is still up for debate, but I (dkubb) was thinking something like the following when there are no extra options to pass:
class User
include DataMapper::Resource
identity_map Moneta::Redis
property :id, Serial
property :name, String
end
And something like this when there are options to provide to the IM constructor:
class User
include DataMapper::Resource
identity_map Moneta::Memcache, :server => 'localhost:11211'
property :id, Serial
property :name, String
end
I don’t know if it would make sense to allow the default IM to be specified for a repository, but perhaps it would. I would be open to suggestions on how this should look.
- We don’t want any hard dependencies on Moneta from within dm-core
- The Identity Map configuration should be inherited by subclasses, and overriding it in the subclass should not affect the parent class or any siblings. The inherited() hooks in DM::Model should dup/copy the configuration to the subclass.
- The default Identity Map should be the DM::IdentityMap class provided with DM. It should be set on the DM::Model instance, and overriding it there should set the default for it’s descendants.