Skip to content

Commit

Permalink
feat(repeater): adopt self-deploying repeaters
Browse files Browse the repository at this point in the history
closes #201
  • Loading branch information
ostridm committed Jun 19, 2024
1 parent 02aa6e4 commit 79b26ce
Show file tree
Hide file tree
Showing 21 changed files with 65 additions and 264 deletions.
15 changes: 6 additions & 9 deletions packages/repeater/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,17 @@ You can customize some properties, e.g. name prefix or description, passing opti

```ts
const repeater = await repeaterFactory.createRepeater({
namePrefix: 'my-repeater',
description: 'My repeater'
namePrefix: 'my-repeater'
});
```

The `createRepeater` method accepts the options described below:

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

The default `requestRunnerOptions` is as follows:

Expand Down
79 changes: 0 additions & 79 deletions packages/repeater/src/api/DefaultRepeatersManager.spec.ts

This file was deleted.

40 changes: 0 additions & 40 deletions packages/repeater/src/api/DefaultRepeatersManager.ts

This file was deleted.

11 changes: 0 additions & 11 deletions packages/repeater/src/api/RepeatersManager.ts

This file was deleted.

24 changes: 0 additions & 24 deletions packages/repeater/src/api/commands/CreateRepeaterRequest.ts

This file was deleted.

