Map sub-id on types, not methods (#135)

This commit is contained in:
Jaco Greeff
2018-08-15 17:07:17 +02:00
committed by GitHub
parent a46774e2e9
commit a5c64709a2
12 changed files with 57 additions and 44 deletions
+2 -2
View File
@@ -53,11 +53,11 @@ export default class HttpProvider implements ProviderInterface {
return this.coder.decodeResponse(result);
}
async subscribe (method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number> {
async subscribe (types: string, method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number> {
throw new Error('Subscriptions has not been implemented');
}
async unsubscribe (method: string, id: number): Promise<boolean> {
async unsubscribe (type: string, method: string, id: number): Promise<boolean> {
throw new Error('Subscriptions has not been implemented');
}
}
+4 -4
View File
@@ -23,9 +23,9 @@ export default function mockProvider (): ProviderInterface {
on(self, type, sub),
send: (method: string, params: Array<any>): Promise<any> =>
send(self, method, params),
subscribe: (method: string, ...params: Array<any>): Promise<number> =>
subscribe(self, method, params),
unsubscribe: (method: string, id: number): Promise<boolean> =>
unsubscribe(self, method, id)
subscribe: (type: string, method: string, ...params: Array<any>): Promise<number> =>
subscribe(self, type, method, params),
unsubscribe: (type: string, method: string, id: number): Promise<boolean> =>
unsubscribe(self, type, method, id)
};
}
@@ -13,13 +13,13 @@ describe('subscribe', () => {
});
it('fails on unknown methods', () => {
return subscribe(state, 'test_notFound').catch((error) => {
return subscribe(state, 'test', 'test_notFound').catch((error) => {
expect(error.message).toMatch(/Invalid method 'test_notFound'/);
});
});
it('returns a subscription id', () => {
return subscribe(state, 'chain_newHead', [() => void 0]).then((id) => {
return subscribe(state, 'chain_newHead', 'chain_newHead', [() => void 0]).then((id) => {
expect(id).toEqual(state.subscriptionId);
});
});
@@ -27,7 +27,7 @@ describe('subscribe', () => {
it('stores the mapping values', () => {
const cb = () => void 0;
return subscribe(state, 'chain_newHead', [cb]).then((id) => {
return subscribe(state, 'chain_newHead', 'chain_newHead', [cb]).then((id) => {
expect(state.subscriptionMap[id]).toEqual('chain_newHead');
expect(state.subscriptions['chain_newHead'].callbacks[id]).toEqual(cb);
});
@@ -36,7 +36,7 @@ describe('subscribe', () => {
it('calls back with the last known value', (done) => {
state.subscriptions['chain_newHead'].lastValue = 'testValue';
subscribe(state, 'chain_newHead', [(_, value) => {
subscribe(state, 'chain_newHead', 'chain_newHead', [(_, value) => {
expect(value).toEqual('testValue');
done();
}]);
+1 -1
View File
@@ -4,7 +4,7 @@
import { MockState, MockState$Subscription$Callback } from './types';
export default async function subscribe (self: MockState, method: string, params: Array<any>): Promise<number> {
export default async function subscribe (self: MockState, type: string, method: string, params: Array<any>): Promise<number> {
self.l.debug(() => ['subscribe', method, params]);
if (self.subscriptions[method]) {
@@ -13,23 +13,23 @@ describe('unsubscribe', () => {
beforeEach(() => {
state = createState();
return subscribe(state, 'chain_newHead', [() => void 0]).then((_id) => {
return subscribe(state, 'chain_newHead', 'chain_newHead', [() => void 0]).then((_id) => {
id = _id;
});
});
it('fails on unknown ids', () => {
return unsubscribe(state, 'chain_newHead', 5).catch((error) => {
return unsubscribe(state, 'chain_newHead', 'chain_newHead', 5).catch((error) => {
expect(error.message).toMatch(/Unable to find/);
});
});
it('unsubscribes successfully', () => {
return unsubscribe(state, 'chain_newHead', id);
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id);
});
it('fails on double unsubscribe', () => {
return unsubscribe(state, 'chain_newHead', id)
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id)
.then(() => unsubscribe(state, id))
.catch((error) => {
expect(error.message).toMatch(/Unable to find/);
@@ -37,7 +37,7 @@ describe('unsubscribe', () => {
});
it('clears the subscriptions', () => {
return unsubscribe(state, 'chain_newHead', id).then(() => {
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id).then(() => {
expect(state.subscriptionMap[id]).not.toBeDefined();
expect(state.subscriptions['chain_newHead'].callbacks[id]).not.toBeDefined();
});
@@ -4,7 +4,7 @@
import { MockState } from './types';
export default async function unsubscribe (self: MockState, _: string, id: number): Promise<boolean> {
export default async function unsubscribe (self: MockState, type: string, name: string, id: number): Promise<boolean> {
const method = self.subscriptionMap[id];
self.l.debug(() => ['unsubscribe', id, method]);
+2 -2
View File
@@ -45,6 +45,6 @@ export interface ProviderInterface {
isConnected (): boolean,
on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void,
send (method: string, params: Array<any>): Promise<any>,
subscribe (method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number>,
unsubscribe (method: string, id: number): Promise<boolean>
subscribe (type: string, method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number>,
unsubscribe (type: string, method: string, id: number): Promise<boolean>
}
+18 -12
View File
@@ -16,15 +16,19 @@ import logger from '@polkadot/util/logger';
import coder from '../coder/json';
type SubscriptionHandler = {
callback: ProviderInterface$Callback,
type: string
};
type WsState$Awaiting = {
callback: ProviderInterface$Callback,
method: string,
params: Array<any>,
subscription?: ProviderInterface$Callback
subscription?: SubscriptionHandler
};
type WsState$Subscription = {
callback: ProviderInterface$Callback,
type WsState$Subscription = SubscriptionHandler & {
method: string,
params: Array<any>
};
@@ -91,7 +95,7 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
return super.on(type, sub);
}
async send (method: string, params: Array<any>, subscription?: ProviderInterface$Callback): Promise<any> {
async send (method: string, params: Array<any>, subscription?: SubscriptionHandler): Promise<any> {
return new Promise((resolve, reject): void => {
try {
const json = this.coder.encodeJson(method, params);
@@ -124,16 +128,18 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
});
}
async subscribe (method: string, params: Array<any>, subscription: ProviderInterface$Callback): Promise<number> {
const id = await this.send(method, params, subscription);
async subscribe (type: string, method: string, params: Array<any>, callback: ProviderInterface$Callback): Promise<number> {
const id = await this.send(method, params, { callback, type });
return id as number;
}
async unsubscribe (method: string, id: number): Promise<boolean> {
assert(!isUndefined(this.subscriptions[`${method}::${id}`]), `Unable to find active subscription=${id}`);
async unsubscribe (type: string, method: string, id: number): Promise<boolean> {
const subscription = `${type}::${id}`;
delete this.subscriptions[id];
assert(!isUndefined(this.subscriptions[subscription]), `Unable to find active subscription=${subscription}`);
delete this.subscriptions[subscription];
const result = await this.send(method, [id]);
@@ -178,12 +184,12 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
}
try {
const { method, params, subscription } = this.handlers[response.id];
const { method, params, subscription } = handler;
const result = this.coder.decodeResponse(response);
if (subscription) {
this.subscriptions[`${method}::${result}`] = {
callback: subscription,
this.subscriptions[`${subscription.type}::${result}`] = {
...subscription,
method,
params
};
@@ -29,9 +29,12 @@ describe('onMessageSubscribe', () => {
ws.handlers[11] = {
callback: (_, id) => {},
method: 'test',
subscription: (_, result) => {
expect(result).toEqual('test');
done();
subscription: {
callback: (_, result) => {
expect(result).toEqual('test');
done();
},
type: 'test'
}
};
@@ -43,9 +46,12 @@ describe('onMessageSubscribe', () => {
ws.handlers[11] = {
callback: (_, id) => {},
method: 'test',
subscription: (error) => {
expect(error.message).toMatch(/test/);
done();
subscription: {
callback: (error) => {
expect(error.message).toMatch(/test/);
done();
},
type: 'test'
}
};
@@ -56,9 +56,9 @@ describe('subscribe', () => {
const ws = createWs();
return ws
.subscribe('subscribe_test', [], () => {})
.subscribe('test', 'subscribe_test', [], () => {})
.then((id) => {
return ws.unsubscribe('subscribe_test', id);
return ws.unsubscribe('test', 'subscribe_test', id);
});
});
@@ -74,9 +74,9 @@ describe('subscribe', () => {
const ws = createWs();
return ws
.subscribe('subscribe_test', [], () => {})
.subscribe('test', 'subscribe_test', [], () => {})
.then((id) => {
return ws.unsubscribe('subscribe_test', 111);
return ws.unsubscribe('test', 'subscribe_test', 111);
})
.catch((error) => {
expect(error.message).toMatch(/find active subscription/);
+2 -1
View File
@@ -21,7 +21,7 @@ describe('formatResult', () => {
send: jest.fn((method, params) =>
Promise.resolve('0x0102')
),
subscribe: jest.fn((method, params, subscription) =>
subscribe: jest.fn((type, method, params, subscription) =>
subscription(null, {
block: '0x1234',
changes: [
@@ -61,6 +61,7 @@ describe('formatResult', () => {
expect(
provider.subscribe
).toHaveBeenCalledWith(
'state_storage',
'state_subscribeStorage',
[[ENC_ONE, ENC_TWO]],
expect.anything()
+2 -2
View File
@@ -17,7 +17,7 @@ import formatResult from './formatResult';
export default function methodSubscribe (provider: ProviderInterface, rpcName: string, method: SectionItem<Interfaces>): ApiInterface$Section$Method {
const unsubscribe = (subscriptionId: any): Promise<any> =>
provider.send(method.subscribe[1], [subscriptionId]);
provider.unsubscribe(rpcName, method.subscribe[1], subscriptionId);
const _call = async (...values: Array<any>): Promise<any> => {
try {
const cb: ProviderInterface$Callback = values.pop();
@@ -29,7 +29,7 @@ export default function methodSubscribe (provider: ProviderInterface, rpcName: s
cb(error, formatResult(method, params, values, result));
};
return provider.subscribe(method.subscribe[0], params, update);
return provider.subscribe(rpcName, method.subscribe[0], params, update);
} catch (error) {
throw new ExtError(`${signature(method)}:: ${error.message}`, (error as ExtError).code, undefined);
}