From 5f8e515c824b6d555b8b0e7b1187b5b76d34d6af Mon Sep 17 00:00:00 2001 From: Tom Molesworth Date: Wed, 23 Oct 2024 03:53:44 +0800 Subject: [PATCH 1/3] Reformat --- lib/Myriad/RPC/Client/Implementation/Memory.pm | 8 ++++++-- lib/Myriad/RPC/Client/Implementation/Redis.pm | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Myriad/RPC/Client/Implementation/Memory.pm b/lib/Myriad/RPC/Client/Implementation/Memory.pm index 7529984e..bb98ddeb 100644 --- a/lib/Myriad/RPC/Client/Implementation/Memory.pm +++ b/lib/Myriad/RPC/Client/Implementation/Memory.pm @@ -91,9 +91,13 @@ async method call_rpc ($service, $method, %args) { return $message->response->{response}; } catch ($e) { if ($e =~ /Timeout/) { - $e = Myriad::Exception::RPC::Timeout->new(reason => 'deadline is due'); + $e = Myriad::Exception::RPC::Timeout->new( + reason => 'deadline is due' + ); } else { - $e = Myriad::Exception::InternalError->new(reason => $e) unless blessed $e && $e->DOES('Myriad::Exception'); + $e = Myriad::Exception::InternalError->new( + reason => $e + ) unless blessed $e && $e->DOES('Myriad::Exception'); } $pending->fail($e); delete $pending_requests->{$message_id}; diff --git a/lib/Myriad/RPC/Client/Implementation/Redis.pm b/lib/Myriad/RPC/Client/Implementation/Redis.pm index 90a2ae5b..24b61b58 100644 --- a/lib/Myriad/RPC/Client/Implementation/Redis.pm +++ b/lib/Myriad/RPC/Client/Implementation/Redis.pm @@ -101,13 +101,17 @@ async method call_rpc($service, $method, %args) { } catch ($e) { $log->warnf('Failed on RPC call - %s', $e); if ($e =~ /Timeout/) { - $e = Myriad::Exception::RPC::Timeout->new(reason => 'deadline is due'); + $e = Myriad::Exception::RPC::Timeout->new( + reason => 'deadline is due' + ); } else { - $e = Myriad::Exception::InternalError->new(reason => $e) unless blessed $e && $e->DOES('Myriad::Exception'); + $e = Myriad::Exception::InternalError->new( + reason => $e + ) unless blessed $e && $e->DOES('Myriad::Exception'); } $pending->fail($e); delete $pending_requests->{$message_id}; - $e->throw(); + $e->throw; } } From 0b847a4435e8f4651b6dd69cd3d395f6fe4fb327 Mon Sep 17 00:00:00 2001 From: Tom Molesworth Date: Wed, 23 Oct 2024 03:54:09 +0800 Subject: [PATCH 2/3] Rethrow exception from RPC call if we had one --- .../RPC/Client/Implementation/Memory.pm | 5 +++++ lib/Myriad/RPC/Client/Implementation/Redis.pm | 5 +++++ t/RPC/full-cycle.t | 22 ++++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/Myriad/RPC/Client/Implementation/Memory.pm b/lib/Myriad/RPC/Client/Implementation/Memory.pm index bb98ddeb..ef72d66d 100644 --- a/lib/Myriad/RPC/Client/Implementation/Memory.pm +++ b/lib/Myriad/RPC/Client/Implementation/Memory.pm @@ -88,6 +88,11 @@ async method call_rpc ($service, $method, %args) { $self->loop->timeout_future(at => $deadline), $pending ); + if(my $err = $message->response->{error}) { + Myriad::Exception::InternalError->new( + reason => $err + )->throw; + } return $message->response->{response}; } catch ($e) { if ($e =~ /Timeout/) { diff --git a/lib/Myriad/RPC/Client/Implementation/Redis.pm b/lib/Myriad/RPC/Client/Implementation/Redis.pm index 24b61b58..aa0a2592 100644 --- a/lib/Myriad/RPC/Client/Implementation/Redis.pm +++ b/lib/Myriad/RPC/Client/Implementation/Redis.pm @@ -97,6 +97,11 @@ async method call_rpc($service, $method, %args) { $pending ); + if(my $err = $message->response->{error}) { + Myriad::Exception::InternalError->new( + reason => $err + )->throw; + } return $message->response->{response}; } catch ($e) { $log->warnf('Failed on RPC call - %s', $e); diff --git a/t/RPC/full-cycle.t b/t/RPC/full-cycle.t index 911f222b..54fdc2c9 100644 --- a/t/RPC/full-cycle.t +++ b/t/RPC/full-cycle.t @@ -3,6 +3,7 @@ use warnings; use Test::More; use Test::Deep; +use Test::Fatal; use Test::Myriad; use Log::Any::Adapter qw(TAP); @@ -17,6 +18,9 @@ package Test::Ping { async method ping : RPC (%args) { return await $api->service_by_name('Test::Pong')->call_rpc('pong'); } + async method throws_error : RPC (%args) { + die 'some error here'; + } } package Test::Pong { @@ -35,14 +39,26 @@ BEGIN { await Test::Myriad->ready(); subtest 'RPC should return a response to caller' => sub { - my $resposne = $pong_service->call_rpc('pong')->get; - cmp_deeply($resposne, {pong => 1}); + my $response = $pong_service->call_rpc('pong')->get; + cmp_deeply($response, {pong => 1}); + done_testing; }; subtest 'RPC client should receive a response' => sub { my $response = $ping_service->call_rpc('ping')->get(); cmp_deeply($response, {pong => 1}); + done_testing; +}; + +subtest 'Methods which throw errors should raise an exception in the caller too' => sub { + my $ex = exception { + my $response = $ping_service->call_rpc('throws_error')->get(); + note explain $response; + }; + isa_ok($ex, 'Myriad::Exception::InternalError'); + like($ex->reason->{reason}, qr/some error here/, 'exception had original message'); + done_testing; }; -done_testing(); +done_testing; From 4635af4bb1baa1e23c91258144fc85d47d447c24 Mon Sep 17 00:00:00 2001 From: Tom Molesworth Date: Wed, 23 Oct 2024 03:54:56 +0800 Subject: [PATCH 3/3] The $pending Future is marked as ready if we had a timeout or a response, no need to fail in those cases --- lib/Myriad/RPC/Client/Implementation/Memory.pm | 2 +- lib/Myriad/RPC/Client/Implementation/Redis.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Myriad/RPC/Client/Implementation/Memory.pm b/lib/Myriad/RPC/Client/Implementation/Memory.pm index ef72d66d..7a70120e 100644 --- a/lib/Myriad/RPC/Client/Implementation/Memory.pm +++ b/lib/Myriad/RPC/Client/Implementation/Memory.pm @@ -104,7 +104,7 @@ async method call_rpc ($service, $method, %args) { reason => $e ) unless blessed $e && $e->DOES('Myriad::Exception'); } - $pending->fail($e); + $pending->fail($e) unless $pending->is_ready; delete $pending_requests->{$message_id}; $e->throw(); } diff --git a/lib/Myriad/RPC/Client/Implementation/Redis.pm b/lib/Myriad/RPC/Client/Implementation/Redis.pm index aa0a2592..ec9097cd 100644 --- a/lib/Myriad/RPC/Client/Implementation/Redis.pm +++ b/lib/Myriad/RPC/Client/Implementation/Redis.pm @@ -114,7 +114,7 @@ async method call_rpc($service, $method, %args) { reason => $e ) unless blessed $e && $e->DOES('Myriad::Exception'); } - $pending->fail($e); + $pending->fail($e) unless $pending->is_ready; delete $pending_requests->{$message_id}; $e->throw; }