NAME
MooX::Failover - Instantiate Moo classes with failover
SYNOPSIS
# In your class:
package MyClass;
use Moo;
use MooX::Failover;
has 'attr' => ( ... );
# after attributes are defined:
failover_to 'OtherClass';
...
# When using the class
my $obj = MyClass->new( %args );
# If %args contains missing or invalid values or new otherwise
# fails, then $obj will be of type "OtherClass".
DESCRIPTION
This module provides constructor failover for Moo classes.
For example, if a class cannot be instantiated because of invalid arguments (perhaps from an untrusted source), then instead it returns the failover class (passing the same arguments to that class).
It is roughly equivalent to using
my $obj = eval { MyClass->new(%args) //
OtherClass->new( %args, error => $@ );
This allows for cleaner design, by not forcing you to duplicate type checking for constructor parameters.
Use Cases
A use case for this module is for instantiating Web::Machine::Resource objects, where a resource class's attributes correspond to URL arguments. A type failure would normally cause an internal serror error (HTTP 500). Using MooX::Failover, we can return a different resource object that examines the error, and returns a more appropriate error code, e.g. bad request (HTTP 400).
Another use case for this module is for instantiating objects based on their data sources. For example, to restrieve an object from a cache, or to fail and retrieve it from the database instead.
Design Considerations
Your failover class should support the same methods as the original class, so that it (roughly) satisfies the Liskov Substitution Principle, where all provable properties of the original class are also provable of the failover class. In practice, we only care about the properties (methods and attributes) that are actually used in our programs.
EXPORTS
The following function is always exported:
failover_to
failover_to $class => %options;
This specifies the class to instantiate if the constructor dies.
It should be specified after all of the attributes have been declared.
Chained failovers are allowed:
failover_to $first => %options1;
failover_to $second => %options2;
...
The following options are supported.
class
-
The name of the class to fail over to. It defaults to
$class
. constructor
-
The name of the constructor method in the failover class. It defaults to "new".
from_constructor
-
The name of the constructor in the class that you are adding failover to. It defaults to "new".
Note that you can add failovers to multiple constructors. Suppose your class has a "new" constructor, as well as a "new_from_file" constructor that loads information from a file and then calls "new". You can specify failovers for both of the constructors:
failover_to 'OtherClass'; failover_to 'OtherClass' => ( from_constructor => 'new_from_file', );
This option was added in v0.3.0.
args
-
The arguments to pass to the failover class. When omitted, it will pass the same arguments as the original class.
This can be a scalar (single argument), hash reference or array reference.
Note that the options are treated are treated as raw Perl code. To use specify options, you need to explicitly add quotes to symbols, for example:
failover_to 'OtherClass' => ( args => [ map { "'$_'" } ( foo => 'bar' ) ], );
This option did not work properly until v0.3.0.
err_arg
-
This is the name of the constructor argument to pass the error to (it defaults to "error". This is useful if the failover class can inspect the error and act appropriately.
For example, if the original class is a handler for a website, where the attributes correspond to URL parameters, then the failover class can return HTTP 400 responses if the errors are for invalid parameters.
To disable it, set it to
undef
. class_arg
-
This is the name of the constructor argument to pass the name of the original class that failed. It defaults to "class".
To disable it, set it to
undef
.For chained failovers, it always contains the name of the original class.
orig_arg
-
This is the name of the constructor to pass an array reference of the original arguments passed to class. It is
undef
by default.The original arguments are already passed to the failover class, but this can be used to pass them all in a specific parameter.
If you do not want the original arguments passed to the failover class separately, set the
args
option to be empty:failover_to 'OtherClass' => ( args => [ ], orig_args => 'failed_args', );
This option was added in v0.3.0.
Note that unimporting Moo using
no Moo;
will also unimport MooX::Failover.
ATTRIBUTES
None. Since v0.2.0, there is no longer a failover_to
attribute.
SEE ALSO
This was originally a Moo port of MooseX::Failover. The interface was redesigned significantly, to be more efficient.
AUTHOR
Robert Rothenberg <rrwo@thermeon.com
>
Acknowledgements
COPYRIGHT
Copyright 2014 Thermeon Worldwide, PLC.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.