Inside an async sub, a loop that (a) assigns from a constant-folded
string literal at or above perl's SV_COWBUF_THRESHOLD (1250 bytes)
(e.g. my $p = 'x' x 20_000; — folded at compile time) and (b) genuinely
suspends via await,
produces undef from a later assignment onward (deterministically the
third, in every minimal shape tested; a larger real program failed from
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Hit this working on an async redis client - a pubsub message handler | |
| disconnects two connections, which cancels both their in-flight reads, | |
| and with the default impl that dies: | |
| Can't call method "fh" on an undefined value at Future/IO.pm line 890 | |
| Best I can tell the poll loop caches $npollers and then completes ready | |
| futures inside the loop, so when a continuation cancels other pending | |
| reads, on_cancel splices them out of @pollers behind the loop's back and | |
| the index runs off the end. |
Future::IO 0.23 — cancelling a pending read from inside another read's continuation walks off the end of @pollers
Module: Future::IO 0.23 (current CPAN release), default impl (Future::IO::_DefaultImpl)
Symptom: Can't call method "fh" on an undefined value at Future/IO.pm line 890.
Not affected: Future::IO::Impl::IOAsync 0.805
_DefaultImpl's poll loop caches the poller count before iterating, then completes ready
futures inside that loop. Completing a future runs its continuation synchronously, and if
A port of the sample app from What Is Middleware? — which builds the same three-layer stack in Plack/PSGI (Perl) and Starlette/ASGI (Python) — to PAGI, an async, ASGI-style application interface for Perl.
The app is deliberately tiny but exercises the three things middleware exists to do:
- Logger — wrap the request, time it, log method/path in and status/duration out.
- Authenticator — inspect a header, inject context for downstream layers on
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env perl | |
| # future-io-cancel-bug.pl | |
| # | |
| # Demonstrates a bug in Future::IO::Impl::IOAsync where cancelling a future | |
| # that's waiting on a socket read doesn't properly clean up internal state. | |
| # | |
| # This is SELF-CONTAINED - no Redis or external server required. | |
| # | |
| # Run with different backends: | |
| # perl future-io-cancel-bug.pl # defaults to IOAsync |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Sketch to see if we can just use AUTOLOAD to inject into the | |
| display object methods as needed ad hoc | |
| # in this approach you have some named methods like $args | |
| # and other methods use AUTOLOAD, defautl behavior is to call | |
| # resolve_method_for_proxy($method) or if that doesn't exist | |
| # dfaults to $obj->method. | |
| # if you pass args to an AUTOLOADED method, that sets that | |
| # method to have that value. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use Future::AsyncAwait; | |
| # Define an ASGI-like application as an anonymous async sub. | |
| # This app checks the request scope and sends a response. | |
| my $asgi_app = async sub ($scope, $receive, $send) { | |
| if ($scope->{type} eq 'http') { | |
| # Send the response start message. | |
| await $send->({ | |
| type => "http.response.start", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env perl | |
| use strictures; | |
| use PSGI::Syntax; #(signatures, etc. for example code) | |
| use Future::AsyncAwait; | |
| use Future; | |
| ### Basic ASGI App Implementation | |
| async sub app($scope, $receive, $send) { | |
| if ($scope->{type} eq 'http') { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import asyncio | |
| # A simple logging middleware | |
| class LoggingMiddleware: | |
| def __init__(self, app): | |
| self.app = app | |
| async def __call__(self, scope, receive, send): | |
| # Only handle HTTP requests for this example. | |
| if scope["type"] == "http": |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package MyApp::Model::Components::Counter; | |
| use Moose; | |
| extends 'CatalystX::Components:::DisplayModel'; | |
| has count => (is=>'rw', required=>1, default=>0, live=>1); #lifecycle=>'request|session' | |
| sub increment($self) { | |
| my $current = $self->count; | |
| $self->count($current++); |
NewerOlder