API-Docker
view release on metacpan or search on metacpan
lib/API/Docker/Error/Timeout.pm view on Meta::CPAN
is => 'ro',
required => 1,
);
has partial => (
is => 'ro',
default => sub { '' },
);
has summary => (
is => 'ro',
);
sub as_string { $_[0]->message . $_[0]->location }
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
API::Docker::Error::Timeout - Read timeout while waiting for the Docker Engine
=head1 VERSION
version 0.004
=head1 SYNOPSIS
# Stop waiting after two seconds of silence instead of hanging forever.
my $out = '';
eval {
$docker->containers->attach($id,
stream => 1,
stdout => 1,
read_timeout => 2,
on_frame => sub { $out .= $_[0]{data} },
);
};
if (my $err = $@) {
die $err unless ref $err
&& $err->isa('API::Docker::Error::Timeout');
# Every complete frame reached the callback before the timeout; the
# summary says how many.
warn 'stopped after ' . $err->summary->{delivered} . ' frames';
}
=head1 DESCRIPTION
L<API::Docker::Role::HTTP> croaks with an object of this class when a request
was given a L<API::Docker::Role::HTTP/read_timeout> and the daemon then went
quiet for longer than it -- and, with L</phase> set to C<'connect'>, when a
request was given a L<API::Docker::Role::HTTP/connect_timeout> and the socket
never came up within it.
The rest of this describes the read timeout, which is the one that has
something to hand back. A connect timeout carries no L</partial> and no
L</summary>, for the reason L</phase> gives: nothing was ever sent.
It is an B<idle> timeout, not a deadline: the clock is the time since the last
byte arrived, so a stream that keeps producing runs as long as it likes and one
that stalls is cut off. That is the distinction the endpoints this exists for
need -- a hung C</containers/{id}/attach> has already delivered its buffered
frames before it stalls, so "nothing yet" would never have fired.
=head2 Why it is fatal, on every path
A timeout is not information about the response; it is the absence of it. The
transport cannot know whether the daemon was about to send the rest, so it
cannot decide for the caller that what arrived is usable -- and every return
shape this distribution promises would hide the question if it tried. C<ndjson>
promises an ArrayRef of events, C<raw> promises the response bytes, the default
promises the decoded body: a truncated value satisfies all three and is
indistinguishable from a complete one. A half tarball that looks whole is a
worse outcome than the hang it replaced.
That holds for the callback streams too, even though they have already handed
the caller every complete unit. Returning normally there would run the stream
handler's finish step, which is written for a daemon that closed: it treats a
trailing partial line as a complete final event, and reports leftover bytes as
a frame the daemon cut in half. Neither statement is true of a timeout. One
rule -- a timeout is fatal -- also keeps C<read_timeout> meaning the same thing
whether or not C<on_event>/C<on_frame>/C<on_chunk> is in use.
Nothing is lost with the exception: L</partial> carries the bytes a buffered
read had collected, L</summary> the count a streamed one had delivered. A
caller who wants "collect what there is, then stop" writes the C<eval> in the
SYNOPSIS; a caller who wants to fail loudly gets that without writing anything.
=head2 It is still the string it replaces
Like L<API::Docker::Error::HTTP> and L<API::Docker::Error::Stream>, this class
overloads stringification (with C<< fallback => 1 >>, so comparison,
concatenation, C<sprintf> and matching all work through it) and produces what
a plain C<croak> would have died with: the reason, followed by Carp's own
C< at FILE line N.> location suffix, naming the same frame.
The boolean overload is explicit rather than derived from the string, so it
cannot be made false by its own message.
=head2 message
The reason on its own, without the location suffix: the request it belongs to,
the timeout that expired and how much had arrived before it did.
The request is named without its query string, for the same reason the
C<< >= 400 >> croak names it that way -- C</build> carries its C<buildargs>
there, which can hold credentials and have no business in an exception.
=head2 location
Carp's location suffix (C< at FILE line N.\n>), captured at the point the
( run in 0.897 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )