Skip to content

Commit 37e9e3f

Browse files
committed
feat(repeater): adopt self-deploying repeaters
closes #201
1 parent 02aa6e4 commit 37e9e3f

22 files changed

+101
-264
lines changed

packages/repeater/README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,17 @@ You can customize some properties, e.g. name prefix or description, passing opti
4141

4242
```ts
4343
const repeater = await repeaterFactory.createRepeater({
44-
namePrefix: 'my-repeater',
45-
description: 'My repeater'
44+
namePrefix: 'my-repeater'
4645
});
4746
```
4847

4948
The `createRepeater` method accepts the options described below:
5049

51-
| Option | Description |
52-
| :---------------------------- | ----------------------------------------------------------------------------------------------------- |
53-
| `namePrefix` | Enter a name prefix that will be used as a constant part of the unique name. By default, `sectester`. |
54-
| `description` | Set a short description of the Repeater. |
55-
| `requestRunnerOptions` | Custom the request runner settings that will be used to execute requests to your application. |
56-
| `projectId` | Specify the project ID to associate the Repeater with. |
57-
| `disableRandomNameGeneration` | Disable random name generation for the Repeater's name. |
50+
| Option | Description |
51+
| :---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
52+
| `namePrefix` | Enter a name prefix that will be used as a constant part of the unique name. By default, the hostname value used. |
53+
| `disableRandomNameGeneration` | Disable random name generation for the Repeater's name. |
54+
| `requestRunnerOptions` | Custom the request runner settings that will be used to execute requests to your application. |
5855

5956
The default `requestRunnerOptions` is as follows:
6057

packages/repeater/src/api/DefaultRepeatersManager.spec.ts

Lines changed: 0 additions & 79 deletions
This file was deleted.

packages/repeater/src/api/DefaultRepeatersManager.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

packages/repeater/src/api/RepeatersManager.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/repeater/src/api/commands/CreateRepeaterRequest.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

packages/repeater/src/api/commands/DeleteRepeaterRequest.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

packages/repeater/src/api/commands/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/repeater/src/api/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/repeater/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import './register';
2-
export { RepeatersManager } from './api';
32
export * from './lib';
43
export * from './models';
54
export * from './request-runner';

