You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Just want to say, I really like Dancer2. But I hit a limitation with one area of its support for recent improvements to async style code calling.
I have been trying to use Future::AsyncAwait with the delayed DSL something like:
package MyService;
# NOTE: Running this under Twiggy to get the event loop to work.
use Dancer2;
use AnyEvent; # for the event loop
use AnyEvent::HTTP; # for async http calls
use Promise::ES6; # modern promise responses
use Future::AsyncAwait; # for even more modern handling of async.
post '/' => sub {
my $url = "...";
delayed async {
# just a deferred promise implementation. pick anyone you prefer.
my ( $resolve, $reject );
my $promise = Promise::ES6->new(
sub ( $res, $rej ) { ( $resolve, $reject ) = ( $res, $rej ) }
);
# start an async call
AnyEvent::HTTP::http_get( $url, %opts, sub {
my ($body, $header) = @_;
$header->{Status} =~ /^[23]\d\d/ ? $resolve->($body) : $reject->($body);
});
my $response = await $promise;
# Problems starts here.
delayed {
content($response);
done();
};
}
}
1;
The problem is that i get an error after the await that the inner delayed DSL can not be used where they are located. Looks like Dancer2 does a check to see if a package variable that was localized is defined, which gets lost during the await. If i manually copy that variable and the others before the await call, I can make it work if I restore them after the await:
my $stash = stash_package_variables();
my $response = await $promise;
restore_package_variables($stash);
The problem seems to revolve around the design of the delayed underlying objects Dancer2::Core::Response::Delayed in that this object captures the needed package variables in a block locally and then reuses the object in the subsequent delayed calls. But the design for delayed assumes that you are wrapping all your async callbacks in delayed DSL. That not possible in async/await style since the underlying callbacks are not usually exposed.
I guess technically in my example I could wrap the callback for the http_get call, but my actual implementation is with a HTTP library that already returns the promise and you should be able to use this with any library that returns promises without having to change the library to be Dancer2 aware.
Another minor issue is that the top level await can not be wrapped in async like I have it in the current example. You have to instead manually unwrap the async call like:
delayed {
Future->unwrap(async sub {
})->();
};
It would be better to natively support async/await style directly in the DSL and adjust the delayed design to be smarter about how to handle the transitions across the await boundaries.
The text was updated successfully, but these errors were encountered:
Im pretty sure that my workaround of stashing of the package variables is likely to cause other problems since they are not localized correctly after that.
Just want to say, I really like Dancer2. But I hit a limitation with one area of its support for recent improvements to async style code calling.
I have been trying to use
Future::AsyncAwait
with thedelayed
DSL something like:The problem is that i get an error after the
await
that the innerdelayed
DSL can not be used where they are located. Looks like Dancer2 does a check to see if a package variable that was localized is defined, which gets lost during the await. If i manually copy that variable and the others before theawait
call, I can make it work if I restore them after theawait
:The problem seems to revolve around the design of the
delayed
underlying objectsDancer2::Core::Response::Delayed
in that this object captures the needed package variables in a block locally and then reuses the object in the subsequentdelayed
calls. But the design for delayed assumes that you are wrapping all yourasync
callbacks in delayed DSL. That not possible in async/await style since the underlying callbacks are not usually exposed.I guess technically in my example I could wrap the callback for the http_get call, but my actual implementation is with a HTTP library that already returns the promise and you should be able to use this with any library that returns promises without having to change the library to be
Dancer2
aware.Another minor issue is that the top level await can not be wrapped in async like I have it in the current example. You have to instead manually unwrap the async call like:
It would be better to natively support async/await style directly in the DSL and adjust the delayed design to be smarter about how to handle the transitions across the
await
boundaries.The text was updated successfully, but these errors were encountered: