From a2f863c56b08259dd397e9ec58e59c16f0e610fb Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 8 Feb 2019 16:32:38 +0200 Subject: [PATCH] Expose api.disconnect() (#664) * Expose api.disconnect() * Noop for non-WS disconnects --- packages/api/src/Base.ts | 7 +++++++ packages/rpc-core/src/index.ts | 7 +++++++ packages/rpc-provider/src/http/index.ts | 7 +++++++ packages/rpc-provider/src/mock/index.ts | 4 ++++ packages/rpc-provider/src/types.ts | 1 + packages/rpc-provider/src/ws/index.ts | 20 +++++++++++++++++++- 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/api/src/Base.ts b/packages/api/src/Base.ts index 4e58afdd67..1f41d9fdb5 100644 --- a/packages/api/src/Base.ts +++ b/packages/api/src/Base.ts @@ -226,6 +226,13 @@ export default abstract class ApiBase implement return this._extrinsics as SubmittableExtrinsics; } + /** + * @description Disconnect from the underlying provider, halting all comms + */ + disconnect (): void { + this._rpcBase.disconnect(); + } + /** * @description Attach an eventemitter handler to listen to a specific event * diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index f86b1d0a55..f33a6b3c99 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -84,6 +84,13 @@ export default class Rpc implements RpcInterface { return `${method} (${inputs}): ${type}`; } + /** + * @description Manually disconnect from the attached provider + */ + disconnect (): void { + this._provider.disconnect(); + } + private createInterface ({ methods }: RpcSection): RpcInterface$Section { return Object .keys(methods) diff --git a/packages/rpc-provider/src/http/index.ts b/packages/rpc-provider/src/http/index.ts index c1b3ce6e0a..8e9aa6d717 100644 --- a/packages/rpc-provider/src/http/index.ts +++ b/packages/rpc-provider/src/http/index.ts @@ -56,6 +56,13 @@ export default class HttpProvider implements ProviderInterface { return false; } + /** + * @description Manually disconnect from the connection + */ + disconnect (): void { + // noop + } + /** * @summary Whether the node is connected or not. * @return {boolean} true if connected diff --git a/packages/rpc-provider/src/mock/index.ts b/packages/rpc-provider/src/mock/index.ts index 95ea769846..bba4b80a92 100644 --- a/packages/rpc-provider/src/mock/index.ts +++ b/packages/rpc-provider/src/mock/index.ts @@ -75,6 +75,10 @@ export default class Mock implements ProviderInterface { return true; } + disconnect (): void { + // noop + } + isConnected (): boolean { return true; } diff --git a/packages/rpc-provider/src/types.ts b/packages/rpc-provider/src/types.ts index 070479c97e..79ce0a5926 100644 --- a/packages/rpc-provider/src/types.ts +++ b/packages/rpc-provider/src/types.ts @@ -43,6 +43,7 @@ export type ProviderInterface$EmitCb = (value?: any) => any; export interface ProviderInterface { readonly hasSubscriptions: boolean; + disconnect (): void; isConnected (): boolean; on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void; send (method: string, params: Array): Promise; diff --git a/packages/rpc-provider/src/ws/index.ts b/packages/rpc-provider/src/ws/index.ts index 21b982dda2..8012453c50 100644 --- a/packages/rpc-provider/src/ws/index.ts +++ b/packages/rpc-provider/src/ws/index.ts @@ -120,6 +120,22 @@ export default class WsProvider implements WSProviderInterface { } } + /** + * @description Manually disconnect from the connection, clearing autoconnect logic + */ + disconnect (): void { + if (isNull(this.websocket)) { + throw new Error('Cannot disconnect on a non-open websocket'); + } + + // switch off autoConnect, we are in manual mode now + this.autoConnect = false; + + // 1000 - Normal closure; the connection successfully completed + this.websocket.close(1000); + this.websocket = null; + } + /** * @summary Whether the node is connected or not. * @return {boolean} true if connected @@ -231,7 +247,9 @@ export default class WsProvider implements WSProviderInterface { } private onSocketClose = (event: CloseEvent): void => { - l.error(`disconnected from ${this.endpoint}::${event.code}: ${event.reason}`); + if (this.autoConnect) { + l.error(`disconnected from ${this.endpoint}::${event.code}: ${event.reason}`); + } this._isConnected = false; this.emit('disconnected');