Promise-Me
view release on metacpan or search on metacpan
lib/Promise/Me.pm view on Meta::CPAN
Boolean. Default to true. If true, the shared space used by the parent and child processes will be destroy automatically. Disable this if you want to debug or take a sneak peek into the data. The shared space will be either shared memory of cache fil...
=head2 tmpdir
The optional path to the temporary directory to use when you want to use file cache as a medium for shared data.
=head2 use_async
This is a boolean value which is set automatically when a promise is instantiated from L</async>.
It enables subroutine arguments to be passed to the code being run asynchronously.
=head1 PRIVATE METHODS
=head2 _browse
Used for debugging purpose only, this will print out the L<PPI> structure of the code filtered and parsed.
=head2 _parse
After the code has been collected, this method will quickly parse it and make changes to enable L</async>
=head2 _reject_resolve
This is a common code called by either L</resolve> or L</reject>
=head2 _set_exit_values
This is called upon the exit of the asynchronous process to set some general value about how the process exited.
See L</exit_bit>, L</exit_signal> and L</exit_status>
=head2 _set_shared_space
This is called in L</exec> to share data including result between main parent process and asynchronous process.
=head1 SHARED VARIABLES
It is important to be able to share variables between processes in a seamless way.
When the asynchronous process is executed, the main process first fork and from this point on all data is being duplicated in an impermeable way so that if a variable is modified, it would have no effect on its alter ego in the other process; thus th...
You can enable shared variables in two ways:
=over 4
=item 1. declaring the variable as shared
my $name : shared;
# Initiate a value
my $location : shared = 'Tokyo';
# you can also use 'pshared'
my $favorite_programming_language : pshared = 'perl';
# You can share array, hash and scalar
my %preferences : shared;
my @names : shared;
=item 2. calling L</share>
my( $name, %prefs, @middle_names );
share( $name, %prefs, @middle_names );
=back
Once shared, you can use those variables normally and their values will be shared between the parent process and the asynchronous process.
For example:
my( $name, @first_names, %preferences );
share( $name, @first_names, %preferences );
$name = 'Momo Taro';
Promise::Me->new(sub
{
$preferences{name} = $name = 'Mr. ' . $name;
print( "Hello $name\n" );
$preferences{location} = 'Okayama';
$preferences{lang} = 'ja_JP';
$preferences{locale} = 'æ¡å¤ªé';
my $rv = $tbl->insert( \%$preferences )->exec || die( My::Exception->new( $tbl->error ) );
$rv;
})->then(sub
{
my $mail = My::Mailer->new(
to => $preferences{email},
name => $preferences{name},
body => $welcome_ja_file,
);
$mail->send || die( $mail->error );
})->catch(sub
{
my $exception = shift( @_ );
$logger->write( $exception );
})->finally(sub
{
$dbh->disconnect;
});
If you want to mix this feature and the usage of threads' C<shared> feature, use the keyword C<pshared> instead of C<shared>, such as:
my $name : pshared;
Otherwise the two keywords would conflict.
=head1 SHARED MEMORY
This module uses shared memory using L<Module::Generic::SharedMemXS>, or shared cache file using L<Module::Generic::File::Cache> if shared memory is not supported, or if the value of the global package variable C<$SHARE_MEDIUM> is set to C<file> inst...
The value of C<$SHARE_MEDIUM> is automatically initialised to C<memory> if the system, on which this module runs, supports L<IPC::SysV>, or C<mmap>, or else to C<file>
Shared memory is used for:
=over 4
=item 1. shared variables
=item 2. storing results returned by asynchronous processes
=back
You can control how much shared memory is allocated for each by:
lib/Promise/Me.pm view on Meta::CPAN
use Time::HiRes;
my $result : shared = '';
my $p1 = Promise::Me->new(sub
{
sleep(1);
$result .= "Peter ";
})->then(sub
{
print( "Promise 1: result is now: '$result'\n" );
});
my $p2 = Promise::Me->new(sub
{
sleep(0.5);
$result .= "John ";
})->then(sub
{
print( "Promise 2: result is now: '$result'\n" );
});
await( $p1, $p2 );
print( "Result is: '$result'\n" );
This will yield:
Promise 2: result is now: 'John '
Promise 1: result is now: 'John Peter '
Result is: 'John Peter '
=head1 CLASS VARIABLE
=head2 $RESULT_MEMORY_SIZE
This is the size in bytes of the shared memory block used for sharing result between sub process and main process, such as when you call:
my $res = $prom->result;
It defaults to 512Kb
=head2 $SERIALISER
A string representing the serialiser to use by default. A serialiser is used to serialiser data to share them between processes. This defaults to C<storable>
Currently supported serialisers are: L<CBOR::XS>, L<Sereal> and L<Storable|Storable::Improved>
You can set accordingly the value for C<$SERIALISER> to: C<cbor>, C<sereal> or C<storable>
You can override this global value when you instantiate a new L<Promise::Me> object with the C<serialiser> option. See L</new>
Note that the serialiser used to serialise shared variable, is set only via this class variable C<$SERIALISER>
=head2 $SHARE_MEDIUM
The value of C<$SHARE_MEDIUM> is automatically initialised to C<memory> if the system, on which this module runs, supports L<IPC::SysV>, or C<mmap>, or else to C<file>
=head2 $SHARED_MEMORY_SIZE
This is the size in bytes of the shared memory block used for sharing variables between the main process and the sub processes. This is used when you share variables, such as:
my $name : shared;
my( $name, %prefs, @middle_names );
share( $name, %prefs, @middle_names );
See L</"SHARED VARIABLES">
=head2 $USE_THREADS_SHARED
my $data : shared = '';
# Do some asynchronous activities with Promise::Me
or
my $data : pshared = ''; # does the same thing, but avoid conflict with threads
By default, C<Promise::Me> will recognise the variable attribute C<shared>, and handle it. However, when using L<threads>, this C<shared> pragma would also be used and recognised by L<threads> leading to a conflict. Setting C<$USE_THREADS_SHARED> to ...
Also, instead of using C<shared>, you can use C<pshared>
You can also set the value of C<$USE_THREADS_SHARED> upon import by using C<no_shared>
use Promise::Me 'no_shared'; # effectively sets $USE_THREADS_SHARED to true
However, if you did:
use Promise::Me;
$Promise::Me::USE_THREADS_SHARED = 1;
This would not work, because it would be too late. C<$USE_THREADS_SHARED> is used when the module is being loaded in the caller's namespace, so setting the variable after would be too late.
=head1 SHARED VARIABLES
C<Promise::Me> supports two attributes for shared variables:
=over 4
=item C<:shared>
Shares variables across processes or threads. By default, or if C<$USE_THREADS_SHARED> is false, C<:shared> uses C<Promise::Me::Share> with shared memory (via L<Module::Generic::SharedMemXS>) and customisable serialisation (e.g., L<CBOR>, L<Sereal>)....
=item C<:pshared>
Always uses C<Promise::Me::Share> for sharing, regardless of C<threads> usage or the C<no_shared> option. This ensures consistent inter-process sharing with C<Promise::Me>âs mechanism.
=back
To avoid conflicts with dependencies that load C<threads> (e.g., under C<mod_perl>), use C<:pshared> or avoid C<no_shared>. If you explicitly use C<threads>, call C<Promise::Me> with C<no_shared> to prefer C<threads::shared> for C<:shared>.
Example:
use Promise::Me;
my $result : shared = ''; # Uses Promise::Me::Share
my $promise = Promise::Me->new(sub
{
$result = "data from child";
});
await($promise);
print $result; # Outputs: data from child
use threads;
use threads::shared;
use Promise::Me qw( no_shared );
my $result : shared = ''; # Uses threads::shared
( run in 1.375 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )