Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mos-connection

Package Overview
Dependencies
Maintainers
1
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mos-connection - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

21

CHANGELOG.md

@@ -5,2 +5,23 @@ # Change Log

<a name="0.5.0"></a>
# [0.5.0](https://github.com/nrkno/tv-automation-mos-connection/compare/0.4.0...0.5.0) (2018-08-17)
### Bug Fixes
* 0 reconnects implies infinite reconnects ([7749dc3](https://github.com/nrkno/tv-automation-mos-connection/commit/7749dc3))
* extra guards in switching logic ([a66584e](https://github.com/nrkno/tv-automation-mos-connection/commit/a66584e))
* reconnect timer reset ([970da0d](https://github.com/nrkno/tv-automation-mos-connection/commit/970da0d))
* roAck may contain error regarding buddy server ([4ef32ff](https://github.com/nrkno/tv-automation-mos-connection/commit/4ef32ff))
* timeout messages even before being sent ([39ba705](https://github.com/nrkno/tv-automation-mos-connection/commit/39ba705))
### Features
* failover prototype ([2f979e6](https://github.com/nrkno/tv-automation-mos-connection/commit/2f979e6))
* failover upon NACK: Main Available ([5bb64e4](https://github.com/nrkno/tv-automation-mos-connection/commit/5bb64e4))
* option to enable offspec failover behaviour ([86f7b0d](https://github.com/nrkno/tv-automation-mos-connection/commit/86f7b0d))
<a name="0.4.0"></a>

@@ -7,0 +28,0 @@ # [0.4.0](https://github.com/nrkno/tv-automation-mos-connection/compare/0.3.17...0.4.0) (2018-08-03)

2

dist/config/connectionConfig.d.ts

@@ -9,2 +9,3 @@ /** */

openRelay?: boolean;
offspecFailover?: boolean;
}

@@ -29,2 +30,3 @@ /** */

openRelay?: boolean;
offspecFailover?: boolean;
private _profiles;

@@ -31,0 +33,0 @@ constructor(init: IConnectionConfig);

10

dist/connection/mosSocketClient.d.ts
/// <reference types="node" />
import { EventEmitter } from 'events';
import { MosMessage } from '../mosModel/MosMessage';
import { HandedOverQueue } from './NCSServerConnection';
export declare type CallBackFunction = (err: any, data: object) => void;
export interface QueueMessage {
time: number;
msg: MosMessage;
}
export declare class MosSocketClient extends EventEmitter {

@@ -39,4 +44,5 @@ private _host;

disconnect(): void;
queueCommand(message: MosMessage, cb: CallBackFunction): void;
queueCommand(message: MosMessage, cb: CallBackFunction, time?: number): void;
processQueue(): void;
handOverQueue(): HandedOverQueue;
/** */

@@ -57,3 +63,3 @@ readonly host: string;

/** */
private executeCommand(message);
private executeCommand(message, isRetry?);
/** */

@@ -60,0 +66,0 @@ private _autoReconnectionAttempt();

@@ -86,7 +86,7 @@ "use strict";

}
queueCommand(message, cb) {
queueCommand(message, cb, time) {
message.prepare();
// console.log('queueing', message.messageID, message.constructor.name )
this._queueCallback[message.messageID + ''] = cb;
this._queueMessages.push({ time: Date.now(), msg: message });
this._queueMessages.push({ time: time || Date.now(), msg: message });
this.processQueue();

@@ -109,9 +109,30 @@ }

else {
// Try again later:
clearTimeout(this.processQueueTimeout);
this.processQueueTimeout = setTimeout(() => {
this.processQueue();
}, 200);
if (!this._sentMessage && this._queueMessages.length > 0) {
if (Date.now() - this._queueMessages[0].time > this._commandTimeout) {
const msg = this._queueMessages.shift();
this._queueCallback[msg.msg.messageID]('Command timed out', {});
delete this._queueCallback[msg.msg.messageID];
this.processQueue();
}
else {
// Try again later:
clearTimeout(this.processQueueTimeout);
this.processQueueTimeout = setTimeout(() => {
this.processQueue();
}, 200);
}
}
}
}
handOverQueue() {
const queue = {
messages: this._queueMessages,
callbacks: this._queueCallback
};
this._queueMessages = [];
this._queueCallback = {};
this._sentMessage = null;
clearTimeout(this.processQueueTimeout);
return queue;
}
/** */

@@ -172,3 +193,3 @@ get host() {

/** */
executeCommand(message) {
executeCommand(message, isRetry) {
if (this._sentMessage)

@@ -190,4 +211,10 @@ throw Error('executeCommand: there already is a sent Command!');

console.log('timeout ' + sentMessageId);
this._sendReply(sentMessageId, Error('Command timed out'), null);
this.processQueue();
if (isRetry) {
this._sendReply(sentMessageId, Error('Command timed out'), null);
this.processQueue();
}
else {
this._sentMessage = null;
this.executeCommand(message, true);
}
}

@@ -203,4 +230,4 @@ }, this._commandTimeout);

if (this._autoReconnect) {
if (this._reconnectAttempts > 0) { // no reconnection if no valid reconnectionAttemps is set
if ((this._reconnectAttempt >= this._reconnectAttempts)) { // if current attempt is not less than max attempts
if (this._reconnectAttempts > -1) { // no reconnection if no valid reconnectionAttemps is set
if (this._reconnectAttempts > 0 && (this._reconnectAttempt >= this._reconnectAttempts)) { // if current attempt is not less than max attempts
// reset reconnection behaviour

@@ -234,4 +261,4 @@ this._clearConnectionAttemptTimer();

this._client.emit(socketConnection_1.SocketConnectionEvent.ALIVE);
global.clearInterval(this._connectionAttemptTimer);
// this._clearConnectionAttemptTimer()
// global.clearInterval(this._connectionAttemptTimer)
this._clearConnectionAttemptTimer();
this.connected = true;

@@ -307,5 +334,10 @@ }

if (parsedData.mos.mosAck && parsedData.mos.mosAck.status === 'NACK') {
if (this._debug)
console.log('Mos Error message:' + parsedData.mos.mosAck.statusDescription);
this.emit('error', 'Error message: ' + parsedData.mos.mosAck.statusDescription);
if (this._sentMessage && parsedData.mos.mosAck.statusDescription === 'Buddy server cannot respond because main server is available') {
this._sendReply(this._sentMessage.msg.messageID, 'Main server available', parsedData);
}
else {
if (this._debug)
console.log('Mos Error message:' + parsedData.mos.mosAck.statusDescription);
this.emit('error', 'Error message: ' + parsedData.mos.mosAck.statusDescription);
}
}

@@ -312,0 +344,0 @@ else {

/// <reference types="node" />
import { ConnectionType } from './socketConnection';
import { MosSocketClient } from '../connection/mosSocketClient';
import { MosSocketClient, CallBackFunction, QueueMessage } from '../connection/mosSocketClient';
import { MosMessage } from '../mosModel/MosMessage';

@@ -14,2 +14,8 @@ import { EventEmitter } from 'events';

}
export interface HandedOverQueue {
messages: QueueMessage[];
callbacks: {
[messageId: string]: CallBackFunction;
};
}
/** */

@@ -44,4 +50,8 @@ export declare class NCSServerConnection extends EventEmitter implements INCSServerConnection {

readonly id: string;
handOverQueue(otherConnection: NCSServerConnection): void;
receiveQueue(queue: {
[clientId: string]: HandedOverQueue;
}): void;
dispose(): Promise<void>;
private _sendHeartBeats();
}

@@ -141,2 +141,31 @@ "use strict";

}
handOverQueue(otherConnection) {
const cmds = {};
// this._clients.forEach((client, id) => {
// // cmds[id] = client.client.handOverQueue()
// })
for (const id in this._clients) {
cmds[id] = this._clients[id].client.handOverQueue();
}
otherConnection.receiveQueue(cmds);
}
receiveQueue(queue) {
// @todo: keep order
// @todo: prevent callback-promise horror...
for (const clientId of Object.keys(queue)) {
for (const msg of queue[clientId].messages) {
this.executeCommand(msg.msg).then((data) => {
const cb = queue[clientId].callbacks[msg.msg.messageID];
if (cb) {
cb(null, data);
}
}, (err) => {
const cb = queue[clientId].callbacks[msg.msg.messageID];
if (cb) {
cb(null, err);
}
});
}
}
}
dispose() {

@@ -143,0 +172,0 @@ this._disposed = true;

@@ -188,3 +188,3 @@ "use strict";

let id1 = (theirMosId1 ? myMosID + '_' + theirMosId1 : null);
let mosDevice = new MosDevice_1.MosDevice(id0, id1, this._conf, primary, secondary);
let mosDevice = new MosDevice_1.MosDevice(id0, id1, this._conf, primary, secondary, this._conf.offspecFailover);
// Add mosDevice to register:

@@ -191,0 +191,0 @@ if (this._mosDevices[id0]) {

@@ -55,3 +55,3 @@ /// <reference types="node" />

private _callbackOnROStory?;
constructor(idPrimary: string, idSecondary: string | null, connectionConfig: IConnectionConfig, primaryConnection: NCSServerConnection | null, secondaryConnection: NCSServerConnection | null);
constructor(idPrimary: string, idSecondary: string | null, connectionConfig: IConnectionConfig, primaryConnection: NCSServerConnection | null, secondaryConnection: NCSServerConnection | null, offSpecFailover?: boolean);
readonly hasConnection: boolean;

@@ -101,2 +101,4 @@ readonly idPrimary: string;

onROStory(cb: (story: IMOSROFullStory) => Promise<IMOSROAck>): void;
private executeCommand(message, resend?);
private switchConnections(message?);
}

@@ -23,3 +23,3 @@ "use strict";

class MosDevice {
constructor(idPrimary, idSecondary, connectionConfig, primaryConnection, secondaryConnection) {
constructor(idPrimary, idSecondary, connectionConfig, primaryConnection, secondaryConnection, offSpecFailover) {
this._debug = false;

@@ -78,3 +78,8 @@ this.supportedProfiles = {

this._primaryConnection = primaryConnection;
this._primaryConnection.onConnectionChange(() => this.emitConnectionChange());
this._primaryConnection.onConnectionChange(() => {
this.emitConnectionChange();
if (offSpecFailover && this._currentConnection !== this._primaryConnection && this._primaryConnection.connected) {
this.switchConnections().catch(() => null); // and hope no current message goes lost
}
});
}

@@ -509,3 +514,3 @@ if (secondaryConnection) {

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
let listMachInfo = data.mos.listMachInfo;

@@ -530,5 +535,2 @@ let list = {

}
else {
reject('No Connection');
}
});

@@ -562,3 +564,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
if (data.mos.roAck) {

@@ -576,5 +578,2 @@ reject(Parser_1.Parser.xml2ROAck(data.mos.roAck));

}
else {
reject('No Connection');
}
});

@@ -586,3 +585,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
if (data.mos.roAck) {

@@ -600,5 +599,2 @@ reject(Parser_1.Parser.xml2ROAck(data.mos.roAck));

}
else {
reject('No Connection');
}
});

@@ -624,3 +620,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
if (data.mos.roAck) {

@@ -639,5 +635,2 @@ reject(Parser_1.Parser.xml2ROAck(data.mos.roAck));

}
else {
reject('No Connection');
}
});

@@ -665,3 +658,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
let roAck = Parser_1.Parser.xml2ROAck(data.mos.roAck);

@@ -671,5 +664,2 @@ resolve(roAck);

}
else {
reject('No Connection');
}
});

@@ -686,3 +676,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
let roAck = Parser_1.Parser.xml2ROAck(data.mos.roAck);

@@ -692,5 +682,2 @@ resolve(roAck);

}
else {
reject('No Connection');
}
});

@@ -710,3 +697,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
let roAck = Parser_1.Parser.xml2ROAck(data.mos.roAck);

@@ -716,5 +703,2 @@ resolve(roAck);

}
else {
reject('No Connection');
}
});

@@ -760,3 +744,3 @@ }

if (this._currentConnection) {
this._currentConnection.executeCommand(message).then((data) => {
this.executeCommand(message).then((data) => {
if (data.mos.hasOwnProperty('roListAll')) {

@@ -780,5 +764,2 @@ let xmlRos = (data.mos.roListAll || {}).ro;

}
else {
reject('No Connection');
}
});

@@ -789,4 +770,55 @@ }

}
executeCommand(message, resend) {
if (this._currentConnection) {
console.log('exec command', message);
if (!this._currentConnection.connected) {
return this.switchConnections(message);
}
return this._currentConnection.executeCommand(message).then((res) => {
if (res.mos.roAck && res.mos.roAck.roStatus === 'Buddy server cannot respond because main server is available') {
return Promise.reject('Buddy server cannot respond because main server is available');
}
return res;
}).catch((e) => {
console.log('errored', e);
if (this._primaryConnection && this._secondaryConnection && !resend) {
return this.switchConnections(message);
}
else {
return Promise.reject(e);
}
});
}
else {
return Promise.reject('No connection');
}
}
switchConnections(message) {
if (this._currentConnection && this._primaryConnection && this._secondaryConnection) {
console.log('swithcing conn');
this._currentConnection = this._currentConnection === this._primaryConnection ? this._secondaryConnection : this._primaryConnection;
if (!this._currentConnection.connected)
return Promise.reject('No connection available for failover');
let p;
if (message) {
console.log('resending msg');
p = this.executeCommand(message, true).catch((e) => {
if (e === 'Main server available') {
// @todo: we may deadlock if primary is down for us, but up for buddy
return this.switchConnections(message);
}
// @ts-ignore - following line will always resolve if called from here
this.switchConnections().catch((e) => {
throw Error('e');
});
return Promise.reject(e);
});
}
(this._currentConnection === this._primaryConnection ? this._secondaryConnection : this._primaryConnection).handOverQueue(this._currentConnection);
return p || Promise.resolve();
}
return Promise.reject('No connection available for failover');
}
}
exports.MosDevice = MosDevice;
//# sourceMappingURL=MosDevice.js.map
{
"name": "mos-connection",
"version": "0.4.0",
"version": "0.5.0",
"description": "MOS compliant TCP/IP Socket connection.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc