Compare commits

..

15 Commits

Author SHA1 Message Date
736240b978 1.0.93 2019-11-09 12:23:34 +01:00
73f4600c2a fix(core): update 2019-11-09 12:23:33 +01:00
40beec1166 1.0.92 2019-11-07 01:02:03 +01:00
f8690fef50 1.0.91 2019-11-07 00:59:46 +01:00
972ddbf327 fix(core): update 2019-11-07 00:59:45 +01:00
80aacd17a6 1.0.90 2019-11-03 20:23:23 +01:00
e67b3e50cc fix(core): update 2019-11-03 20:23:22 +01:00
a4a8959b74 1.0.89 2019-09-25 18:46:18 +02:00
bab0f062f7 fix(core): update 2019-09-25 18:46:18 +02:00
3bdfe4dcb4 1.0.88 2019-09-25 18:26:40 +02:00
fca960ad0d fix(core): update 2019-09-25 18:26:39 +02:00
e43ed3951c 1.0.87 2019-09-17 15:40:55 +02:00
23df304535 fix(core): update 2019-09-17 15:40:54 +02:00
9a142175aa 1.0.86 2019-09-17 14:01:24 +02:00
09b593e192 fix(core): update 2019-09-17 14:01:24 +02:00
12 changed files with 429 additions and 450 deletions

