Skip to content

Commit

Permalink
fix(cli): streamorders handling xud not ready (#1663)
Browse files Browse the repository at this point in the history
This fixes the behavior of the `streamorders` cli command when xud is
not ready for the call. Previously, if xud was locked it would stream
an endless series of reconnecting messages and if xud was not running
on the specified host/port at all it would simply hang. Now the command
exits with an appropriate error message in such cases.
  • Loading branch information
sangaman authored Jun 16, 2020
1 parent f3d3b69 commit 1f9e82f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
20 changes: 16 additions & 4 deletions lib/cli/commands/streamorders.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ServiceError, status } from 'grpc';
import { Arguments, Argv } from 'yargs';
import { XudClient } from '../../proto/xudrpc_grpc_pb';
import * as xudrpc from '../../proto/xudrpc_pb';
import { setTimeoutPromise } from '../../utils/utils';
import { loadXudClient } from '../command';

export const command = 'streamorders [existing]';
Expand All @@ -24,10 +26,15 @@ const ensureConnection = async (argv: Arguments, printError?: boolean) => {
if (!client) {
client = await loadXudClient(argv);
}
client.waitForReady(Number.POSITIVE_INFINITY, (error: Error | null) => {
client.waitForReady(Date.now() + 3000, (error: Error | null) => {
if (error) {
if (error.message === 'Failed to connect before the deadline') {
console.error(`could not connect to xud at ${argv.rpchost}:${argv.rpcport}, is xud running?`);
process.exit(1);
}

if (printError) console.error(`${error.name}: ${error.message}`);
setTimeout(ensureConnection.bind(undefined, argv), 3000);
setTimeout(ensureConnection.bind(undefined, argv, printError), 3000);
} else {
console.log('Successfully connected, subscribing for orders');
streamOrders(argv);
Expand All @@ -50,8 +57,13 @@ const streamOrders = (argv: Arguments<any>) => {
// adding end, close, error events only once,
// since they'll be thrown for three of subscriptions in the corresponding cases, catching once is enough.
ordersSubscription.on('end', reconnect.bind(undefined, argv));
ordersSubscription.on('error', async (err: Error) => {
console.warn(`Unexpected error occured: ${err.message}, trying to reconnect`);
ordersSubscription.on('error', async (err: ServiceError) => {
if (err.code === status.UNIMPLEMENTED) {
console.error("xud is locked, run 'xucli unlock', 'xucli create', or 'xucli restore' then try again");
process.exit(1);
}
console.warn(`Unexpected error occured: ${err.message}, reconnecting in 1 second`);
await setTimeoutPromise(1000);
await ensureConnection(argv);
});

Expand Down
9 changes: 3 additions & 6 deletions lib/grpc/GrpcService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,7 @@ class GrpcService {
* See [[Service.subscribeOrders]]
*/
public subscribeOrders: grpc.handleServerStreamingCall<xudrpc.SubscribeOrdersRequest, xudrpc.OrderUpdate> = (call) => {
if (!this.service) {
call.emit('error', { code: status.UNAVAILABLE, message: 'xud is starting', name: 'NotReadyError' });
if (!this.isReady(this.service, call)) {
return;
}
this.service.subscribeOrders(call.request.toObject(), (order?: Order, orderRemoval?: OrderPortion) => {
Expand All @@ -848,8 +847,7 @@ class GrpcService {
* See [[Service.subscribeSwapFailures]]
*/
public subscribeSwapFailures: grpc.handleServerStreamingCall<xudrpc.SubscribeSwapsRequest, xudrpc.SwapFailure> = (call) => {
if (!this.service) {
call.emit('error', { code: status.UNAVAILABLE, message: 'xud is starting', name: 'NotReadyError' });
if (!this.isReady(this.service, call)) {
return;
}
this.service.subscribeSwapFailures(call.request.toObject(), (result: SwapFailure) => {
Expand All @@ -862,8 +860,7 @@ class GrpcService {
* See [[Service.subscribeSwaps]]
*/
public subscribeSwaps: grpc.handleServerStreamingCall<xudrpc.SubscribeSwapsRequest, xudrpc.SwapSuccess> = (call) => {
if (!this.service) {
call.emit('error', { code: status.UNAVAILABLE, message: 'xud is starting', name: 'NotReadyError' });
if (!this.isReady(this.service, call)) {
return;
}
this.service.subscribeSwaps(call.request.toObject(), (result: SwapSuccess) => {
Expand Down

0 comments on commit 1f9e82f

Please sign in to comment.