Elastic::Model::Scope - Keeps objects alive and connected
version 0.51
Elastic::Model::Scope is an optional in-memory cache, which serves three purposes:
Keep weak-ref Elastic::Doc attributes alive
Reuse Elastic::Doc objects as singletons.
Multiple scopes allow you to have multiple versions of Elastic::Doc objects live at the same time.
See Elastic::Manual::Scoping for a fuller discussion of when and how to use scoping.
The parent scope of this scope, or UNDEF.
The logic used in scopes is best explained by the examples below:
$obj = $scope->get_object($domain_name, $uid);
When calling "get()" in Elastic::Model::Domain or "get_doc()" in Elastic::Model::Role::Model to retrieve an object from Elasticsearch, we first check to see if we can return the object from our in-memory cache by calling "get_object()":
If an object with the same namespace_name/type/id exists in the CURRENT scope (and its version is as least as high as the requested version, if any) then we return the SAME object.
namespace_name/type/id
$scope = $model->new_scope; $one = $domain->get( user => 123 ); $two = $domain->get( user => 123 ); print $one->name; # Clint $two->name('John'); print $one->name; # John print refaddr($one) == refaddr($two) ? 'TRUE' : 'FALSE'; # TRUE
If an object with the same domain_name/type/id exists in the PARENT scope (and its version is as least as high as the requested version, if any) then we return a CLONE of the object. (Note: we clone the original object as it was when loaded from Elasticsearch. Any unsaved changes are ignored.)
domain_name/type/id
$scope_1 = $model->new_scope; $one = $domain->get( user => 123 ); print $one->name; # Clint $one->name('John'); $scope_2 = $model->new_scope; $two = $domain->get( user => 123 ); print $two->name; # Clint print refaddr($one) == refaddr($two) ? 'TRUE' : 'FALSE'; # FALSE
Otherwise the calling method will fetch the object from Elasticsearch itself, and store it in the current scope.
If the object exists in the same scope or a parent scope, but it is an Elastic::Model::Deleted object, then we return undef.
undef
$object = $scope->store_object($ns_name, $object);
When we load a object that doesn't exist in the current scope or in any of its parents, or we create-a-new or update-an-existing object via "save()" in Elastic::Model::Role::Doc, we also store it in the current scope via "store_object()".
$scope_1 = $model->new_scope; $one = $domain->get( user => 123 ); print $one->name; # Clint $scope_2 = $model->new_scope; $two = $domain->get( user => 123 ); print $two->name; # Clint print refaddr($one) == refaddr($two) ? 'TRUE' : 'FALSE'; # FALSE
Now we update the $one object, while $scope_2 is current, and save it:
$one
$scope_2
$one->name('John'); $one->save;
Object $one is now in $scope_1 AND $scope_2.
$scope_1
$three = $domain->get( user => 123 ); print $three->name; # John print refaddr($one) == refaddr($three) ? 'TRUE' : 'FALSE'; # TRUE
Object $two still exists, and is still kept alive, but will no longer be returned from $scope_2.
$two
print $two->name; # Clint
$scope->delete_object( $ns_name, $uid );
When calling "delete_doc()" in Elastic::Model::Role::Model, "delete_doc()" in Elastic::Model::Domain or "delete()" in Elastic::Model::Role::Doc we check to see if an object with the same UID (namespace_name/type/id) exists in the current scope.
If it does, we rebless it into Elastic::Model::Deleted. Otherwise, we create a new Elastic::Model::Deleted object with the $uid and store that in the current scope.
$uid
$scope_1 = $model->new_scope; $one = $domain->get( user => 1 ); $domain->delete (user => 1 ); print $domain->isa('Elastic::Model::Deleted') ? 'TRUE' : 'FALSE'; # TRUE print $one->name; # Throws an error,
$scope_1 = $model->new_scope; $one = $domain->get( user => 1 ); $scope_2 = $model->new_scope; $domain->delete( user => 1); $two = $domain->get( user => 1 ); # Throws an error print $one->name; # Clint undef $scope_2; $two = $domain->get( user => 1 ); print refaddr($one) == refaddr($two) ? 'TRUE' : 'FALSE'; # TRUE
But, calling delete() on an object which isn't in the current scope still affects that object:
$scope_1 = $model->new_scope; $one = $domain->get( user => 1 ); $scope_2 = $model->new_scope; $one->delete; print $one->name; # Throws an error
Clinton Gormley <drtech@cpan.org>
This software is copyright (c) 2015 by Clinton Gormley.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Elastic::Model, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Elastic::Model
CPAN shell
perl -MCPAN -e shell install Elastic::Model
For more information on module installation, please visit the detailed CPAN module installation guide.