Skip to content

Commit 7d88ed6

Browse files
committed
Updates.
1 parent 0cc04fe commit 7d88ed6

File tree

3 files changed

+47
-39
lines changed

3 files changed

+47
-39
lines changed

src/cache.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
CONNECT,
55
DELETE,
66
ERROR,
7+
ErrorCallback,
78
Informer,
89
ListPromise,
910
ObjectCallback,
@@ -21,7 +22,7 @@ export class ListWatch<T extends KubernetesObject> implements ObjectCache<T>, In
2122
private objects: T[] = [];
2223
private resourceVersion: string;
2324
private readonly indexCache: { [key: string]: T[] } = {};
24-
private readonly callbackCache: { [key: string]: Array<ObjectCallback<T>> } = {};
25+
private readonly callbackCache: { [key: string]: Array<ObjectCallback<T> | ErrorCallback> } = {};
2526
private request: RequestResult | undefined;
2627
private stopped: boolean = false;
2728

@@ -52,11 +53,13 @@ export class ListWatch<T extends KubernetesObject> implements ObjectCache<T>, In
5253
this._stop();
5354
}
5455

55-
public on(verb: string, cb: ObjectCallback<T>): void {
56+
public on(verb: 'add' | 'update' | 'delete' | 'change', cb: ObjectCallback<T>): void;
57+
public on(verb: 'error' | 'connect', cb: ErrorCallback): void;
58+
public on(verb: string, cb: any): void {
5659
if (verb === CHANGE) {
57-
this.on(ADD, cb);
58-
this.on(UPDATE, cb);
59-
this.on(DELETE, cb);
60+
this.on('add', cb);
61+
this.on('update', cb);
62+
this.on('delete', cb);
6063
return;
6164
}
6265
if (this.callbackCache[verb] === undefined) {
@@ -65,11 +68,13 @@ export class ListWatch<T extends KubernetesObject> implements ObjectCache<T>, In
6568
this.callbackCache[verb].push(cb);
6669
}
6770

68-
public off(verb: string, cb: ObjectCallback<T>): void {
71+
public off(verb: 'add' | 'update' | 'delete' | 'change', cb: ObjectCallback<T>): void;
72+
public off(verb: 'error' | 'connect', cb: ErrorCallback): void;
73+
public off(verb: string, cb: any): void {
6974
if (verb === CHANGE) {
70-
this.off(ADD, cb);
71-
this.off(UPDATE, cb);
72-
this.off(DELETE, cb);
75+
this.off('add', cb);
76+
this.off('update', cb);
77+
this.off('delete', cb);
7378
return;
7479
}
7580
if (this.callbackCache[verb] === undefined) {
@@ -113,14 +118,14 @@ export class ListWatch<T extends KubernetesObject> implements ObjectCache<T>, In
113118
private async doneHandler(err: any): Promise<any> {
114119
this._stop();
115120
if (err) {
116-
this.callbackCache[ERROR].forEach((elt: ObjectCallback<T>) => elt(undefined, err));
121+
this.callbackCache[ERROR].forEach((elt: ErrorCallback) => elt(err));
117122
return;
118123
}
119124
if (this.stopped) {
120125
// do not auto-restart
121126
return;
122127
}
123-
this.callbackCache[CONNECT].forEach((elt: ObjectCallback<T>) => elt());
128+
this.callbackCache[CONNECT].forEach((elt: ErrorCallback) => elt(undefined));
124129
// TODO: Don't always list here for efficiency
125130
// try to restart the watch from resourceVersion, but detect 410 GONE and relist in that case.
126131
// Or if resourceVersion is empty.

src/cache_test.ts

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { EventEmitter } from 'ws';
99

1010
import { V1Namespace, V1NamespaceList, V1ObjectMeta, V1Pod, V1ListMeta } from './api';
1111
import { deleteObject, ListWatch, deleteItems } from './cache';
12-
import { ADD, UPDATE, DELETE, ERROR, ListPromise, CHANGE, CONNECT } from './informer';
12+
import { ListPromise } from './informer';
1313

1414
use(chaiAsPromised);
1515

@@ -44,7 +44,9 @@ describe('ListWatchCache', () => {
4444
};
4545
const lw = new ListWatch('/some/path', fake, listFn);
4646
const verb = 'FOOBAR';
47-
expect(() => lw.on(verb, (obj?: V1Namespace) => {})).to.throw(`Unknown verb: ${verb}`);
47+
// The 'as any' is a hack to get around Typescript which prevents an unknown verb from being
48+
// passed. We want to test for Javascript clients also, where this is possible
49+
expect(() => (lw as any).on(verb, (obj?: V1Namespace) => {})).to.throw(`Unknown verb: ${verb}`);
4850
});
4951

5052
it('should perform basic caching', async () => {
@@ -216,19 +218,19 @@ describe('ListWatchCache', () => {
216218
expect(pathOut).to.equal('/some/path');
217219

218220
const addPromise = new Promise<V1Namespace>((resolve: (V1Namespace) => void) => {
219-
informer.on(ADD, (obj?: V1Namespace) => {
221+
informer.on('add', (obj?: V1Namespace) => {
220222
resolve(obj);
221223
});
222224
});
223225

224226
const updatePromise = new Promise<V1Namespace>((resolve: (V1Namespace) => void) => {
225-
informer.on(UPDATE, (obj?: V1Namespace) => {
227+
informer.on('update', (obj?: V1Namespace) => {
226228
resolve(obj);
227229
});
228230
});
229231

230232
const deletePromise = new Promise<V1Namespace>((resolve: (V1Namespace) => void) => {
231-
informer.on(DELETE, (obj?: V1Namespace) => {
233+
informer.on('delete', (obj?: V1Namespace) => {
232234
resolve(obj);
233235
});
234236
});
@@ -310,7 +312,7 @@ describe('ListWatchCache', () => {
310312

311313
let count = 0;
312314
const changePromise = new Promise<boolean>((resolve: (V1Namespace) => void) => {
313-
informer.on(CHANGE, (obj?: V1Namespace) => {
315+
informer.on('change', (obj?: V1Namespace) => {
314316
count++;
315317
if (count == 3) {
316318
resolve(true);
@@ -372,13 +374,13 @@ describe('ListWatchCache', () => {
372374
expect(pathOut).to.equal('/some/path');
373375

374376
const addPromise = new Promise<V1Namespace>((resolve: (V1Namespace) => void) => {
375-
informer.on(ADD, (obj?: V1Namespace) => {
377+
informer.on('add', (obj?: V1Namespace) => {
376378
resolve(obj);
377379
});
378380
});
379381

380382
const addPromise2 = new Promise<V1Namespace>((resolve: (V1Namespace) => void) => {
381-
informer.on(ADD, (obj?: V1Namespace) => {
383+
informer.on('add', (obj?: V1Namespace) => {
382384
resolve(obj);
383385
});
384386
});
@@ -442,9 +444,9 @@ describe('ListWatchCache', () => {
442444
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn, false);
443445

444446
const addObjects: V1Namespace[] = [];
445-
informer.on(ADD, (obj?: V1Namespace) => addObjects.push(obj!));
447+
informer.on('add', (obj?: V1Namespace) => addObjects.push(obj!));
446448
const updateObjects: V1Namespace[] = [];
447-
informer.on(UPDATE, (obj?: V1Namespace) => updateObjects.push(obj!));
449+
informer.on('update', (obj?: V1Namespace) => updateObjects.push(obj!));
448450

449451
informer.start();
450452
await promise;
@@ -518,11 +520,11 @@ describe('ListWatchCache', () => {
518520
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn, false);
519521

520522
const addObjects: V1Namespace[] = [];
521-
informer.on(ADD, (obj?: V1Namespace) => addObjects.push(obj!));
523+
informer.on('add', (obj?: V1Namespace) => addObjects.push(obj!));
522524
const updateObjects: V1Namespace[] = [];
523-
informer.on(UPDATE, (obj?: V1Namespace) => updateObjects.push(obj!));
525+
informer.on('update', (obj?: V1Namespace) => updateObjects.push(obj!));
524526
const deleteObjects: V1Namespace[] = [];
525-
informer.on(DELETE, (obj?: V1Namespace) => deleteObjects.push(obj!));
527+
informer.on('delete', (obj?: V1Namespace) => deleteObjects.push(obj!));
526528
informer.start();
527529
await promise;
528530
const [pathOut, , , doneHandler] = mock.capture(fakeWatch.watch).last();
@@ -729,16 +731,16 @@ describe('ListWatchCache', () => {
729731
await watchCalled;
730732
const [, , watchHandler] = mock.capture(fakeWatch.watch).last();
731733

732-
informer.on(ADD, addToList1Fn);
733-
informer.on(ADD, addToList2Fn);
734+
informer.on('add', addToList1Fn);
735+
informer.on('add', addToList2Fn);
734736

735737
watchHandler('ADDED', {
736738
metadata: {
737739
name: 'name1',
738740
} as V1ObjectMeta,
739741
} as V1Namespace);
740742

741-
informer.off(ADD, addToList2Fn);
743+
informer.off('add', addToList2Fn);
742744

743745
watchHandler('ADDED', {
744746
metadata: {
@@ -779,16 +781,16 @@ describe('ListWatchCache', () => {
779781
addedList.push(obj!);
780782
};
781783
const removeSelf = function() {
782-
informer.off(ADD, removeSelf);
784+
informer.off('add', removeSelf);
783785
};
784786

785787
informer.start();
786788

787789
await watchCalled;
788790
const [, , watchHandler] = mock.capture(fakeWatch.watch).last();
789791

790-
informer.on(ADD, removeSelf);
791-
informer.on(ADD, addToListFn);
792+
informer.on('add', removeSelf);
793+
informer.on('add', addToListFn);
792794

793795
watchHandler('ADDED', {
794796
metadata: {
@@ -877,9 +879,9 @@ describe('ListWatchCache', () => {
877879
const [, , watchHandler] = mock.capture(fakeWatch.watch).last();
878880

879881
let adds = 0;
880-
informer.on(ADD, () => adds++);
881-
informer.on(ADD, addToList1Fn);
882-
informer.on(ADD, addToList2Fn);
882+
informer.on('add', () => adds++);
883+
informer.on('add', addToList1Fn);
884+
informer.on('add', addToList2Fn);
883885

884886
watchHandler('ADDED', {
885887
metadata: {
@@ -888,7 +890,7 @@ describe('ListWatchCache', () => {
888890
} as V1ObjectMeta,
889891
} as V1Namespace);
890892

891-
informer.off(ADD, addToList2Fn);
893+
informer.off('add', addToList2Fn);
892894

893895
watchHandler('ADDED', {
894896
metadata: {
@@ -1010,7 +1012,7 @@ describe('ListWatchCache', () => {
10101012
await promise;
10111013

10121014
let errorEmitted = false;
1013-
cache.on(ERROR, () => (errorEmitted = true));
1015+
cache.on('error', () => (errorEmitted = true));
10141016

10151017
const [, , , doneHandler] = mock.capture(fakeWatch.watch).last();
10161018

@@ -1131,7 +1133,7 @@ describe('delete items', () => {
11311133
};
11321134
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn, false);
11331135
const connectPromise = new Promise<boolean>((resolve: (boolean) => void) => {
1134-
informer.on(CONNECT, (obj?: V1Namespace) => {
1136+
informer.on('connect', (obj?: V1Namespace) => {
11351137
resolve(true);
11361138
});
11371139
});
@@ -1185,7 +1187,7 @@ describe('delete items', () => {
11851187
await promise;
11861188

11871189
let errorEmitted = false;
1188-
cache.on(ERROR, () => (errorEmitted = true));
1190+
cache.on('error', () => (errorEmitted = true));
11891191

11901192
const [, , , doneHandler] = mock.capture(fakeWatch.watch).last();
11911193

@@ -1198,7 +1200,7 @@ describe('delete items', () => {
11981200
expect(errorEmitted).to.equal(true);
11991201

12001202
const connectPromise = new Promise<boolean>((resolve: (boolean) => void) => {
1201-
cache.on(CONNECT, (obj?: V1Namespace) => {
1203+
cache.on('connect', (obj?: V1Namespace) => {
12021204
resolve(true);
12031205
});
12041206
});

src/informer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { Watch } from './watch';
55

66
import http = require('http');
77

8-
export type ObjectCallback<T extends KubernetesObject> = (obj?: T, err?: any) => void;
8+
export type ObjectCallback<T extends KubernetesObject> = (obj: T) => void;
9+
export type ErrorCallback = (err?: any) => void;
910
export type ListCallback<T extends KubernetesObject> = (list: T[], ResourceVersion: string) => void;
1011
export type ListPromise<T extends KubernetesObject> = () => Promise<{
1112
response: http.IncomingMessage;

0 commit comments

Comments
 (0)