Git Product home page Git Product logo

cro-websocket's People

Contributors

altai-man avatar altreus avatar japhb avatar jnthn avatar krunen avatar titsuki avatar vrurg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cro-websocket's Issues

Deadlock in Cro::WebSocket::Client::Connection.send

In a project I'm working on, I use a WebSocket client and throttle messages sent using a Supply. The problem is it deadlocks as soon as I try to send anything. Here's a golf that demonstrates this:

use v6.d;
use Cro::HTTP::Router;
use Cro::HTTP::Router::WebSocket;
use Cro::HTTP::Server;
use Cro::WebSocket::Client;

my $application = route {
    get -> 'websocket' {
        web-socket -> $incoming {
            supply {
                whenever $incoming -> $message {
                    say await $message.body;
                }
            }
        }
    }
};

my Cro::Service $server = Cro::HTTP::Server.new: :8000port, :$application;
$server.start;
END $server.stop;

my Cro::WebSocket::Client             $client     .= new: uri => 'ws://localhost:8000/websocket';
my Cro::WebSocket::Client::Connection $connection  = await $client.connect;
$connection.send: 'Sending...';

my Promise  $done-sending       .= new;
my Supplier $throttler-supplier .= new;
my Supply   $throttler           = $throttler-supplier.Supply.throttle: 1, 0.5;
$throttler.tap({
    $connection.send: $_;
    $throttler-supplier.done if $_ == 100;
}, done => {
    $connection.close: :0timeout;
    $done-sending.keep;
});

$throttler-supplier.emit: $_ for 1..100;
await $done-sending;

This outputs "Sending..." then deadlocks.

  • Cro::WebSocket version
    Cro::WebSocket:ver<0.8.0.1>
  • Perl 6 version
    This is Rakudo version 2018.12-338-g9d55dedc1 built on MoarVM version 2019.03-9-g834db592b
    implementing Perl 6.d.
  • OS
    OpenBSD bastille.kennel.qt 6.4 GENERIC.MP#683 amd64

Unable to create 32 KiB frame

Cro::WebSocket::FrameParser incorrectly applies the "no negative lengths" check (more precisely, no high bit set, since length is always unsigned, according to RFC 6455) to 2-byte extended payload lengths; this limitation only applies to 8-byte extended payload lengths. The net effect is being unable to handle frames with payload length in the range 2¹⁵ ..^ 2¹⁶.

Upcoming PR will address this.

The "Ping is recieved" test in the t/websocket-client.t fails 9 times out of 1000

The "Ping is recieved" test in the t/websocket-client.t rarely fails (about once every 30 times)

Result:

$ PERL6LIB=lib prove -v -r --exec=perl6 t/websocket-client.t
t/websocket-client.t .. 
ok 1 - Cannot send anything to closed channel(by done)
ok 2 - Empty ping is recieved
not ok 3 - Ping is recieved
# Failed test 'Ping is recieved'
# at t/websocket-client.t line 85
ok 4 - Timeout breaks ping promise
ok 5 - 
ok 6 - The connection is closed by close() call
ok 7 - Cannot send anything to closed channel by close() call
ok 8 - Can send Hash using client with JSON body serializer installed
ok 9 - Got hash back from body, thanks to JSON body parser
ok 10 - Correct hash content (1)
ok 11 - Correct hash content (2)
ok 12 - Correct hash content (3)
ok 13 - Can send Hash using client constructed with :json
ok 14 - Got hash back from body, thanks to :json
ok 15 - Correct hash content (1)
ok 16 - Correct hash content (2)
ok 17 - Correct hash content (3)
1..17
# Looks like you failed 1 test of 17
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/17 subtests 

Test Summary Report
-------------------
t/websocket-client.t (Wstat: 256 Tests: 17 Failed: 1)
  Failed test:  3
  Non-zero exit status: 1
Files=1, Tests=17,  7 wallclock secs ( 0.02 usr  0.00 sys +  2.54 cusr  0.24 csys =  2.80 CPU)
Result: FAIL

Perl6 version:

