NAME

Evented::API::Engine - an Evented API Engine for Perl applications.

SYNOPSIS

Main

my $api = Evented::API::Engine->new;
$api->load_module('My::Module');

My::Module

# Module metadata
#
# @name:        'My::Module'
# @package:     'M::My::Module'
# @description:
#
# @depends.modules+ 'Some::Other'
# @depends.modules+ 'Another::Yet'
#
# @author.name:     'Mitchell Cooper'
# @author.website:  'https://github.com/cooper'
#
package M::My::Module;

use warnings;
use strict;
use 5.010;

# Auto-exported variables
our ($api, $mod);

# Default initializer
sub init {
    say 'Loading ', $mod->name;
    
    # indicates load success
    return 1;
}

# Default deinitializer
sub void {
    say 'Bye!';
    
    # indicates unload success
    return 1;
}

# Package must return module object
$mod;

DESCRIPTION

Perl provides a simple way to load dependencies. But what about upgrading or unloading? API Engine makes it easy to create an excessively versatile Perl application capable of adapting dynamically with the user's ever-changing needs.

Module management

Modules are Perl packages which can be easily loaded, unloaded, and reloaded. API Engine automatically tracks the changes made by each module and reverts them upon unload, leaving no trace. With API Engine used properly, it is even possible to reload your entire program without restarting it.

Modules themselves can determine the necessity of additional code which may be dynamically added and removed through the use of submodules.

Dependency resolution

API Engine automatically resolves dependencies of both modules and normal Perl packages. It loads and unloads dependencies in the proper order. It is also possible to specify that a submodule is automatically loaded and unloaded in conjunction with some top-level module.

Event management

API Engine is Evented in that it tracks all Evented::Object callbacks attached from within modules and automatically removes them upon unloading. This allows you to employ events excessively without constantly worrying about their eventual disposal.

METHODS

Evented::API::Engine->new(%opts)

Creates a new instance of the Evented API Engine. This single object will be used throughout the life of the application.

my $api = Evented::API::Engine->new(
    mod_inc  => [ 'mod', '/usr/share/something/mod' ],
    features => [ qw(io-async something-else)       ],
    modules  => [ $conf->keys_for_block('modules')  ]
);

Parameters

  • %opts: a package whose event activity you're monitoring.

%opts - constructor options

  • \@mod_inc - list of module search directories

  • \@features - optional, list of feature names to enable immediately

  • \@modules - optional, list of names of toplevel modules to load immediately

  • \&log_sub - optional, code to be called for API Engine log messages

  • $developer - optional, if true, module info will be written to JSON metadata files. your program should include a developer mode option which in turn enables this.

$api->load_modules(@mod_names)

Loads one or more modules at once.

This is preferred over calling ->load_module() several times in a row because it skips common dependencies which have already been attempted.

Parameters

  • @mod_names - list of module names to load

Returns

Module objects for those which loaded successfully.

  • $mod_name - name of the module to load.

  • \@dirs - optional, module search directories. if omitted, the normal search directories specified at API Engine construction time will be used.

Returns

On success, the loaded module object. Otherwise, false.

$api->unload_module($mod, $unload_dependents, $unload_parent)

Unloads a module.

Parameters

  • $mod - module object or name to unload.

  • $unload_dependents - optional, if true, modules dependent on the one being unloaded will also be unloaded. the normal behavior is to refuse to unload if dependent modules are loaded.

  • $unload_parent - optional, if true and the module being unloaded is a submodule, its parent will also be unloaded. the normal behavior is to refuse to unload if the requested module is a submodule.

Returns

Name of the unloaded module on success, otherwise false.

$api->reload_module($mod)

Reloads a module.

This is preferred over calling ->unload_module() and ->load_module for a few reasons:

  • Some modules that do not allow permanent unloading may allow reloading.

  • Unchanged dependencies are not unloaded when reloading.

  • Some unchanged data can be retained during reload.

Parameters

  • $mod - module object or name to reload.

Returns

True on success.

$api->reload_modules(@mods)

Reloads one or more modules at once. See ->reload_module().

Parameters

  • @mods - module objects or names to reload.

Returns

Number of modules reloaded successfully, false if all failed.

$api->get_module($mod_name)

Fetches a loaded module object.

Parameters

  • $mod_name - name of the module to find.

Returns

Module object on success, false otherwise.

$api->package_to_module($pkg)

Fetches a loaded module object by the corresponding Perl package name.

Parameters

  • $pkg - Perl package name to find.

Returns

Module object on success, false otherwise.

$api->module_loaded($mod_name)

Returns true if the specified module is loaded.

Parameters

  • $mod_name - name of the module to find.

Returns

True if the module is loaded.

$api->store($key, $value)

Stores a piece of data associated with the API Engine.

Parameters

  • $key - name for fetching data later.

  • $value - value to store.

$api->retrieve($key)

Retrieves a piece of data associated with the API Engine.

Parameters

  • $key - name associated with data to fetch.

Returns

Fetched data, undef if not found.

$api->list_store_add($key, $value)

Adds an entry to a list of data associated with the API Engine.

  • $key - name for fetching data later.

  • $value - value to add.

$api->list_store_items($key)

Fetches all values in a list associated with the API Engine.

  • $key - name of the list to retrieve.

Returns

List of fetch values, or empty list if none were found.

$api->add_feature($feature)

Enables a feature.

Features are just a simple way for modules to determine whether a feature is provided by another module. For instance, if multiple modules provide different database backends, each of these could enable the database feature. Modules requiring a database would check for the feature enabled without having to know which module provides it.

Parameters

  • $feature - name of the feature to enable.

$api->remove_feature($feature)

Disables a feature.

See ->add_feature for an explanation of features.

Parameters

  • $feature - name of the feature to disable.

$api->has_feature($feature)

Returns true if the specified feature is enabled.

See ->add_feature for an explanation of features.

Parameters

  • $feature - name of the feature to find.

Returns

True if the requested feature is enabled.

$api->Log($msg)

Used for logging associated with the API Engine. Use module ->Log() for messages associated with a specific module.

Parameters

  • $msg - text to log.

AUTHOR

Mitchell Cooper <cooper@cpan.org>

Copyright © 2017. Released under New BSD license.

Comments, complaints, and recommendations are accepted. Bugs may be reported on GitHub.