Discussion:
[Mojolicious] On converting IOLoop->delay->steps into promises
Roger Crew
2018-08-14 00:46:00 UTC
Permalink
Looked at the wiki upgrade page re converting uses of Mojo::IOLoop->delay.
Problem is, the main thing I seem to be using delay->steps for is handling
a sequence of nonblocking tasks, each one dependent on the previous, and
what's tricky is that each intermediate step/thunk can actually go 3 ways:

1. launch another nonblocking call
(with $delay->begin as callback, which then invokes the next step)
2. die on some error
3. return (i.e., to skip all remaining steps and this is *not* an
error)

So it's a question of what to do about

Mojo::IOLoop->delay->steps(
sub { nonblocking_call( shift->begin ); },
sub { ... },
# ...
sub {
my $delay = shift;
return unless _we_should_continue_with( @_ );
next_nonblocking_call( @_, $delay->begin );
},
# ...
sub { ... },
)
->catch( sub {
my $error = shift:
# handle it...
})

the natural thing is to build a chain of ->then() handlers,
but if you return out of a then handler, that's equivalent to $delay->pass
which continues the sequence, which we don't want,
but rejecting is also wrong because that invokes the catch handler at the
end

Best I can come up with is this

my $setbreak_p;
my $break = sub {
$setbreak_p->resolve(@_);
return Mojo::Promise->new->reject('this gets ignored');
};
$setbreak_p = nonblocking_call_p()
->then( sub { ... })
# ...
->then( sub {
return $break->()
unless _we_should continue_with( @_ );
next_nonblocking_call_p( @_ );
})
# ...
->then( sub { ... });
$setbreak_p
->catch( sub {
my $error = shift:
# handle it...
})
->finally( sub { ref $tx; } )
# if we need to be keeping $tx alive throughout

which works, but has a bit of a "promise spaghetti" feel to it and am
wondering if there's some easier way that I'm missing
--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at https://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.
Loading...