$ perl6 --version
This is Rakudo version 2018.02.1-172-g34889bebc built on MoarVM version 2018.02-171-geee5be412
implementing Perl 6.c.

Zef installed modules:

$ perl6 --version
This is Rakudo version 2018.02.1-172-g34889bebc built on MoarVM version 2018.02-171-geee5be412
implementing Perl 6.c.
itoyota@debian:~/Program/cro-websocket$ zef list --installed
===> Found via /home/itoyota/rakudo/install/share/perl6
CORE:ver<6.c>:auth<perl>
===> Found via /home/itoyota/rakudo/install/share/perl6/site
App::Mi6:ver<0.1.2>
Base64:ver<0.0.1>:auth<github:ugexe>
Bench:ver<0.1.5>:auth<github:tony-o>
CPAN::Uploader::Tiny:ver<0.0.3>
Config::JSON:ver<1.001003>
Cro::Core:ver<0.7.3>
Cro::HTTP:ver<0.7.3>
Cro::TLS:ver<0.7.3>
Cro::WebSocket:ver<0.7.3>
Crypt::Random:ver<0.4.1>:auth<github:skinkade>
Digest::HMAC:ver<1.0.0>:auth<github:retupmoca>
Digest::SHA1::Native:ver<0.02>
Digest:ver<0.3.4>:auth<Lucien Grondin>
File::Directory::Tree:auth<labster>
File::Find:ver<0.1>
File::Temp:ver<0.0.6>
File::Which:ver<1.0.0>
HTTP::HPACK:ver<0.9.2>
HTTP::Tinyish:ver<0.1.0>
IO::Path::ChildSecure:ver<1.001010>
IO::Socket::Async::SSL:ver<0.6.1>
JSON::Class:ver<0.0.10>:auth<github:jonathanstowe>
JSON::Fast:ver<0.9.9>
JSON::JWT:ver<1.0>:auth<github:retupmoca>
JSON::Marshal:ver<0.0.14>:auth<github:jonathanstowe>
JSON::Name:ver<0.0.2>:auth<github:jonathanstowe>
JSON::Pretty:ver<0.1.0>:auth<github:FROGGS>
JSON::Tiny:ver<1.0>
JSON::Unmarshal:ver<0.08>
LibraryMake:ver<1.0.0>:auth<github:retupmoca>
META6:ver<0.0.19>:auth<github:jonathanstowe>
MIME::Base64:ver<1.2.1>:auth<github:retupmoca>
MeCab:ver<0.0.5>
OO::Monitors:ver<1.1>
OpenSSL:ver<0.1.18>:auth<github:sergot>
Pod::To::HTML:ver<0.3.13>
Pod::To::Markdown:ver<.0.1.3>
Shell::Command
Temp::Path:ver<1.001003>
Terminal::ANSIColor:ver<0.4>
Test::META:ver<0.0.13>:auth<github:jonathanstowe>
Test::When:ver<1.001008>
Testo:ver<1.003004>
Text::Table::Simple:ver<0.0.5>:auth<github:ugexe>
URI::Encode:ver<0.05>:auth<David Farrell>
URI:ver<0.1.4>
YAMLish:ver<0.0.4>:auth<Leon Timmermans>
Z-Script:ver<1.001002>
cro:ver<0.7.3>
if:ver<0.1.0>:auth<github:FROGGS>
zef:ver<0.1.32>:auth<github:ugexe>
zef:ver<0.2.2>:auth<github:ugexe>

Rakudist test fails. Cro::WebSocket:ver<0.8.4> , Rakudo v2020.10

Hi! The summary:

