# ABSTRACT: Proxy role for ephemeal peers
package Net::Object::Peer::Ephemeral;

use Moo::Role;

our $VERSION = '0.04'; # TRIAL

1;

#
# This file is part of Net-Object-Peer
#
# This software is Copyright (c) 2016 by Smithsonian Astrophysical Observatory.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#

=pod

=head1 NAME

Net::Object::Peer::Ephemeral - Proxy role for ephemeal peers

=head1 VERSION

version 0.04

=head1 DESCRIPTION

This role's sole purpose is to inform a subscriber that the emitter is
ephemeral (e.g., will disappear without an additional reference) and
it should keep track of it.  Normally only weak references to emittes
are kept, so as to prevent them outliving their intended scope.

Sometimes, however, it is necessary that the emitter outlive its
scope.  For example, assume that C<$subscriber> expects event C<A> to
be emitted when some condition has been met by C<$emitter>, but
C<$emitter> actually emits C<B>.  C<$subscriber> could tie
C<$emitter>'s C<B> event to it's own C<B> callback, but if
C<$subscriber> searches its subscriptions for C<A> event emitters,
it won't find this one.

One workaround is to create a proxy object which subscribes to
C<$emitter>'s C<B> event and re-emits it (with C<$emitter> as the
emitter) as event C<A>.  How does one keep that object alive?  Typically
it would be created on the fly when passed to the subscriber, e.g.

  $subscriber->subscribe( Translator->new( emitter => $emitter,
                                      from => C<B>, to => C<A> ),
                                      C<A> );

If C<$subscriber> doesn't hold on to the proxy object, it will be
destroyed immediately after the subscription, and the whole process fails.

Instead, if C<Translator> consumes the C<Net::Ojbect::Peer::Ephemeral>
role, C<$subscriber> will ensure it is not destroyed by holding strong
reference to it.  In this example, C<Translator> should subscribe to
the C<$emitter>'s C<detach> event so that it can detach itself from
C<$subscriber> and thus be destroyed.

=head1 SYNTAX

  # in class which will act as an intermediate/proxy
  package Ephemeral;
  with 'Net::Object::Peer::Ephemeral';

  [...]

=head1 AUTHOR

Diab Jerius <djerius@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2016 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

  The GNU General Public License, Version 3, June 2007

=cut

__END__

#pod =head1 SYNTAX
#pod
#pod   # in class which will act as an intermediate/proxy
#pod   package Ephemeral;
#pod   with 'Net::Object::Peer::Ephemeral';
#pod
#pod   [...]
#pod
#pod =head1 DESCRIPTION
#pod
#pod This role's sole purpose is to inform a subscriber that the emitter is
#pod ephemeral (e.g., will disappear without an additional reference) and
#pod it should keep track of it.  Normally only weak references to emittes
#pod are kept, so as to prevent them outliving their intended scope.
#pod
#pod Sometimes, however, it is necessary that the emitter outlive its
#pod scope.  For example, assume that C<$subscriber> expects event C<A> to
#pod be emitted when some condition has been met by C<$emitter>, but
#pod C<$emitter> actually emits C<B>.  C<$subscriber> could tie
#pod C<$emitter>'s C<B> event to it's own C<B> callback, but if
#pod C<$subscriber> searches its subscriptions for C<A> event emitters,
#pod it won't find this one.
#pod
#pod One workaround is to create a proxy object which subscribes to
#pod C<$emitter>'s C<B> event and re-emits it (with C<$emitter> as the
#pod emitter) as event C<A>.  How does one keep that object alive?  Typically
#pod it would be created on the fly when passed to the subscriber, e.g.
#pod
#pod   $subscriber->subscribe( Translator->new( emitter => $emitter,
#pod                                       from => C<B>, to => C<A> ),
#pod                                       C<A> );
#pod
#pod If C<$subscriber> doesn't hold on to the proxy object, it will be
#pod destroyed immediately after the subscription, and the whole process fails.
#pod
#pod Instead, if C<Translator> consumes the C<Net::Ojbect::Peer::Ephemeral>
#pod role, C<$subscriber> will ensure it is not destroyed by holding strong
#pod reference to it.  In this example, C<Translator> should subscribe to
#pod the C<$emitter>'s C<detach> event so that it can detach itself from
#pod C<$subscriber> and thus be destroyed.