packages/repeater/src/lib/DefaultRepeater.spec.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { RunningStatus } from './Repeater';
22
import { DefaultRepeater } from './DefaultRepeater';
33
import { Protocol } from '../models/Protocol';
44
import { Request, Response } from '../request-runner';
5+
import { RepeaterBridgesOptions } from './RepeaterBridgesOptions';
56
import {
67
RepeaterErrorCodes,
78
RepeaterServer,
@@ -23,10 +24,12 @@ import { EventEmitter } from 'events';
2324

2425
describe('DefaultRepeater', () => {
2526
const RepeaterId = 'fooId';
27+
const RepeaterNamePrefix = 'localhost';
2628

2729
let events!: EventEmitter;
2830
let sut!: DefaultRepeater;
2931

32+
const mockedRepeaterBridgesOptions = mock<RepeaterBridgesOptions>();
3033
const mockedRepeaterServer = mock<RepeaterServer>();
3134
const repeaterCommands = mock<RepeaterCommands>();
3235
const mockedLogger = mock<Logger>();
@@ -45,12 +48,14 @@ describe('DefaultRepeater', () => {
4548
}
4649
);
4750

48-
when(mockedRepeaterServer.deploy(anything())).thenResolve({
51+
when(mockedRepeaterServer.deploy()).thenResolve({
4952
repeaterId: RepeaterId
5053
});
5154

55+
when(mockedRepeaterBridgesOptions.domain).thenReturn(RepeaterNamePrefix);
56+
5257
sut = new DefaultRepeater(
53-
RepeaterId,
58+
instance(mockedRepeaterBridgesOptions),
5459
instance(mockedLogger),
5560
instance(mockedRepeaterServer),
5661
instance(repeaterCommands)
@@ -71,17 +76,15 @@ describe('DefaultRepeater', () => {
7176
await sut.start();
7277

7378
// assert
74-
verify(mockedRepeaterServer.connect()).once();
75-
verify(
76-
mockedRepeaterServer.deploy(
77-
objectContaining({ repeaterId: RepeaterId })
78-
)
79-
).once();
79+
verify(mockedRepeaterServer.connect(RepeaterNamePrefix)).once();
80+
verify(mockedRepeaterServer.deploy()).once();
8081
});
8182

8283
it('should throw when underlying connect throws', async () => {
8384
// arrange
84-
when(mockedRepeaterServer.connect()).thenReject(new Error('foo'));
85+
when(mockedRepeaterServer.connect(RepeaterNamePrefix)).thenReject(
86+
new Error('foo')
87+
);
8588

8689
// act
8790
const act = () => sut.start();
@@ -92,9 +95,7 @@ describe('DefaultRepeater', () => {
9295

9396
it('should throw when underlying deploy throws', async () => {
9497
// arrange
95-
when(mockedRepeaterServer.deploy(anything())).thenReject(
96-
new Error('foo')
97-
);
98+
when(mockedRepeaterServer.deploy()).thenReject(new Error('foo'));
9899

99100
// act
100101
const act = () => sut.start();
@@ -132,7 +133,9 @@ describe('DefaultRepeater', () => {
132133

133134
it('should be possible to start() after start() error', async () => {
134135
// act
135-
when(mockedRepeaterServer.connect()).thenReject().thenResolve();
136+
when(mockedRepeaterServer.connect(RepeaterNamePrefix))
137+
.thenReject()
138+
.thenResolve();
136139

137140
// assert
138141
await expect(sut.start()).rejects.toThrow();

packages/repeater/src/lib/DefaultRepeater.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Repeater, RepeaterId, RunningStatus } from './Repeater';
1+
import { Repeater, RunningStatus } from './Repeater';
2+
import { RepeaterBridgesOptions } from './RepeaterBridgesOptions';
23
import {
34
RepeaterServer,
45
RepeaterErrorCodes,
@@ -18,15 +19,21 @@ import { inject, injectable, Lifecycle, scoped } from 'tsyringe';
1819
@scoped(Lifecycle.ContainerScoped)
1920
@injectable()
2021
export class DefaultRepeater implements Repeater {
22+
private _repeaterId = '';
23+
2124
private _runningStatus = RunningStatus.OFF;
2225

26+
get repeaterId(): string {
27+
return this._repeaterId;
28+
}
29+
2330
get runningStatus(): RunningStatus {
2431
return this._runningStatus;
2532
}
2633

2734
constructor(
28-
@inject(RepeaterId)
29-
public readonly repeaterId: RepeaterId,
35+
@inject(RepeaterBridgesOptions)
36+
private readonly repeaterBridgesOptions: RepeaterBridgesOptions,
3037
private readonly logger: Logger,
3138
@inject(RepeaterServer)
3239
private readonly repeaterServer: RepeaterServer,
@@ -68,7 +75,7 @@ export class DefaultRepeater implements Repeater {
6875

6976
this.subscribeDiagnosticEvents();
7077

71-
await this.repeaterServer.connect();
78+
await this.repeaterServer.connect(this.repeaterBridgesOptions.domain);
7279

7380
this.logger.log('Deploying the repeater');
7481

@@ -80,9 +87,9 @@ export class DefaultRepeater implements Repeater {
8087
}
8188

8289
private async deploy() {
83-
await this.repeaterServer.deploy({
84-
repeaterId: this.repeaterId
85-
});
90+
const { repeaterId } = await this.repeaterServer.deploy();
91+
92+
this._repeaterId = repeaterId;
8693
}
8794

8895
private subscribeRedeploymentEvent() {

packages/repeater/src/lib/DefaultRepeaterServer.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import io, { Socket } from 'socket.io-client';
2222
import parser from 'socket.io-msgpack-parser';
2323
import { ErrorEvent } from 'ws';
2424
import { EventEmitter, once } from 'events';
25-
import { hostname } from 'os';
2625
import Timer = NodeJS.Timer;
2726

2827
export interface DefaultRepeaterServerOptions {
@@ -134,14 +133,14 @@ export class DefaultRepeaterServer implements RepeaterServer {
134133
return result;
135134
}
136135

137-
public async connect(namePrefix: string = hostname()) {
136+
public async connect(domain: string) {
138137
this._socket = io(this.options.uri, {
139138
parser,
140139
path: '/api/ws/v1',
141140
transports: ['websocket'],
142141
reconnectionAttempts: this.MAX_RECONNECTION_ATTEMPTS,
143142
auth: {
144-
domain: namePrefix,
143+
domain,
145144
token: this.options.token
146145
}
147146
});

packages/repeater/src/lib/Repeater.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ export enum RunningStatus {
44
RUNNING
55
}
66

7-
export type RepeaterId = string;
8-
export const RepeaterId = Symbol('RepeaterId');
9-
107
export interface Repeater {
11-
readonly repeaterId: RepeaterId;
8+
readonly repeaterId: string;
129
readonly runningStatus: RunningStatus;
1310
start(): Promise<void>;
1411
stop(): Promise<void>;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface RepeaterBridgesOptions {
2+
domain: string;
3+
}
4+
5+
export const RepeaterBridgesOptions: unique symbol = Symbol(
6+
'RepeaterBridgesOptions'
7+
);

0 commit comments

Comments
 (0)