22:16:31 11/04/2020 [bash: zef install cro] ===> Testing: Cro::WebSocket:ver<0.8.4>
22:17:02 11/04/2020 [bash: zef install cro] [Cro::WebSocket]     # You planned 2 tests, but ran 3
22:17:02 11/04/2020 [bash: zef install cro] [Cro::WebSocket] # Failed test 'If send resulted in error, an exception is thrown'
22:17:02 11/04/2020 [bash: zef install cro] [Cro::WebSocket] # at t/websocket-client.t line 163
22:17:03 11/04/2020 [bash: zef install cro] [Cro::WebSocket] # You failed 1 test of 25
22:17:10 11/04/2020 [bash: zef install cro] ===> Testing [FAIL]: Cro::WebSocket:ver<0.8.4>
22:17:10 11/04/2020 [bash: zef install cro] stderr: Aborting due to test failure: Cro::WebSocket:ver<0.8.4> (use --force-test to override)

A full log is available here - http://rakudist.raku.org/sparky/report/debian/890

HTH

Aleksei

Lockup at client when awaiting JSON body

I have been converting the cro-websocket test files into performance tests of the various pieces. This had been working fine with most of the parser/serializer/handler bits, but when I did a test of the whole client/server pair, I ran into a lockup at the client.

See https://gist.github.com/japhb/c07f5699dbb6d2e45a392865b52abe58 for the test file. (The perf test version of this file just comments out the say calls and raises $repeat to something in the ~1000 range.) It's pretty straightforward; I was comparing the performance of round trips of text and JSON bodies, using a server side taken nearly as-is from t/http-router-websocket.t. The client should be pretty uncontroversial, but though it seems to work fine for plain text round trips, it locks up while awaiting the body-text on the client side for JSON round trips.

Any ideas what's going on here? The only obvious thing I can see different between the plain text and JSON cases with CRO_TRACE=1 is that the plain text response is sent unfragmented, while the JSON response message is sent as a fragment frame containing the entirety of the JSON data followed by an empty continuation frame, but if that's really the problem I'm surprised cro-websocket passes it's own test suite.

Suggestion: client should accept Upgrade header 'WebSocket'

Some websocket servers are using 'WebSocket' instead of 'websocket' token in the Upgrade header.
And maybe a more useful error message here

die unless $resp.header('upgrade') eq 'websocket';
die unless $resp.header('connection') ~~ m:i/^Upgrade$/;
die unless $resp.header('Sec-WebSocket-Accept').trim eq $answer;

See
https://www.iana.org/assignments/http-upgrade-tokens/http-upgrade-tokens.xhtml
https://tools.ietf.org/html/rfc6455#section-11.2

Question: Throttling websocket server stream?

When the input is faster ( for a single stream ) than the server can process - the cro app caches the data left, so it stores it in the RAM.
The issue here is that this can act as a DOS when several requests with more data are processed.

WS connections dropped after enabling HTTP/2

On a cro server I have set up. After enabling https in Cro::HTTP::Server. Chrome proves a failed: Connection closed before receiving a handshake response error from the dev console and firefox returns a vaguer _Firefox can’t establish a connection to the server at [websocket_address]/ws-connect. error from its dev console. I am sorry for the vague code example. I've found the below does not work

my Cro::Service $http = Cro::HTTP::Server.new(
    http => <1.1 2>,
    host => %*ENV<JSCARTY_HOST> ||
        die("Missing JSCARTY_HOST in environment"),
    port => %*ENV<JSCARTY_PORT> ||
        die("Missing JSCARTY_PORT in environment"),
    tls  => %(
        private-key-file => %*ENV<JSCARTY_TLS_KEY> ||
            %?RESOURCES<fake-tls/server-key.pem>,
        certificate-file => %*ENV<JSCARTY_TLS_CERT> ||
            %?RESOURCES<fake-tls/server-crt.pem>
    ),
    :$application,
    after => [
        Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
    ]
);

while the below does

my Cro::Service $http = Cro::HTTP::Server.new(
    http => <1.1>,
    host => %*ENV<JSCARTY_HOST> ||
        die("Missing JSCARTY_HOST in environment"),
    port => %*ENV<JSCARTY_PORT> ||
        die("Missing JSCARTY_PORT in environment"),
    :$application,
    after => [
        Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
    ]
);

Better cro trace output for web sockets

Recently, the trace-output method was added to Cro::Message. We should override it in the web socket frame and message classes in order to do a better job of showing the content.

