bbkr / json-rpc Goto Github PK
View Code? Open in Web Editor NEWJSON-RPC client and server for Raku language.
License: Artistic License 2.0
JSON-RPC client and server for Raku language.
License: Artistic License 2.0
This is really old module - it was started back in 2010 when Rakudo was running on ParrotVM and spec (especially concurrency parts) was in flux. Moreover - it started as JSON-RPC 1.0 client, while 2.0 spec brought significant changes that requires better abstraction to avoid messy procedural code flow.
What needs to be done:
[A,B]
request where A is notification, and B is regular request response will look like [B]
, forcing user to recalculate stack positions. If client calls B he should be able to retrieve response directly from this call. I'm not sure what would be the best interface. Maybe $response = $client.method_call()
single calls should look like $promise = $client.'rpc.batch'.method_call()
in Batches so clients can get response directly from Promise object without stack recalculations? Promises looks... promising, because they may also allow to start batch processing my $batch = $client.'rpc.batch'(); await $batch
instead of special $batch->flush
keyword.Request ID looks like
0 1 2 3 4 5 6 7 8 9A B C D E F G H I J K L M N O P Q R S T U V W X Y Za b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Za b c d e f g h i j k l m n o p q r s t u v w x y za b c d e f g h i j k l m n o p q r s t u v w x y z0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9a b c d e f g h i j k l m n o p q r s t u v w x y za b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z0 1 2 3 4 5 6 7 8 9A B C D E F G H I
Probably something changed in
sub sequencer {
state @pool = 'a' .. 'z', 'A' .. 'Z', 0 .. 9;
return @pool.roll( 32 ).join( );
}
Markdown is not useful when code is distributed in Star bundle.
Exceptions won't be thrown on error, instead of that exception objects will be returned in result array.
This has to be implemented along with notifications, because notifications should be skipped in response batch while maintaining requests order.
Interface suggestion:
$client.rpc.batch.method_name("param");
$client.rpc.batch.rpc.notification.method_name("param"); # notification in batch
$client.rpc.batch.method_name("param");
my @results = $client.rpc.flush;
Spec 4.1 Notification.
Interface suggestion:
$client.rpc.notification.method_name("param1", "param2");
Request object
, so it's easy to handle notifications on dispatch level.[2013-03-11T01:50:59Z] GET http://www.travelimgusa.com/ip.php HTTP/1.1
recv failed: Connection reset by peer
in method get at src/gen/CORE.setting:8327
It should abandon processing and listen for next request.
Spec 4.1 Notification.
Param list should stay unmodified, I don't think that $server.add(5,6,:notification)
is a good idea.
The correct way nowadays is to omit the *
from self.bless(*, ...)
.
Currently usage of the * warns, but it will die soon.
When this module was rewritten for Rakudo NOM branch URI module was broken.
Now that it's fixed it's time to abandon built-in mini-grammar for client uri parsing.
client.t test failed due to %request{'id'} eqv $response{'id'} failed.
Which request id is 'Any::U' but server responed 'Any'.
Error msg:
Request id is different than response id (-32000): {:request(${:id(Any:U), :jsonrpc("2.0"), :method("ping")}), :response(${:id(Any), :jsonrpc("2.0"), :result("pong")})}
I'm not really familiar with Perl6 but I try to point out possible lines caused this:
https://github.com/bbkr/jsonrpc/blob/c1ff17aa829075e2fb708e367da097a6a577a149/t/client.t#L222
https://github.com/bbkr/jsonrpc/blob/c1ff17aa829075e2fb708e367da097a6a577a149/lib/JSON/RPC/Client.pm#L298
https://github.com/bbkr/jsonrpc/blob/c1ff17aa829075e2fb708e367da097a6a577a149/lib/JSON/RPC/Server.pm#L116
https://github.com/bbkr/jsonrpc/blob/c1ff17aa829075e2fb708e367da097a6a577a149/lib/JSON/RPC/Server.pm#L153
I just installed perl6 on my box following this howto: http://rakudo.org/how-to-get-rakudo/
git clone https://github.com/tadzik/rakudobrew ~/.rakudobrew
echo 'export PATH=~/.rakudobrew/bin:$PATH' >> ~/.bash_profile
source ~/.bash_profile
rakudobrew build moar
rakudobrew build-panda
Problem firstly accured when I try to panda install Task::Star
and it stopped at JSON::RPC.
I'm still stuck here now.
Rakudo built from Git.
$ prove -r -e "perl6 -Ilib" t
t/server.t .. ok
t/client.t .. 3/39 Too many positionals passed; expected 1 argument but got 2
in method rpc.notification at /Users/gabor/work/jsonrpc/lib/JSON/RPC/Client.pm:152
in block <unit> at t/client.t:49
# Looks like you planned 39 tests, but ran 4
t/client.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 35/39 subtests
Test Summary Report
-------------------
t/client.t (Wstat: 65280 Tests: 4 Failed: 0)
Non-zero exit status: 255
Parse errors: Bad plan. You planned 39 tests but ran 4.
Files=2, Tests=33, 16 wallclock secs ( 0.05 usr 0.01 sys + 22.93 cusr 0.62 csys = 23.61 CPU)
Result: FAIL
perl6 version:
This is perl6 version 2015.07.1-868-g5cc2563 built on MoarVM version 2015.08-15-g4b427ed
I was trying to install JSON::RPC
via panda and the tests failed on me. Here is the output:
qlx4r@qp11 ~$ panda install JSON::RPC
==> Fetching JSON::RPC
==> Building JSON::RPC
==> Testing JSON::RPC
# Failed test 'rpc call Batch (all notifications)'
# at t/client.t line 190
# Died
# Failed test 'rpc call Batch (all notifications) validate'
# at t/client.t line 195
# Actual type: Any
# Failed test 'not ordered Batch'
# at t/client.t line 237
# Died
# Failed test 'not ordered Batch validate'
# at t/client.t line 242
# expected: 'pong'
# got: '7'
# Failed test 'not ordered Batch validate'
# at t/client.t line 243
# expected: 'ping'
# got: '19'
# Failed test 'duplicated id in Batch'
# at t/client.t line 257
# Died
# Failed test 'duplicated id in Batch validate'
# at t/client.t line 262
# expected: 'pong'
# got: '7'
# Failed test 'duplicated id in Batch validate'
# at t/client.t line 263
# expected: 'ping'
# got: '19'
# Failed test 'amount of Responses in Batch different than expected validate'
# at t/client.t line 283
# Actual type: X::AdHoc
# Looks like you failed 9 tests of 39
t/client.t ..
Dubious, test returned 9 (wstat 2304, 0x900)
Failed 9/39 subtests
t/server.t .. ok
Test Summary Report
-------------------
t/client.t (Wstat: 2304 Tests: 39 Failed: 9)
Failed tests: 24-25, 31-37
Non-zero exit status: 9
Files=2, Tests=68, 13 wallclock secs ( 0.04 usr 0.00 sys + 12.31 cusr 0.10 csys = 12.45 CPU)
Result: FAIL
test stage failed for JSON::RPC: Tests failed
in method throw at /home/qlx4r/.rakudobrew/moar-nom/install/share/perl6/runtime/CORE.setting.moarvm:1
in method install at /home/qlx4r/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:142
in method resolve at /home/qlx4r/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:219
in sub MAIN at /home/qlx4r/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:18
in block <unit> at /home/qlx4r/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:95
Failure Summary
----------------
JSON::RPC(
*test stage failed for JSON::RPC: Tests failed)
With example Client/Server the client outputs:
Parse error (-32700): "Input (0 characters) is not a valid JSON string"
$ perl6 -v This is Rakudo version 2017.04.3 built on MoarVM version 2017.04-53-g66c6dda implementing Perl 6.c.
Currently requests in batch are sequential. Which reduces transfer cost only. Once MoarVM concurrency is stable batches should get Promise-based processing.
I'm trying to install Task::Star, following the instructions given with rakudobrew. MoarVM and panda install fine. The output of moar --version
is
This is MoarVM version 2015.10-103-gaf3b12e built with JIT support
I get the following errors. The tests fail in the same way whether installing as part of Task::Star or panda install JSON::RPC
.
==> Fetching JSON::RPC
==> Building JSON::RPC
==> Testing JSON::RPC
# Failed test 'rpc call Batch'
# at t/client.t line 165
# Too many positionals passed; expected 1 argument but got 4
# Failed test 'rpc call Batch validate'
# at t/client.t line 174
# expected: '7'
# got: (Failure)
# Failed test 'rpc call Batch validate'
# at t/client.t line 175
# expected: '19'
# got: (Failure)
# Failed test 'rpc call Batch validate'
# at t/client.t line 177
# Actual type: Any
Use of uninitialized value @responses of type Any in string context
Any of .^name, .perl, .gist, or .say can stringify undefined things, if needed. in block at t/client.t:178
# Failed test 'rpc call Batch validate'
# at t/client.t line 179
# Actual type: Any
# Failed test 'rpc call Batch validate'
# at t/client.t line 180
# expected: $["hello", 5]
# got: Any
# Looks like you failed 6 tests of 39
t/client.t ..
Dubious, test returned 6 (wstat 1536, 0x600)
Failed 6/39 subtests
t/server.t .. ok
# Failed test 'notification was processed'
# at t/server.t line 239
# expected: '7'
# got: ''
It disappears if Application class method
method notify_hello ( $count ){ $.count = $count; }
is changed for example to
method notify_hello ( $count ){ $.count = $count; say $.count; }
During overnight run following request crashed server:
[2013-03-11T02:18:09Z] GET /robots.txt HTTP/1.1
Nominal type check failed for parameter '$json'; expected Str but got Any instead
Previous requests were fine,
[2013-03-10T23:31:13Z] GET /robots.txt HTTP/1.1
[2013-03-10T23:53:11Z] GET /robots.txt HTTP/1.1
It should enter handler and return Parse Error.
Currently exceptions are in X::JSON::RPC::WhatWentWrong form, while best practice is JSON::RPC::X::WhatWentWrong.
Check ecosystem for potential compatibility breaks.
Rakudobrew on Ubuntu 15.04 & Linux Mint 17.2;
Running :~$ panda install Task::Star
Result:
~$ panda install Task::Star
==> Task::Star depends on JSON::RPC, Pod::To::HTML, p6doc
==> p6doc depends on File::Temp
==> File::Temp depends on File::Directory::Tree
==> Fetching JSON::RPC
==> Building JSON::RPC
==> Testing JSON::RPC
Request id is different than response id (-32000): {:request(${:id(Any:U), :jsonrpc("2.0"), :method("ping")}), :response(${:id(Any), :jsonrpc("2.0"), :result("pong")})}
# Looks like you planned 39 tests, but ran 29
t/client.t ..·
Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 10/39 subtests·
t/server.t .. ok
Test Summary Report
-------------------
t/client.t (Wstat: 65280 Tests: 29 Failed: 0)
Non-zero exit status: 255
Parse errors: Bad plan. You planned 39 tests but ran 29.
Files=2, Tests=58, 11 wallclock secs ( 0.04 usr 0.00 sys + 11.44 cusr 0.12 csys = 11.60 CPU)
Result: FAIL
test stage failed for JSON::RPC: Tests failed
in method throw at /home/eric/.rakudobrew/moar-nom/install/share/perl6/runtime/CORE.setting.moarvm:1
in method install at /home/eric/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:142
in block at /home/eric/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:214
in method resolve at /home/eric/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:208
in sub MAIN at /home/eric/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:18
in block <unit> at /home/eric/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:145
Failure Summary
----------------
Task::Star(
*test stage failed for JSON::RPC: Tests failed)
vytas-local@vytas-desktop:/tmp$ perl6 -v
This is perl6 version 2015.09-355-g06fef86 built on MoarVM version 2015.09-79-gee9fc2b
vytas-local@vytas-desktop:/tmp$ panda install Task::Star
[...]
==> Building JSON::RPC
==> Testing JSON::RPC
**Request id is different than response id (-32000): {:request(${:id(Any:U), :jsonrpc("2.0"), :method("ping")}), :response(${:id(Any), :jsonrpc("2.0"), :result("pong")})}
t/client.t ..
Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 10/39 subtests
t/server.t .. ok
t/client.t (Wstat: 65280 Tests: 29 Failed: 0)
Non-zero exit status: 255
Parse errors: Bad plan. You planned 39 tests but ran 29.
Files=2, Tests=58, 14 wallclock secs ( 0.03 usr 0.01 sys + 13.40 cusr 0.18 csys = 13.62 CPU)
Result: FAIL
test stage failed for JSON::RPC: Tests failed
in method throw at /home/vytas-local/.rakudobrew/moar-nom/install/share/perl6/runtime/CORE.setting.moarvm:1
in method install at /home/vytas-local/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:142
in block at /home/vytas-local/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:214
in method resolve at /home/vytas-local/.rakudobrew/moar-nom/install/share/perl6/site/lib/Panda.pm:208
in sub MAIN at /home/vytas-local/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:18
in block at /home/vytas-local/.rakudobrew/bin/../moar-nom/install/share/perl6/site/bin/panda:145
Task::Star(
*test stage failed for JSON::RPC: Tests failed)
2.23s$ PERL6LIB=lib prove -v -r --exec=perl6 t/
t/client.t .. ===SORRY!===
Could not find JSON::Tiny:ver<True>:auth<True>:api<True> in:
/home/travis/build/bbkr/jsonrpc/lib
/home/travis/.perl6/2015.11-374-g539b5f4
/home/travis/.rakudobrew/moar-nom/install/share/perl6/site
/home/travis/.rakudobrew/moar-nom/install/share/perl6/vendor
/home/travis/.rakudobrew/moar-nom/install/share/perl6
Dubious, test returned 1 (wstat 256, 0x100)
No subtests run
t/server.t .. ===SORRY!===
Could not find JSON::Tiny:ver<True>:auth<True>:api<True> in:
/home/travis/build/bbkr/jsonrpc/lib
/home/travis/.perl6/2015.11-374-g539b5f4
/home/travis/.rakudobrew/moar-nom/install/share/perl6/site
/home/travis/.rakudobrew/moar-nom/install/share/perl6/vendor
/home/travis/.rakudobrew/moar-nom/install/share/perl6
Dubious, test returned 1 (wstat 256, 0x100)
No subtests run
Can you please "GIT TAG" your RAKU modules with it's version, similar and at the same time you maintain it's "version": "x.y.z" in your META6.json
file?
I was told, this will happen "for free" going forward with mi6 anyhow, but for now it would be great if you spend those 2 seconds already now :)
"Tagging" is generally highly appreciated in regards to "reproducible builds" and here especially for the "Rakudo Star" modules
THANK YOU!
Tests fail:
$ prove -e 'perl6' -vlr t/
t/client.t .. ===SORRY!===
Expected MAST::Frame, but didn't get one
Dubious, test returned 1 (wstat 256, 0x100)
No subtests run
t/server.t ..
1..29
ok 1 - The object is-a 'JSON::RPC::Server'
ok 2 - rpc call with positional parameters
ok 3 - rpc call with positional parameters
ok 4 - rpc call with named parameters
ok 5 - rpc call with named parameters
ok 6 - a Notification
ok 7 - a Notification
ok 8 - rpc call of non-existent method
ok 9 - rpc call with invalid JSON
ok 10 - rpc call with invalid Request object
ok 11 - rpc call Batch, invalid JSON
ok 12 - rpc call with an empty Array
ok 13 - rpc call with an invalid Batch (but not empty)
ok 14 - rpc call with invalid Batch
ok 15 - rpc call Batch
ok 16 - rpc call Batch (all notifications)
ok 17 - no params and empty response
ok 18 - method named rpc can be called
ok 19 - parse error (empty string)
ok 20 - parse error (top container is not JSON Object or Array)
ok 21 - invalid request (null is not the same as omitted params)
ok 22 - invalid params (no candidate found)
ok 23 - private method not found
ok 24 - batch recursion forbidden
ok 25 - null id does not mean notification (null is not the same as omitted id)
ok 26 - internal error
ok 27 - custom error
ok 28 - can invoke language built-in method name
ok 29 - notification was processed
ok
Test Summary Report
-------------------
t/client.t (Wstat: 256 Tests: 0 Failed: 0)
Non-zero exit status: 1
Parse errors: No plan found in TAP output
Files=2, Tests=29, 8 wallclock secs ( 0.04 usr 0.00 sys + 8.06 cusr 0.35 csys = 8.45 CPU)
Result: FAIL
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.