12 changes: 0 additions & 12 deletions packages/repeater/src/api/commands/DeleteRepeaterRequest.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/repeater/src/api/commands/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/repeater/src/api/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/repeater/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import './register';
export { RepeatersManager } from './api';
export * from './lib';
export * from './models';
export * from './request-runner';
29 changes: 16 additions & 13 deletions packages/repeater/src/lib/DefaultRepeater.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { RunningStatus } from './Repeater';
import { DefaultRepeater } from './DefaultRepeater';
import { Protocol } from '../models/Protocol';
import { Request, Response } from '../request-runner';
import { RepeaterBridgesOptions } from './RepeaterBridgesOptions';
import {
RepeaterErrorCodes,
RepeaterServer,
Expand All @@ -23,10 +24,12 @@ import { EventEmitter } from 'events';

describe('DefaultRepeater', () => {
const RepeaterId = 'fooId';
const RepeaterNamePrefix = 'localhost';

let events!: EventEmitter;
let sut!: DefaultRepeater;

const mockedRepeaterBridgesOptions = mock<RepeaterBridgesOptions>();
const mockedRepeaterServer = mock<RepeaterServer>();
const repeaterCommands = mock<RepeaterCommands>();
const mockedLogger = mock<Logger>();
Expand All @@ -45,12 +48,14 @@ describe('DefaultRepeater', () => {
}
);

when(mockedRepeaterServer.deploy(anything())).thenResolve({
when(mockedRepeaterServer.deploy()).thenResolve({
repeaterId: RepeaterId
});

when(mockedRepeaterBridgesOptions.domain).thenReturn(RepeaterNamePrefix);

sut = new DefaultRepeater(
RepeaterId,
instance(mockedRepeaterBridgesOptions),
instance(mockedLogger),
instance(mockedRepeaterServer),
instance(repeaterCommands)
Expand All @@ -71,17 +76,15 @@ describe('DefaultRepeater', () => {
await sut.start();

// assert
verify(mockedRepeaterServer.connect()).once();
verify(
mockedRepeaterServer.deploy(
objectContaining({ repeaterId: RepeaterId })
)
).once();
verify(mockedRepeaterServer.connect(RepeaterNamePrefix)).once();
verify(mockedRepeaterServer.deploy()).once();
});

it('should throw when underlying connect throws', async () => {
// arrange
when(mockedRepeaterServer.connect()).thenReject(new Error('foo'));
when(mockedRepeaterServer.connect(RepeaterNamePrefix)).thenReject(
new Error('foo')
);

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

it('should throw when underlying deploy throws', async () => {
// arrange
when(mockedRepeaterServer.deploy(anything())).thenReject(
new Error('foo')
);
when(mockedRepeaterServer.deploy()).thenReject(new Error('foo'));

// act
const act = () => sut.start();
Expand Down Expand Up @@ -132,7 +133,9 @@ describe('DefaultRepeater', () => {

it('should be possible to start() after start() error', async () => {
// act
when(mockedRepeaterServer.connect()).thenReject().thenResolve();
when(mockedRepeaterServer.connect(RepeaterNamePrefix))
.thenReject()
.thenResolve();

// assert
await expect(sut.start()).rejects.toThrow();
Expand Down
21 changes: 14 additions & 7 deletions packages/repeater/src/lib/DefaultRepeater.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Repeater, RepeaterId, RunningStatus } from './Repeater';
import { Repeater, RunningStatus } from './Repeater';
import { RepeaterBridgesOptions } from './RepeaterBridgesOptions';
import {
RepeaterServer,
RepeaterErrorCodes,
Expand All @@ -18,15 +19,21 @@ import { inject, injectable, Lifecycle, scoped } from 'tsyringe';
@scoped(Lifecycle.ContainerScoped)
@injectable()
export class DefaultRepeater implements Repeater {
private _repeaterId = '';

private _runningStatus = RunningStatus.OFF;

get repeaterId(): string {
return this._repeaterId;
}

get runningStatus(): RunningStatus {
return this._runningStatus;
}

constructor(
@inject(RepeaterId)
public readonly repeaterId: RepeaterId,
@inject(RepeaterBridgesOptions)
private readonly repeaterBridgesOptions: RepeaterBridgesOptions,
private readonly logger: Logger,
@inject(RepeaterServer)
private readonly repeaterServer: RepeaterServer,
Expand Down Expand Up @@ -68,7 +75,7 @@ export class DefaultRepeater implements Repeater {

this.subscribeDiagnosticEvents();

await this.repeaterServer.connect();
await this.repeaterServer.connect(this.repeaterBridgesOptions.domain);

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

Expand All @@ -80,9 +87,9 @@ export class DefaultRepeater implements Repeater {
}

private async deploy() {
await this.repeaterServer.deploy({
repeaterId: this.repeaterId
});
const { repeaterId } = await this.repeaterServer.deploy();

this._repeaterId = repeaterId;
}

private subscribeRedeploymentEvent() {
Expand Down
5 changes: 2 additions & 3 deletions packages/repeater/src/lib/DefaultRepeaterServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import io, { Socket } from 'socket.io-client';
import parser from 'socket.io-msgpack-parser';
import { ErrorEvent } from 'ws';
import { EventEmitter, once } from 'events';
import { hostname } from 'os';
import Timer = NodeJS.Timer;

export interface DefaultRepeaterServerOptions {
Expand Down Expand Up @@ -134,14 +133,14 @@ export class DefaultRepeaterServer implements RepeaterServer {
return result;
}

public async connect(namePrefix: string = hostname()) {
public async connect(domain: string) {
this._socket = io(this.options.uri, {
parser,
path: '/api/ws/v1',
transports: ['websocket'],
reconnectionAttempts: this.MAX_RECONNECTION_ATTEMPTS,
auth: {
domain: namePrefix,
domain,
token: this.options.token
}
});
Expand Down
5 changes: 1 addition & 4 deletions packages/repeater/src/lib/Repeater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ export enum RunningStatus {
RUNNING
}

export type RepeaterId = string;
export const RepeaterId = Symbol('RepeaterId');

export interface Repeater {
readonly repeaterId: RepeaterId;
readonly repeaterId: string;
readonly runningStatus: RunningStatus;
start(): Promise<void>;
stop(): Promise<void>;
Expand Down
7 changes: 7 additions & 0 deletions packages/repeater/src/lib/RepeaterBridgesOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface RepeaterBridgesOptions {
domain: string;
}

export const RepeaterBridgesOptions: unique symbol = Symbol(
'RepeaterBridgesOptions'
);
Loading

0 comments on commit 79b26ce

Please sign in to comment.