Websocket not always keeping Close promise

Websocket Close Promise doesn't fire during abnormal closures. A poorly configured firewall lead me to finding out that timed-out connections were not being cleaned up.

The below script simply sets up a socket and tells the user to run ss --kill in another session. This isn't exactly the same as the firewall timeout, but it does demonstrates the same issue.

I do get a "software caused connection abort" message which seems to originate from libuv. A connection timeout doesn't print a message in the terminal.

CRO_TRACE=1 indicates many components receive a DONE event.

use Cro::HTTP::Router;
use Cro::HTTP::Router::WebSocket;
use Cro::HTTP::Server;
use Cro::WebSocket::Client;

my $http-request;
my $application = route {
  get -> 'websocket' {
    $http-request = request;

    web-socket -> $incoming, $close {
      supply {
        whenever $incoming -> $msg {
           await($msg.body).say;
        }
        whenever $close {
           say "NEVER HERE";
        }
      }
    }
  }
}

my $cro-service = Cro::HTTP::Server.new(:http<1.1>, :host<0.0.0.0>, :port<10200>, :$application);
$cro-service.start;

{
    my $connection = await Cro::WebSocket::Client.connect: 'http://localhost:10200/websocket';
    $connection.send('Have Connection');
}

# Text will report "software caused connection abort" but $close will not fire.
say 'Run: sudo ss --kill dst %s/32 dport %s'.sprintf($http-request.connection.peer-host, $http-request.connection.peer-port);

react whenever signal(SIGINT) {
    $cro-service.stop;
    exit;
}

segfaults when certain errors inside websocket whenever blocks

As shown in the significantly golfed code below, certain errors can trigger segfaults if they occur inside a WebSocket whenever block. I have only been able to trigger this error with the X::AdHoc error thrown by a monitor (for which I opened a separate issue, jnthn/oo-monitors#18). I'm not sure if other errors would trigger the same behavior, but wasn't able to do so with die.

use Cro::HTTP::Router;
use Cro::HTTP::Server;
use Cro::HTTP::Router::WebSocket;
use Cro::WebSocket::Client;
use OO::Monitors;

monitor M { has $.x = 2}
my Supplier $incoming .= new;

my $application = route {
    get { web-socket { supply whenever $incoming { M.new.clone: :0x }}}}

Cro::HTTP::Server.new(:host<localhost>, :port(10000), :$application).start;
Cro::WebSocket::Client.connect('ws://localhost:10000').result.send: '';
$incoming.emit: 1;

await Promise.new;
# OUTPUT: 
# A WebSocket handler crashed: Cannot copy object with representation ReentrantMutex
#  in block <unit> at segfault.golfed.rakumod line 11
#
# segmentation fault (core dumped)

I'll post the output from perl6-gdb-m in a reply.

The "Timeout breaks ping promise" test in the t/websocket-client.t occasionally fails

t/websocket-client.t seems unstable it occasionally fails.

Result:

$ PERL6LIB=lib prove -v -r --exec=perl6 t/websocket-client.t 
t/websocket-client.t .. 
ok 1 - Cannot send anything to closed channel(by done)
ok 2 - Empty ping is recieved
ok 3 - Ping is recieved
not ok 4 - Timeout breaks ping promise
# Failed test 'Timeout breaks ping promise'
# at t/websocket-client.t line 88
ok 5 - 
ok 6 - The connection is closed by close() call
ok 7 - Cannot send anything to closed channel by close() call
ok 8 - Can send Hash using client with JSON body serializer installed
ok 9 - Got hash back from body, thanks to JSON body parser
ok 10 - Correct hash content (1)
ok 11 - Correct hash content (2)
ok 12 - Correct hash content (3)
ok 13 - Can send Hash using client constructed with :json
ok 14 - Got hash back from body, thanks to :json
ok 15 - Correct hash content (1)
ok 16 - Correct hash content (2)
ok 17 - Correct hash content (3)
1..17
# Looks like you failed 1 test of 17
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/17 subtests 

Test Summary Report
-------------------
t/websocket-client.t (Wstat: 256 Tests: 17 Failed: 1)
  Failed test:  4
  Non-zero exit status: 1
Files=1, Tests=17,  2 wallclock secs ( 0.02 usr  0.00 sys +  2.44 cusr  0.26 csys =  2.72 CPU)
Result: FAIL

All of the results: https://gist.github.com/titsuki/26fa50d6ce15697424ad4081f022dcf1

Perl 6 version:

$ perl6 --version
This is Rakudo version 2017.12-211-g029226fe9 built on MoarVM version 2017.12.1-30-ged7c1234f
implementing Perl 6.c.

Zef installed modules:

$ zef list --installed
===> Found via /home/itoyota/rakudo/install/share/perl6
CORE:ver<6.c>:auth<perl>
===> Found via /home/itoyota/rakudo/install/share/perl6/site
App::Mi6:ver<0.1.2>
Base64:ver<0.0.1>:auth<github:ugexe>
Bench:ver<0.1.5>:auth<github:tony-o>
CPAN::Uploader::Tiny:ver<0.0.3>
Config::JSON:ver<1.001003>
Cro::Core:ver<0.7.3>
Cro::HTTP:ver<0.7.3>
Cro::TLS:ver<0.7.3>
Cro::WebSocket:ver<0.7.3>
Crypt::Random:ver<0.4.1>:auth<github:skinkade>
Digest::HMAC:ver<1.0.0>:auth<github:retupmoca>
Digest::SHA1::Native:ver<0.02>
Digest:ver<0.3.4>:auth<Lucien Grondin>
File::Directory::Tree:auth<labster>
File::Find:ver<0.1>
File::Temp:ver<0.0.6>
File::Which:ver<1.0.0>
HTTP::HPACK:ver<0.9.2>
HTTP::Tinyish:ver<0.1.0>
IO::Path::ChildSecure:ver<1.001010>
IO::Socket::Async::SSL:ver<0.6.1>
JSON::Class:ver<0.0.10>:auth<github:jonathanstowe>
JSON::Fast:ver<0.9.9>
JSON::JWT:ver<1.0>:auth<github:retupmoca>
JSON::Marshal:ver<0.0.14>:auth<github:jonathanstowe>
JSON::Name:ver<0.0.2>:auth<github:jonathanstowe>
JSON::Pretty:ver<0.1.0>:auth<github:FROGGS>
JSON::Tiny:ver<1.0>
JSON::Unmarshal:ver<0.08>
LibraryMake:ver<1.0.0>:auth<github:retupmoca>
META6:ver<0.0.19>:auth<github:jonathanstowe>
MIME::Base64:ver<1.2.1>:auth<github:retupmoca>
MeCab:ver<0.0.5>
OO::Monitors:ver<1.1>
OpenSSL:ver<0.1.18>:auth<github:sergot>
Pod::To::HTML:ver<0.3.13>
Pod::To::Markdown:ver<.0.1.3>
Shell::Command
Temp::Path:ver<1.001003>
Terminal::ANSIColor:ver<0.4>
Test::META:ver<0.0.13>:auth<github:jonathanstowe>
Test::When:ver<1.001008>
Testo:ver<1.003004>
Text::Table::Simple:ver<0.0.5>:auth<github:ugexe>
URI::Encode:ver<0.05>:auth<David Farrell>
URI:ver<0.1.4>
YAMLish:ver<0.0.4>:auth<Leon Timmermans>
Z-Script:ver<1.001002>
cro:ver<0.7.3>
if:ver<0.1.0>:auth<github:FROGGS>
zef:ver<0.1.32>:auth<github:ugexe>
zef:ver<0.2.2>:auth<github:ugexe>

(and sorry for my pull request that was off the point)

Disconnect does not allow for 2-byte status code

I came a cropper of a bug that I debugged like this

--- a/lib/Cro/WebSocket/BodyParsers.pm6
+++ b/lib/Cro/WebSocket/BodyParsers.pm6
@@ -30,6 +30,7 @@ class Cro::WebSocket::BodyParser::JSON does Cro::BodyParser {
 
     method parse($message) {
         $message.body-blob.then: -> $blob-promise {
+            CATCH { say "Not good stuff: " ~ $blob-promise.result.gist }
             from-json $blob-promise.result.decode('utf-8')
         }
     }

The RFC says the first two bytes are an unsigned integer and the rest is whatever.

If there is a body, the first two bytes of the body MUST be a 2-byte unsigned integer (in network byte order) representing a status code with value /code/ defined in Section 7.4. Following the 2-byte integer, the body MAY contain UTF-8-encoded data with value /reason/, the interpretation of which is not defined by this specification.

A websocket I tested with sends non-JSON as reason, but it chokes on decode('utf-8') anyway.

I think close frames should be handled specially but I'm still too novice at this to risk a submission.

Cro::WebSocket::Client.new :headers can't take Pairs (contradicting the documentation)

https://cro.services/docs/reference/cro-websocket-client says

To pass extra headers with the WebSocket handshake HTTP request, pass a list of them with the headers named argument. They can be passed as Pairs or as instances of Cro::HTTP::Header.

my $client = Cro::WebSocket::Client.new:
    uri => 'ws://some.host:1234/path/to/chat',
    headers => [
        referer => 'http://anotherexample.com',
        Cro::HTTP::Header.new(
            name => 'User-agent',
            value => 'Cro'
        )
    ];

If I try this code I get this error:

$ ~/Install/rakduo-2021.10/bin/rakudo client.p6
No such method 'name' for invocant of type 'Pair'.  Did you mean any of
these: 'none', 'note', 'take'?
  in submethod BUILD at /home/nick/Install/rakduo-2021.10/share/perl6/site/sources/CC4AC4535A4D41280A36B0E08E6B7B769FC7D528 (Cro::WebSocket::Client) line 1
  in block <unit> at client.p6 line 5

Line numbers are mangled there, but I think that the problem is this code in Cro::WebSocket::Client BUILD:

        without @headers.first(*.name.lc eq 'sec-websocket-protocol') {
            @!headers.append(Cro::HTTP::Header.new(name => 'Sec-WebSocket-Protocol', value => 'echo-protocol'));
        }

I don't know how to fix this cleanly.

There don't seem to be any regression tests for setting headers.

My "work around" is to build a Cro::HTTP::Header object - hardly a messy hack, but it would have been nicer to use a pair.

Allow websocket routine with no arguments (and be less eager to CATCH)

You currently have to do either

web-socket -> $incoming -> { }

or

web-socket -> $incoming, $on-close -> { }

As usual with my persistent bastardisations of your code, I don't actually use either thing in my test code, so I just had

web-socket -> { }

This caused the obscure error

  in code  at .../lib/Cro/WebSocket/Handler.pm6 (Cro::WebSocket::Handler) line 50

A runtime error from Perl caught by an overeager CATCH. First, it would be nice to support no arguments here; second, some errors should just die hard and I think ones from Perl6 itself should be included.

The "Empty ping is recieved" test in the t/websocket-client.t fails 2 times out of 1000

About 2 times out of 1000, the "Empty ping is recieved" test in the t/websocket-client.t fails.


Experiment

I executed this script:

for i in `seq 1 1000`; do
    PERL6LIB=lib prove -v -r --exec=perl6 t/websocket-client.t
done
$ bash test.sh &> cro-result.txt

After the execution, I did grep:

$ grep "# Failed" cro-result.txt
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Ping is recieved'
# Failed test 'Ping is recieved'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Empty ping is recieved'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Empty ping is recieved'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Ping is recieved'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'
# Failed test 'Timeout breaks ping promise'

The empty ping error was caused 2 times:

$ grep "# Failed" cro-result.txt | grep "Empty" | wc -l
2

version:

$ perl6 --version
This is Rakudo version 2018.02.1-172-g34889bebc built on MoarVM version 2018.02-171-geee5be412
implementing Perl 6.c.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.