732
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartuniverse", "name": "@pushrocks/smartuniverse",
"version": "1.0.85", "version": "1.0.93",
"private": false, "private": false,
"description": "messaging service for your micro services", "description": "messaging service for your micro services",
"main": "dist/index.js", "main": "dist/index.js",
@ -15,10 +15,10 @@
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.17", "@gitzone/tsbuild": "^2.1.17",
"@gitzone/tstest": "^1.0.24", "@gitzone/tstest": "^1.0.28",
"@pushrocks/tapbundle": "^3.0.13", "@pushrocks/tapbundle": "^3.0.13",
"@types/node": "^12.7.4", "@types/node": "^12.12.6",
"tslint": "^5.20.0", "tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0" "tslint-config-prettier": "^1.18.0"
}, },
"peerDependencies": { "peerDependencies": {
@ -27,15 +27,15 @@
"dependencies": { "dependencies": {
"@apiglobal/typedrequest-interfaces": "^1.0.7", "@apiglobal/typedrequest-interfaces": "^1.0.7",
"@pushrocks/lik": "^3.0.11", "@pushrocks/lik": "^3.0.11",
"@pushrocks/smartdelay": "^2.0.3", "@pushrocks/smartdelay": "^2.0.6",
"@pushrocks/smartexpress": "^3.0.40", "@pushrocks/smartexpress": "^3.0.52",
"@pushrocks/smartfile": "^7.0.4", "@pushrocks/smartfile": "^7.0.6",
"@pushrocks/smarthash": "^2.0.6", "@pushrocks/smarthash": "^2.0.6",
"@pushrocks/smartlog": "^2.0.19", "@pushrocks/smartlog": "^2.0.21",
"@pushrocks/smartpromise": "^3.0.2", "@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartrequest": "^1.1.27", "@pushrocks/smartrequest": "^1.1.42",
"@pushrocks/smartrx": "^2.0.5", "@pushrocks/smartrx": "^2.0.5",
"@pushrocks/smartsocket": "^1.1.49", "@pushrocks/smartsocket": "^1.1.58",
"@pushrocks/smarttime": "^3.0.12", "@pushrocks/smarttime": "^3.0.12",
"@pushrocks/smartunique": "^3.0.1" "@pushrocks/smartunique": "^3.0.1"
}, },

View File

@ -77,8 +77,10 @@ tap.test('should receive a message correctly', async (tools) => {
const testChannel = testClientUniverse.getChannel(testChannelData.channelName); const testChannel = testClientUniverse.getChannel(testChannelData.channelName);
const testChannel2 = testClientUniverse2.getChannel(testChannelData.channelName); const testChannel2 = testClientUniverse2.getChannel(testChannelData.channelName);
const subscription = testChannel2.subscribe(messageArg => { const subscription = testChannel2.subscribe(messageArg => {
console.log('Yay##########'); if (messageArg.messageText === 'hellothere') {
done.resolve(); console.log('Yay##########');
done.resolve();
}
}); });
await testChannel.sendMessage({ await testChannel.sendMessage({
messageText: 'hellothere' messageText: 'hellothere'
@ -98,7 +100,7 @@ interface IDemoReqRes {
tap.test('ReactionRequest and ReactionResponse should work', async () => { tap.test('ReactionRequest and ReactionResponse should work', async () => {
const reactionResponse = new smartuniverse.ReactionResponse<IDemoReqRes>({ const reactionResponse = new smartuniverse.ReactionResponse<IDemoReqRes>({
channels: [testClientUniverse.getChannel(testChannelData.channelName)], channels: [testUniverse.getChannel(testChannelData.channelName)],
funcDef: async reqData => { funcDef: async reqData => {
console.log(reqData); console.log(reqData);
return { return {
@ -117,11 +119,12 @@ tap.test('ReactionRequest and ReactionResponse should work', async () => {
console.log(result); console.log(result);
}); });
tap.test('should disconnect the client correctly', async () => { tap.test('should disconnect the client correctly', async (tools) => {
await testClientUniverse.stop(); await testClientUniverse.stop();
await testClientUniverse2.stop();
}); });
tap.test('should end the server correctly', async tools => { tap.test('should end the server correctly', async (tools) => {
await testUniverse.stopServer(); await testUniverse.stopServer();
}); });

View File

@ -0,0 +1,10 @@
import * as plugins from './smartuniverse.plugins';
/**
* broadcasts an event to multiple channels
*/
export class BroadcastEvent<T> {
fire() {
}
};

View File

@ -0,0 +1,5 @@
import * as plugins from './smartuniverse.plugins';
export class BroadcastSUbscription {
}

View File

@ -19,9 +19,9 @@ export interface IClientOptions {
* allows connecting to a universe server * allows connecting to a universe server
*/ */
export class ClientUniverse { export class ClientUniverse {
public options; public options: IClientOptions;
public smartsocketClient: plugins.smartsocket.SmartsocketClient; public smartsocketClient: plugins.smartsocket.SmartsocketClient;
public observableIntake: plugins.smartrx.ObservableIntake<ClientUniverseMessage<any>>; public messageRxjsSubject = new plugins.smartrx.rxjs.Subject<ClientUniverseMessage<any>>();
public clientUniverseCache = new ClientUniverseCache(); public clientUniverseCache = new ClientUniverseCache();
constructor(optionsArg: IClientOptions) { constructor(optionsArg: IClientOptions) {
@ -77,7 +77,7 @@ export class ClientUniverse {
} }
public async stop() { public async stop() {
await this.smartsocketClient.disconnect(); await this.disconnect('triggered');
} }
/** /**
@ -85,7 +85,7 @@ export class ClientUniverse {
* since password validation is done through other means, a connection should always be possible * since password validation is done through other means, a connection should always be possible
*/ */
public async checkConnection(): Promise<void> { public async checkConnection(): Promise<void> {
if (!this.smartsocketClient && !this.observableIntake) { if (!this.smartsocketClient) {
const parsedURL = url.parse(this.options.serverAddress); const parsedURL = url.parse(this.options.serverAddress);
const socketConfig: plugins.smartsocket.ISmartsocketClientOptions = { const socketConfig: plugins.smartsocket.ISmartsocketClientOptions = {
alias: 'universeclient', alias: 'universeclient',
@ -95,7 +95,13 @@ export class ClientUniverse {
url: parsedURL.protocol + '//' + parsedURL.hostname url: parsedURL.protocol + '//' + parsedURL.hostname
}; };
this.smartsocketClient = new SmartsocketClient(socketConfig); this.smartsocketClient = new SmartsocketClient(socketConfig);
this.observableIntake = new plugins.smartrx.ObservableIntake();
this.smartsocketClient.eventSubject.subscribe(async eventArg => {
switch(eventArg) {
case 'disconnected':
this.disconnect('upstreamEvent');
}
});
// lets define some basic actions // lets define some basic actions
@ -105,8 +111,14 @@ export class ClientUniverse {
const socketFunctionUnsubscribe = new plugins.smartsocket.SocketFunction({ const socketFunctionUnsubscribe = new plugins.smartsocket.SocketFunction({
funcName: 'unsubscribe', funcName: 'unsubscribe',
allowedRoles: [], allowedRoles: [],
funcDef: async (data: interfaces.IServerUnsubscribeActionPayload) => { funcDef: async (dataArg: interfaces.IServerUnsubscribeActionPayload) => {
throw new Error('TODO'); const channel = this.clientUniverseCache.channelMap.find(channelArg => {
return channelArg.name === dataArg.name;
});
if (channel) {
channel.unsubscribe();
}
return {};
} }
}); });
@ -123,7 +135,7 @@ export class ClientUniverse {
const clientUniverseMessage = ClientUniverseMessage.createMessageFromMessageDescriptor( const clientUniverseMessage = ClientUniverseMessage.createMessageFromMessageDescriptor(
messageDescriptorArg messageDescriptorArg
); );
this.observableIntake.push(clientUniverseMessage); this.messageRxjsSubject.next(clientUniverseMessage);
// lets find the corresponding channel // lets find the corresponding channel
const targetChannel = this.getChannel(clientUniverseMessage.targetChannelName); const targetChannel = this.getChannel(clientUniverseMessage.targetChannelName);
@ -151,4 +163,15 @@ export class ClientUniverse {
}); });
} }
} }
public async disconnect(reason: 'upstreamEvent' | 'triggered' = 'triggered', tryReconnect = false) {
if ('triggered') {
this.smartsocketClient.disconnect();
}
this.smartsocketClient = null;
if (tryReconnect) {
await plugins.smartdelay.delayForRandom(5000, 20000);
this.checkConnection();
}
}
} }

View File

@ -63,6 +63,10 @@ export class ClientUniverseChannel implements interfaces.IUniverseChannel {
); );
} }
public unsubscribe() {
// TODO: unsubscribe all users
}
public async populateSubscriptionToServer() { public async populateSubscriptionToServer() {
// lets make sure the channel is connected // lets make sure the channel is connected
if (this.status === 'unsubscribed') { if (this.status === 'unsubscribed') {

View File

@ -68,7 +68,7 @@ export class Universe {
/** /**
* returns a channel * returns a channel
*/ */
public getChannelByName(channelNameArg: string) { public getChannel(channelNameArg: string) {
return this.universeCache.channelMap.find(channelArg => { return this.universeCache.channelMap.find(channelArg => {
return channelArg.name === channelNameArg; return channelArg.name === channelNameArg;
}); });
@ -112,6 +112,7 @@ export class Universe {
funcName: 'subscribeChannel', funcName: 'subscribeChannel',
funcDef: async (dataArg, socketConnectionArg) => { funcDef: async (dataArg, socketConnectionArg) => {
const universeConnection = new UniverseConnection({ const universeConnection = new UniverseConnection({
universe: this,
socketConnection: socketConnectionArg, socketConnection: socketConnectionArg,
authenticationRequests: [dataArg] authenticationRequests: [dataArg]
}); });

View File

@ -19,7 +19,7 @@ export class UniverseCache {
// INSTANCE // INSTANCE
// ======== // ========
public standardMessageExpiry: number; public standardMessageExpiry: number;
public destructionTime: number = 60000; public destructionTime: number = 10000;
/** /**
* stores messages for this instance * stores messages for this instance

View File

@ -163,6 +163,6 @@ export class UniverseChannel {
passphrase: this.passphrase, passphrase: this.passphrase,
timestamp: Date.now() timestamp: Date.now()
}); });
this.push(messageToSend); this.universeRef.universeCache.addMessage(messageToSend);
} }
} }

View File

@ -26,7 +26,7 @@ export class UniverseConnection {
universeConnection universeConnection
); );
universeRef.universeCache.connectionMap.add(universeConnection); universeRef.universeCache.connectionMap.add(universeConnection);
console.log('hi') console.log('hi');
} }
/** /**
@ -93,6 +93,8 @@ export class UniverseConnection {
return universeConnection; return universeConnection;
} }
// INSTANCE
public universeRef: Universe;
public terminatedDeferred = plugins.smartpromise.defer(); public terminatedDeferred = plugins.smartpromise.defer();
/** /**
@ -100,23 +102,33 @@ export class UniverseConnection {
*/ */
public socketConnection: plugins.smartsocket.SocketConnection; public socketConnection: plugins.smartsocket.SocketConnection;
public authenticationRequests: Array<interfaces.ISocketRequest_SubscribeChannel['request']> = []; public authenticationRequests: Array<interfaces.ISocketRequest_SubscribeChannel['request']> = [];
public subscribedChannels: UniverseChannel[] = [];
public authenticatedChannels: UniverseChannel[] = []; public authenticatedChannels: UniverseChannel[] = [];
public failedToJoinChannels: UniverseChannel[] = []; public failedToJoinChannels: UniverseChannel[] = [];
/** /**
* terminates the connection * disconnect the connection
*/ */
public terminateConnection() { public async disconnect(reason: 'upstreamevent' | 'triggered' = 'triggered') {
this.socketConnection.socket.disconnect(); if (reason === 'triggered') {
await this.socketConnection.disconnect();
}
this.universeRef.universeCache.connectionMap.remove(this);
this.terminatedDeferred.resolve(); this.terminatedDeferred.resolve();
} }
constructor(optionsArg: { constructor(optionsArg: {
universe: Universe;
socketConnection: plugins.smartsocket.SocketConnection; socketConnection: plugins.smartsocket.SocketConnection;
authenticationRequests: Array<interfaces.ISocketRequest_SubscribeChannel['request']>; authenticationRequests: Array<interfaces.ISocketRequest_SubscribeChannel['request']>;
}) { }) {
this.authenticationRequests = optionsArg.authenticationRequests; this.authenticationRequests = optionsArg.authenticationRequests;
this.socketConnection = optionsArg.socketConnection; this.socketConnection = optionsArg.socketConnection;
this.socketConnection.eventSubject.subscribe(async eventArg => {
switch (eventArg) {
case 'disconnected':
await this.disconnect('upstreamevent');
break;
}
});
} }
} }

View File

@ -64,7 +64,7 @@ export class UniverseMessage<T> implements interfaces.IUniverseMessage {
this.passphrase = messageDescriptor.passphrase; this.passphrase = messageDescriptor.passphrase;
this.payload = messageDescriptor.payload; this.payload = messageDescriptor.payload;
// prevent memory issues // prevent memory issues
this.fallBackDestruction(); this.setDestructionTimer();
} }
public setUniverseCache(universeCacheArg: UniverseCache) { public setUniverseCache(universeCacheArg: UniverseCache) {
@ -73,17 +73,23 @@ export class UniverseMessage<T> implements interfaces.IUniverseMessage {
public setTargetChannel() {} public setTargetChannel() {}
public setDestructionTimer(selfdestructAfterArg: number) { public setDestructionTimer(selfdestructAfterArg?: number) {
if (selfdestructAfterArg) { if (selfdestructAfterArg) {
this.destructionTimer = new Timer(selfdestructAfterArg); this.destructionTimer = new Timer(selfdestructAfterArg);
this.destructionTimer.start(); this.destructionTimer.start();
// set up self destruction by removing this from the parent messageCache // set up self destruction by removing this from the parent messageCache
this.destructionTimer.completed.then(async () => { this.destructionTimer.completed.then(async () => {
this.universeCache.messageMap.remove(this); this.universeCache.messageMap.remove(this);
}).catch(err => {
console.log(err);
console.log(this);
}); });
} else { } else {
this.fallBackDestruction(); plugins.smartdelay.delayFor(1000).then(() => {
if (!this.destructionTimer) {
this.setDestructionTimer(6000);
}
});
} }
} }
@ -93,15 +99,4 @@ export class UniverseMessage<T> implements interfaces.IUniverseMessage {
public handleAsBadMessage() { public handleAsBadMessage() {
plugins.smartlog.defaultLogger.log('warn', 'received a bad message'); plugins.smartlog.defaultLogger.log('warn', 'received a bad message');
} }
/**
* prevents memory leaks if channels have no default
*/
private fallBackDestruction() {
plugins.smartdelay.delayFor(1000).then(() => {
if (!this.destructionTimer) {
this.setDestructionTimer(6000);
}
});
}
} }