Performance improvement by using strict equality, fixed heartbeat issue in connection stage

This commit is contained in:
Nicolas Dextraze 2016-10-17 21:58:28 -07:00
parent dd1302f641
commit f951a625f4
22 changed files with 107 additions and 98 deletions

View File

@ -1,18 +1,19 @@
{ {
"name": "eventstore-node", "name": "eventstore-node",
"version": "0.0.2", "version": "0.0.6",
"description": "A port of the EventStore .Net ClientAPI to Node.js", "description": "A port of the EventStore .Net ClientAPI to Node.js",
"main": "index.js", "main": "index.js",
"directories": {
"lib": "lib",
"test": "test"
},
"scripts": { "scripts": {
"clean": "rm lib/dist.js", "clean": "rm lib/dist.js",
"build": "webpack", "build": "webpack",
"pretest": "npm run build", "pretest": "npm run build",
"test": "nodeunit" "test": "nodeunit",
"prepublish": "npm run build"
}, },
"files": [
"lib",
"src"
],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/nicdex/eventstore-node.git" "url": "git+https://github.com/nicdex/eventstore-node.git"

View File

@ -37,38 +37,38 @@ ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionPackage =
}; };
ConnectToPersistentSubscriptionOperation.prototype._inspectPackage = function(pkg) { ConnectToPersistentSubscriptionOperation.prototype._inspectPackage = function(pkg) {
if (pkg.command == TcpCommand.PersistentSubscriptionConfirmation) if (pkg.command === TcpCommand.PersistentSubscriptionConfirmation)
{ {
var dto = ClientMessage.PersistentSubscriptionConfirmation.decode(pkg.data.toBuffer()); var dto = ClientMessage.PersistentSubscriptionConfirmation.decode(pkg.data.toBuffer());
this._confirmSubscription(dto.last_commit_position, dto.last_event_number); this._confirmSubscription(dto.last_commit_position, dto.last_event_number);
this._subscriptionId = dto.subscription_id; this._subscriptionId = dto.subscription_id;
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation"); return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
} }
if (pkg.command == TcpCommand.PersistentSubscriptionStreamEventAppeared) if (pkg.command === TcpCommand.PersistentSubscriptionStreamEventAppeared)
{ {
var dto = ClientMessage.PersistentSubscriptionStreamEventAppeared.decode(pkg.data.toBuffer()); var dto = ClientMessage.PersistentSubscriptionStreamEventAppeared.decode(pkg.data.toBuffer());
this._onEventAppeared(new results.ResolvedEvent(dto.event)); this._onEventAppeared(new results.ResolvedEvent(dto.event));
return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared"); return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared");
} }
if (pkg.command == TcpCommand.SubscriptionDropped) if (pkg.command === TcpCommand.SubscriptionDropped)
{ {
var dto = ClientMessage.SubscriptionDropped.decode(pkg.data.toBuffer()); var dto = ClientMessage.SubscriptionDropped.decode(pkg.data.toBuffer());
if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.AccessDenied) if (dto.reason === ClientMessage.SubscriptionDropped.SubscriptionDropReason.AccessDenied)
{ {
this.dropSubscription(SubscriptionDropReason.AccessDenied, new Error("You do not have access to the stream.")); this.dropSubscription(SubscriptionDropReason.AccessDenied, new Error("You do not have access to the stream."));
return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped");
} }
if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.NotFound) if (dto.reason === ClientMessage.SubscriptionDropped.SubscriptionDropReason.NotFound)
{ {
this.dropSubscription(SubscriptionDropReason.NotFound, new Error("Subscription not found")); this.dropSubscription(SubscriptionDropReason.NotFound, new Error("Subscription not found"));
return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped");
} }
if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.PersistentSubscriptionDeleted) if (dto.reason === ClientMessage.SubscriptionDropped.SubscriptionDropReason.PersistentSubscriptionDeleted)
{ {
this.dropSubscription(SubscriptionDropReason.PersistentSubscriptionDeleted, new Error("Persistent subscription deleted.")); this.dropSubscription(SubscriptionDropReason.PersistentSubscriptionDeleted, new Error("Persistent subscription deleted."));
return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped");
} }
if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.SubscriberMaxCountReached) if (dto.reason === ClientMessage.SubscriptionDropped.SubscriptionDropReason.SubscriberMaxCountReached)
{ {
this.dropSubscription(SubscriptionDropReason.MaxSubscribersReached, new Error("Maximum subscribers reached.")); this.dropSubscription(SubscriptionDropReason.MaxSubscribersReached, new Error("Maximum subscribers reached."));
return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped");
@ -111,10 +111,10 @@ ConnectToPersistentSubscriptionOperation.prototype.notifyEventsFailed = function
action); action);
var pkg = new TcpPackage(TcpCommand.PersistentSubscriptionNakEvents, var pkg = new TcpPackage(TcpCommand.PersistentSubscriptionNakEvents,
this._userCredentials != null ? TcpFlags.Authenticated : TcpFlags.None, this._userCredentials !== null ? TcpFlags.Authenticated : TcpFlags.None,
this._correlationId, this._correlationId,
this._userCredentials != null ? this._userCredentials.username : null, this._userCredentials !== null ? this._userCredentials.username : null,
this._userCredentials != null ? this._userCredentials.password : null, this._userCredentials !== null ? this._userCredentials.password : null,
createBufferSegment(dto.toBuffer())); createBufferSegment(dto.toBuffer()));
this._enqueueSend(pkg); this._enqueueSend(pkg);
}; };

View File

@ -39,7 +39,7 @@ CreatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
return new ClientMessage.CreatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos, return new ClientMessage.CreatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos,
this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize, this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize,
this._readBatchSize, this._bufferSize, this._maxRetryCount, this._readBatchSize, this._bufferSize, this._maxRetryCount,
this._namedConsumerStrategy == SystemConsumerStrategies.RoundRobin, this._checkPointAfter, this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin, this._checkPointAfter,
this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy); this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy);
}; };

View File

@ -42,7 +42,7 @@ OperationBase.prototype._succeed = function() {
if (!this._completed) { if (!this._completed) {
this._completed = true; this._completed = true;
if (this._response != null) if (this._response)
this._cb(null, this._transformResponse(this._response)); this._cb(null, this._transformResponse(this._response));
else else
this._cb(new Error("No result.")) this._cb(new Error("No result."))
@ -118,7 +118,7 @@ OperationBase.prototype._inspectNotHandled = function(pkg)
case ClientMessage.NotHandled.NotHandledReason.NotMaster: case ClientMessage.NotHandled.NotHandledReason.NotMaster:
var masterInfo = ClientMessage.NotHandled.MasterInfo.decode(message.additional_info); var masterInfo = ClientMessage.NotHandled.MasterInfo.decode(message.additional_info);
return new new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster", return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster",
{host: masterInfo.external_tcp_address, port: masterInfo.external_tcp_port}, {host: masterInfo.external_tcp_address, port: masterInfo.external_tcp_port},
{host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port}); {host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port});
@ -130,7 +130,7 @@ OperationBase.prototype._inspectNotHandled = function(pkg)
OperationBase.prototype._inspectUnexpectedCommand = function(pkg, expectedCommand) OperationBase.prototype._inspectUnexpectedCommand = function(pkg, expectedCommand)
{ {
if (pkg.command == expectedCommand) if (pkg.command === expectedCommand)
throw new Error("Command shouldn't be " + TcpCommand.getName(pkg.command)); throw new Error("Command shouldn't be " + TcpCommand.getName(pkg.command));
this.log.error("Unexpected TcpCommand received.\n" this.log.error("Unexpected TcpCommand received.\n"

View File

@ -46,7 +46,7 @@ SubscriptionOperation.prototype._enqueueSend = function(pkg) {
SubscriptionOperation.prototype.subscribe = function(correlationId, connection) { SubscriptionOperation.prototype.subscribe = function(correlationId, connection) {
if (connection === null) throw new TypeError("connection is null."); if (connection === null) throw new TypeError("connection is null.");
if (this._subscription != null || this._unsubscribed != 0) if (this._subscription !== null || this._unsubscribed)
return false; return false;
this._correlationId = correlationId; this._correlationId = correlationId;
@ -128,7 +128,7 @@ SubscriptionOperation.prototype.inspectPackage = function(pkg) {
case TcpCommand.NotHandled: case TcpCommand.NotHandled:
{ {
if (this._subscription != null) if (this._subscription !== null)
throw new Error("NotHandled command appeared while we already subscribed."); throw new Error("NotHandled command appeared while we already subscribed.");
var message = ClientMessage.NotHandled.decode(pkg.data.toBuffer()); var message = ClientMessage.NotHandled.decode(pkg.data.toBuffer());

View File

@ -39,7 +39,7 @@ UpdatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
return new ClientMessage.UpdatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos, return new ClientMessage.UpdatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos,
this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize, this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize,
this._readBatchSize, this._bufferSize, this._maxRetryCount, this._readBatchSize, this._bufferSize, this._maxRetryCount,
this._namedConsumerStrategy == SystemConsumerStrategies.RoundRobin, this._checkPointAfter, this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin, this._checkPointAfter,
this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy); this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy);
}; };

View File

@ -22,21 +22,21 @@ util.inherits(VolatileSubscriptionOperation, SubscriptionOperation);
VolatileSubscriptionOperation.prototype._createSubscriptionPackage = function() { VolatileSubscriptionOperation.prototype._createSubscriptionPackage = function() {
var dto = new ClientMessage.SubscribeToStream(this._streamId, this._resolveLinkTos); var dto = new ClientMessage.SubscribeToStream(this._streamId, this._resolveLinkTos);
return new TcpPackage(TcpCommand.SubscribeToStream, return new TcpPackage(TcpCommand.SubscribeToStream,
this._userCredentials != null ? TcpFlags.Authenticated : TcpFlags.None, this._userCredentials !== null ? TcpFlags.Authenticated : TcpFlags.None,
this._correlationId, this._correlationId,
this._userCredentials != null ? this._userCredentials.username : null, this._userCredentials !== null ? this._userCredentials.username : null,
this._userCredentials != null ? this._userCredentials.password : null, this._userCredentials !== null ? this._userCredentials.password : null,
new BufferSegment(dto.toBuffer())); new BufferSegment(dto.toBuffer()));
}; };
VolatileSubscriptionOperation.prototype._inspectPackage = function(pkg) { VolatileSubscriptionOperation.prototype._inspectPackage = function(pkg) {
try { try {
if (pkg.command == TcpCommand.SubscriptionConfirmation) { if (pkg.command === TcpCommand.SubscriptionConfirmation) {
var dto = ClientMessage.SubscriptionConfirmation.decode(pkg.data.toBuffer()); var dto = ClientMessage.SubscriptionConfirmation.decode(pkg.data.toBuffer());
this._confirmSubscription(dto.last_commit_position, dto.last_event_number); this._confirmSubscription(dto.last_commit_position, dto.last_event_number);
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation"); return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
} }
if (pkg.command == TcpCommand.StreamEventAppeared) { if (pkg.command === TcpCommand.StreamEventAppeared) {
var dto = ClientMessage.StreamEventAppeared.decode(pkg.data.toBuffer()); var dto = ClientMessage.StreamEventAppeared.decode(pkg.data.toBuffer());
this._onEventAppeared(new results.ResolvedEvent(dto.event)); this._onEventAppeared(new results.ResolvedEvent(dto.event));
return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared"); return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared");

View File

@ -38,7 +38,7 @@ ClusterDnsEndPointDiscoverer.prototype.discover = function(failedTcpEndPoint) {
return endPoints; return endPoints;
}) })
.catch(function (exc) { .catch(function (exc) {
self._log.info(util.format("Discovering attempt %d/%d failed with error: %s.", attempt, self._maxDiscoverAttempts, exc)); self._log.info(util.format("Discovering attempt %d/%d failed with error: %s.\n%s", attempt, self._maxDiscoverAttempts, exc, exc.stack));
}) })
.then(function (endPoints) { .then(function (endPoints) {
if (endPoints) if (endPoints)
@ -67,6 +67,7 @@ ClusterDnsEndPointDiscoverer.prototype._discoverEndPoint = function (failedTcpEn
var self = this; var self = this;
var promise = Promise.resolve(); var promise = Promise.resolve();
var j = 0; var j = 0;
self._log.debug('Gossip candidates', gossipCandidates);
for (var i = 0; i < gossipCandidates.length; i++) { for (var i = 0; i < gossipCandidates.length; i++) {
promise = promise.then(function (endPoints) { promise = promise.then(function (endPoints) {
if (endPoints) return endPoints; if (endPoints) return endPoints;
@ -90,10 +91,9 @@ ClusterDnsEndPointDiscoverer.prototype._discoverEndPoint = function (failedTcpEn
}; };
ClusterDnsEndPointDiscoverer.prototype._getGossipCandidatesFromOldGossip = function (oldGossip, failedTcpEndPoint) { ClusterDnsEndPointDiscoverer.prototype._getGossipCandidatesFromOldGossip = function (oldGossip, failedTcpEndPoint) {
if (failedTcpEndPoint === null) return oldGossip; if (failedTcpEndPoint === null) return this._arrangeGossipCandidates(oldGossip);
var gossipCandidates = oldGossip.filter(function(x) { var gossipCandidates = oldGossip.filter(function(x) {
//TODO: failedTcpEndpoint.host might not be an ip return !(x.externalTcpPort === failedTcpEndPoint.port && x.externalTcpIp === failedTcpEndPoint.host);
return (x.externalTcpPort !== failedTcpEndPoint.port && x.externalTcpIp !== failedTcpEndPoint.host);
}); });
return this._arrangeGossipCandidates(gossipCandidates); return this._arrangeGossipCandidates(gossipCandidates);
}; };
@ -133,6 +133,7 @@ ClusterDnsEndPointDiscoverer.prototype._getGossipCandidatesFromDns = function ()
ClusterDnsEndPointDiscoverer.prototype._tryGetGossipFrom = function (endPoint) { ClusterDnsEndPointDiscoverer.prototype._tryGetGossipFrom = function (endPoint) {
var options = { var options = {
host: endPoint.endPoint.host,
hostname: endPoint.endPoint.hostname, hostname: endPoint.endPoint.hostname,
port: endPoint.endPoint.port, port: endPoint.endPoint.port,
path: '/gossip?format=json' path: '/gossip?format=json'
@ -140,6 +141,7 @@ ClusterDnsEndPointDiscoverer.prototype._tryGetGossipFrom = function (endPoint) {
if (endPoint.hostHeader) { if (endPoint.hostHeader) {
options.headers = {'Host': endPoint.hostHeader}; options.headers = {'Host': endPoint.hostHeader};
} }
this._log.info('Try get gossip from', endPoint);
var self = this; var self = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
try { try {
@ -215,7 +217,7 @@ ClusterDnsEndPointDiscoverer.prototype._tryDetermineBestNode = function (members
var secTcp = node.externalSecureTcpPort > 0 var secTcp = node.externalSecureTcpPort > 0
? {host: externalTcpIp, port: node.externalSecureTcpPort} ? {host: externalTcpIp, port: node.externalSecureTcpPort}
: null; : null;
this._log.info(util.format("Discovering: found best choice [%j,%j] (%s).", normTcp, secTcp == null ? "n/a" : secTcp, node.state)); this._log.info(util.format("Discovering: found best choice [%j,%j] (%s).", normTcp, secTcp === null ? "n/a" : secTcp, node.state));
return new NodeEndPoints(normTcp, secTcp); return new NodeEndPoints(normTcp, secTcp);
}; };

View File

@ -165,7 +165,7 @@ EventStoreConnectionLogicHandler.prototype._startConnection = function(cb, endpo
* @private * @private
*/ */
EventStoreConnectionLogicHandler.prototype._closeConnection = function(reason, error) { EventStoreConnectionLogicHandler.prototype._closeConnection = function(reason, error) {
if (this._state == ConnectionState.Closed) { if (this._state === ConnectionState.Closed) {
this._logDebug("CloseConnection IGNORED because is ESConnection is CLOSED, reason %s, error %s.", reason, error ? error.stack : ''); this._logDebug("CloseConnection IGNORED because is ESConnection is CLOSED, reason %s, error %s.", reason, error ? error.stack : '');
return; return;
} }
@ -189,7 +189,7 @@ EventStoreConnectionLogicHandler.prototype._closeConnection = function(reason, e
EventStoreConnectionLogicHandler.prototype._closeTcpConnection = function(reason) { EventStoreConnectionLogicHandler.prototype._closeTcpConnection = function(reason) {
if (!this._connection) { if (!this._connection) {
this._logDebug("CloseTcpConnection IGNORED because _connection == null"); this._logDebug("CloseTcpConnection IGNORED because _connection === null");
return; return;
} }
@ -320,7 +320,7 @@ EventStoreConnectionLogicHandler.prototype._startPersistentSubscription = functi
EventStoreConnectionLogicHandler.prototype._establishTcpConnection = function(endPoints) { EventStoreConnectionLogicHandler.prototype._establishTcpConnection = function(endPoints) {
var endPoint = this._settings.useSslConnection ? endPoints.secureTcpEndPoint : endPoints.tcpEndPoint; var endPoint = this._settings.useSslConnection ? endPoints.secureTcpEndPoint : endPoints.tcpEndPoint;
if (endPoint == null) if (endPoint === null)
{ {
this._closeConnection("No end point to node specified."); this._closeConnection("No end point to node specified.");
return; return;
@ -328,8 +328,8 @@ EventStoreConnectionLogicHandler.prototype._establishTcpConnection = function(en
this._logDebug("EstablishTcpConnection to [%j]", endPoint); this._logDebug("EstablishTcpConnection to [%j]", endPoint);
if (this._state != ConnectionState.Connecting) return; if (this._state !== ConnectionState.Connecting) return;
if (this._connectingPhase != ConnectingPhase.EndPointDiscovery) return; if (this._connectingPhase !== ConnectingPhase.EndPointDiscovery) return;
var self = this; var self = this;
this._connectingPhase = ConnectingPhase.ConnectionEstablishing; this._connectingPhase = ConnectingPhase.ConnectionEstablishing;
@ -358,10 +358,10 @@ EventStoreConnectionLogicHandler.prototype._establishTcpConnection = function(en
}; };
EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(connection) { EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(connection) {
if (this._state != ConnectionState.Connecting || !this._connection.equals(connection) || connection.isClosed) if (this._state !== ConnectionState.Connecting || !this._connection.equals(connection) || connection.isClosed)
{ {
this._logDebug("IGNORED (_state %s, _conn.Id %s, conn.Id %s, conn.closed %s): TCP connection to [%j, L%j] established.", this._logDebug("IGNORED (_state %s, _conn.Id %s, conn.Id %s, conn.closed %s): TCP connection to [%j, L%j] established.",
this._state, this._connection == null ? EmptyGuid : this._connection.connectionId, connection.connectionId, this._state, this._connection === null ? EmptyGuid : this._connection.connectionId, connection.connectionId,
connection.isClosed, connection.remoteEndPoint, connection.localEndPoint); connection.isClosed, connection.remoteEndPoint, connection.localEndPoint);
return; return;
} }
@ -373,7 +373,7 @@ EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(
timeStamp: Date.now() timeStamp: Date.now()
}; };
if (this._settings.defaultUserCredentials != null) if (this._settings.defaultUserCredentials !== null)
{ {
this._connectingPhase = ConnectingPhase.Authentication; this._connectingPhase = ConnectingPhase.Authentication;
@ -402,7 +402,7 @@ EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
this.emit('connected', this._connection.remoteEndPoint); this.emit('connected', this._connection.remoteEndPoint);
if (Date.now() - this._lastTimeoutsTimeStamp >= this._settings.operationTimeoutCheckPeriod) if ((Date.now() - this._lastTimeoutsTimeStamp) >= this._settings.operationTimeoutCheckPeriod)
{ {
this._operations.checkTimeoutsAndRetry(this._connection); this._operations.checkTimeoutsAndRetry(this._connection);
this._subscriptions.checkTimeoutsAndRetry(this._connection); this._subscriptions.checkTimeoutsAndRetry(this._connection);
@ -411,19 +411,19 @@ EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
}; };
EventStoreConnectionLogicHandler.prototype._tcpConnectionError = function(connection, error) { EventStoreConnectionLogicHandler.prototype._tcpConnectionError = function(connection, error) {
if (this._connection != connection) return; if (!this._connection.equals(connection)) return;
if (this._state == ConnectionState.Closed) return; if (this._state === ConnectionState.Closed) return;
this._logDebug("TcpConnectionError connId %s, exc %s.", connection.connectionId, error); this._logDebug("TcpConnectionError connId %s, exc %s.", connection.connectionId, error);
this._closeConnection("TCP connection error occurred.", error); this._closeConnection("TCP connection error occurred.", error);
}; };
EventStoreConnectionLogicHandler.prototype._tcpConnectionClosed = function(connection, error) { EventStoreConnectionLogicHandler.prototype._tcpConnectionClosed = function(connection, error) {
if (this._state == ConnectionState.Init) throw new Error(); if (this._state === ConnectionState.Init) throw new Error();
if (this._state == ConnectionState.Closed || !this._connection.equals(connection)) if (this._state === ConnectionState.Closed || !this._connection.equals(connection))
{ {
this._logDebug("IGNORED (_state: %s, _conn.ID: %s, conn.ID: %s): TCP connection to [%j, L%j] closed.", this._logDebug("IGNORED (_state: %s, _conn.ID: %s, conn.ID: %s): TCP connection to [%j, L%j] closed.",
this._state, this._connection == null ? EmptyGuid : this._connection.connectionId, connection.connectionId, this._state, this._connection === null ? EmptyGuid : this._connection.connectionId, connection.connectionId,
connection.remoteEndPoint, connection.localEndPoint); connection.remoteEndPoint, connection.localEndPoint);
return; return;
} }
@ -447,7 +447,7 @@ EventStoreConnectionLogicHandler.prototype._tcpConnectionClosed = function(conne
}; };
EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connection, pkg) { EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connection, pkg) {
if (!connection.equals(this._connection) || this._state == ConnectionState.Closed || this._state == ConnectionState.Init) if (!connection.equals(this._connection) || this._state === ConnectionState.Closed || this._state === ConnectionState.Init)
{ {
this._logDebug("IGNORED: HandleTcpPackage connId %s, package %s, %s.", this._logDebug("IGNORED: HandleTcpPackage connId %s, package %s, %s.",
connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId); connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId);
@ -458,9 +458,9 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
this._connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId); this._connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId);
this._packageNumber += 1; this._packageNumber += 1;
if (pkg.command == TcpCommand.HeartbeatResponseCommand) if (pkg.command === TcpCommand.HeartbeatResponseCommand)
return; return;
if (pkg.command == TcpCommand.HeartbeatRequestCommand) if (pkg.command === TcpCommand.HeartbeatRequestCommand)
{ {
this._connection.enqueueSend(new TcpPackage( this._connection.enqueueSend(new TcpPackage(
TcpCommand.HeartbeatResponseCommand, TcpCommand.HeartbeatResponseCommand,
@ -469,13 +469,13 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
return; return;
} }
if (pkg.command == TcpCommand.Authenticated || pkg.command == TcpCommand.NotAuthenticated) if (pkg.command === TcpCommand.Authenticated || pkg.command === TcpCommand.NotAuthenticated)
{ {
if (this._state == ConnectionState.Connecting if (this._state === ConnectionState.Connecting
&& this._connectingPhase == ConnectingPhase.Authentication && this._connectingPhase === ConnectingPhase.Authentication
&& this._authInfo.correlationId == pkg.correlationId) && this._authInfo.correlationId === pkg.correlationId)
{ {
if (pkg.command == TcpCommand.NotAuthenticated) if (pkg.command === TcpCommand.NotAuthenticated)
this.emit('authenticationFailed', "Not authenticated"); this.emit('authenticationFailed', "Not authenticated");
this._goToConnectedState(); this._goToConnectedState();
@ -483,7 +483,7 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
} }
} }
if (pkg.command == TcpCommand.BadRequest && pkg.correlationId == EmptyGuid) if (pkg.command === TcpCommand.BadRequest && pkg.correlationId === EmptyGuid)
{ {
var message = "<no message>"; var message = "<no message>";
try { try {
@ -515,7 +515,7 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
default: default:
throw new Error("Unknown InspectionDecision: " + result.decision); throw new Error("Unknown InspectionDecision: " + result.decision);
} }
if (this._state == ConnectionState.Connected) if (this._state === ConnectionState.Connected)
this._operations.scheduleWaitingOperations(connection); this._operations.scheduleWaitingOperations(connection);
return; return;
@ -557,13 +557,13 @@ EventStoreConnectionLogicHandler.prototype._reconnectTo = function(endPoints) {
var endPoint = this._settings.useSslConnection var endPoint = this._settings.useSslConnection
? endPoints.secureTcpEndPoint ? endPoints.secureTcpEndPoint
: endPoints.tcpEndPoint; : endPoints.tcpEndPoint;
if (endPoint == null) if (endPoint === null)
{ {
this._closeConnection("No end point is specified while trying to reconnect."); this._closeConnection("No end point is specified while trying to reconnect.");
return; return;
} }
if (this._state != ConnectionState.Connected || this._connection.remoteEndPoint == endPoint) if (this._state !== ConnectionState.Connected || this._connection.remoteEndPoint === endPoint)
return; return;
var msg = util.format("EventStoreConnection '%s': going to reconnect to [%j]. Current endpoint: [%j, L%j].", var msg = util.format("EventStoreConnection '%s': going to reconnect to [%j]. Current endpoint: [%j, L%j].",
@ -581,7 +581,7 @@ EventStoreConnectionLogicHandler.prototype._timerTick = function() {
{ {
case ConnectionState.Init: break; case ConnectionState.Init: break;
case ConnectionState.Connecting: case ConnectionState.Connecting:
if (this._connectingPhase == ConnectingPhase.Reconnecting && Date.now() - this._reconnInfo.timeStamp >= this._settings.reconnectionDelay) if (this._connectingPhase === ConnectingPhase.Reconnecting && (Date.now() - this._reconnInfo.timeStamp) >= this._settings.reconnectionDelay)
{ {
this._logDebug("TimerTick checking reconnection..."); this._logDebug("TimerTick checking reconnection...");
@ -594,17 +594,17 @@ EventStoreConnectionLogicHandler.prototype._timerTick = function() {
this._discoverEndpoint(null); this._discoverEndpoint(null);
} }
} }
else if (this._connectingPhase == ConnectingPhase.Authentication && Date.now() - this._authInfo.timeStamp >= this._settings.operationTimeout) else if (this._connectingPhase === ConnectingPhase.Authentication && (Date.now() - this._authInfo.timeStamp) >= this._settings.operationTimeout)
{ {
this.emit('authenticationFailed', "Authentication timed out."); this.emit('authenticationFailed', "Authentication timed out.");
this._goToConnectedState(); this._goToConnectedState();
} }
else if (this._connectingPhase > ConnectingPhase.ConnectionEstablishing) else if (this._connectingPhase === ConnectingPhase.Authentication || this._connectingPhase === ConnectingPhase.Connected)
this._manageHeartbeats(); this._manageHeartbeats();
break; break;
case ConnectionState.Connected: case ConnectionState.Connected:
// operations timeouts are checked only if connection is established and check period time passed // operations timeouts are checked only if connection is established and check period time passed
if (Date.now() - this._lastTimeoutsTimeStamp >= this._settings.operationTimeoutCheckPeriod) if ((Date.now() - this._lastTimeoutsTimeStamp) >= this._settings.operationTimeoutCheckPeriod)
{ {
// On mono even impossible connection first says that it is established // On mono even impossible connection first says that it is established
// so clearing of reconnection count on ConnectionEstablished event causes infinite reconnections. // so clearing of reconnection count on ConnectionEstablished event causes infinite reconnections.
@ -624,14 +624,14 @@ EventStoreConnectionLogicHandler.prototype._timerTick = function() {
}; };
EventStoreConnectionLogicHandler.prototype._manageHeartbeats = function() { EventStoreConnectionLogicHandler.prototype._manageHeartbeats = function() {
if (this._connection == null) return; if (this._connection === null) return;
var timeout = this._heartbeatInfo.isIntervalStage ? this._settings.heartbeatInterval : this._settings.heartbeatTimeout; var timeout = this._heartbeatInfo.isIntervalStage ? this._settings.heartbeatInterval : this._settings.heartbeatTimeout;
if (Date.now() - this._heartbeatInfo.timeStamp < timeout) if ((Date.now() - this._heartbeatInfo.timeStamp) < timeout)
return; return;
var packageNumber = this._packageNumber; var packageNumber = this._packageNumber;
if (this._heartbeatInfo.lastPackageNumber != packageNumber) if (this._heartbeatInfo.lastPackageNumber !== packageNumber)
{ {
this._heartbeatInfo = {lastPackageNumber: packageNumber, isIntervalStage: true, timeStamp: Date.now()}; this._heartbeatInfo = {lastPackageNumber: packageNumber, isIntervalStage: true, timeStamp: Date.now()};
return; return;
@ -649,10 +649,9 @@ EventStoreConnectionLogicHandler.prototype._manageHeartbeats = function() {
else else
{ {
// TcpMessage.HeartbeatTimeout analog // TcpMessage.HeartbeatTimeout analog
var msg = util.format("EventStoreConnection '%s': closing TCP connection [%j, L%j, %s] due to HEARTBEAT TIMEOUT at pkgNum %d.", this._logInfo("EventStoreConnection '%s': closing TCP connection [%j, L%j, %s] due to HEARTBEAT TIMEOUT at pkgNum %d.",
this._esConnection.connectionName, this._connection.remoteEndPoint, this._connection.localEndPoint, this._esConnection.connectionName, this._connection.remoteEndPoint, this._connection.localEndPoint,
this._connection.connectionId, packageNumber); this._connection.connectionId, packageNumber);
this._settings.log.info(msg);
this._closeTcpConnection(msg); this._closeTcpConnection(msg);
} }
}; };

View File

@ -55,7 +55,7 @@ OperationsManager.prototype.checkTimeoutsAndRetry = function(connection) {
var removeOperations = []; var removeOperations = [];
var self = this; var self = this;
this._activeOperations.forEach(function(correlationId, operation) { this._activeOperations.forEach(function(correlationId, operation) {
if (operation.connectionId != connection.connectionId) if (operation.connectionId !== connection.connectionId)
{ {
retryOperations.push(operation); retryOperations.push(operation);
} }

View File

@ -13,8 +13,14 @@ function SimpleQueuedHandler() {
} }
SimpleQueuedHandler.prototype.registerHandler = function(type, handler) { SimpleQueuedHandler.prototype.registerHandler = function(type, handler) {
type = typeName(type); var typeId = typeName(type);
this._handlers[type] = handler; this._handlers[typeId] = function (msg) {
try {
handler(msg);
} catch(e) {
console.log('ERROR: ', e);
}
};
}; };
SimpleQueuedHandler.prototype.enqueueMessage = function(msg) { SimpleQueuedHandler.prototype.enqueueMessage = function(msg) {
@ -28,10 +34,10 @@ SimpleQueuedHandler.prototype.enqueueMessage = function(msg) {
SimpleQueuedHandler.prototype._processQueue = function() { SimpleQueuedHandler.prototype._processQueue = function() {
var message = this._messages.shift(); var message = this._messages.shift();
while(message) { while(message) {
var type = typeName(message); var typeId = typeName(message);
var handler = this._handlers[type]; var handler = this._handlers[typeId];
if (!handler) if (!handler)
throw new Error("No handler registered for message " + type); throw new Error("No handler registered for message " + typeId);
setImmediate(handler, message); setImmediate(handler, message);
message = this._messages.shift(); message = this._messages.shift();
} }

View File

@ -42,7 +42,7 @@ SubscriptionsManager.prototype.purgeSubscribedAndDroppedSubscriptions = function
var self = this; var self = this;
var subscriptionsToRemove = []; var subscriptionsToRemove = [];
this._activeSubscriptions.forEach(function(_, subscription) { this._activeSubscriptions.forEach(function(_, subscription) {
if (subscription.isSubscribed && subscription.connectionId == connectionId) { if (subscription.isSubscribed && subscription.connectionId === connectionId) {
subscription.operation.connectionClosed(); subscription.operation.connectionClosed();
subscriptionsToRemove.push(subscription); subscriptionsToRemove.push(subscription);
} }
@ -60,7 +60,7 @@ SubscriptionsManager.prototype.checkTimeoutsAndRetry = function(connection) {
var removeSubscriptions = []; var removeSubscriptions = [];
this._activeSubscriptions.forEach(function(_, subscription) { this._activeSubscriptions.forEach(function(_, subscription) {
if (subscription.isSubscribed) return; if (subscription.isSubscribed) return;
if (subscription.connectionId != connection.connectionId) if (subscription.connectionId !== connection.connectionId)
{ {
retrySubscriptions.push(subscription); retrySubscriptions.push(subscription);
} }
@ -165,7 +165,7 @@ SubscriptionsManager.prototype._logDebug = function(message) {
if (!this._settings.verboseLogging) return; if (!this._settings.verboseLogging) return;
var parameters = Array.prototype.slice.call(arguments, 1); var parameters = Array.prototype.slice.call(arguments, 1);
this._settings.log.debug("EventStoreConnection '%s': %s.", this._connectionName, parameters.length == 0 ? message : util.format(message, parameters)); this._settings.log.debug("EventStoreConnection '%s': %s.", this._connectionName, parameters.length === 0 ? message : util.format(message, parameters));
}; };
module.exports = SubscriptionsManager; module.exports = SubscriptionsManager;

View File

@ -31,7 +31,7 @@ var defaultConnectionSettings = {
// Cluster Settings // Cluster Settings
clusterDns: '', clusterDns: '',
maxDiscoverAttemps: 10, maxDiscoverAttempts: 10,
externalGossipPort: 0, externalGossipPort: 0,
gossipTimeout: 1000 gossipTimeout: 1000
}; };
@ -85,7 +85,7 @@ function createFromGossipSeeds(connectionSettings, gossipSeeds, connectionName)
maxDiscoverAttempts: mergedSettings.maxDiscoverAttempts, maxDiscoverAttempts: mergedSettings.maxDiscoverAttempts,
gossipTimeout: mergedSettings.gossipTimeout gossipTimeout: mergedSettings.gossipTimeout
}; };
var endPointDiscoverer = new ClusterDnsEndPointDiscoverer(connectionSettings.log, var endPointDiscoverer = new ClusterDnsEndPointDiscoverer(mergedSettings.log,
clusterSettings.clusterDns, clusterSettings.clusterDns,
clusterSettings.maxDiscoverAttempts, clusterSettings.maxDiscoverAttempts,
clusterSettings.externalGossipPort, clusterSettings.externalGossipPort,

View File

@ -38,6 +38,7 @@ EventStorePersistentSubscriptionBase.prototype.start = function() {
this._startSubscription(this._subscriptionId, this._streamId, this._bufferSize, this._userCredentials, this._startSubscription(this._subscriptionId, this._streamId, this._bufferSize, this._userCredentials,
this._onEventAppeared.bind(this), this._onSubscriptionDropped.bind(this), this._settings) this._onEventAppeared.bind(this), this._onSubscriptionDropped.bind(this), this._settings)
.then(function(subscription) { .then(function(subscription) {
console.log('Subscription started.');
self._subscription = subscription; self._subscription = subscription;
}); });
}; };
@ -145,7 +146,7 @@ EventStorePersistentSubscriptionBase.prototype._processQueue = function() {
e = this._queue.shift(); e = this._queue.shift();
} }
this._isProcessing = false; this._isProcessing = false;
//} while (_queue.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) == 0); //} while (_queue.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) === 0);
}; };
EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) { EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) {

View File

@ -1,5 +1,5 @@
module.exports = function GossipSeed(endPoint, hostName) { module.exports = function GossipSeed(endPoint, hostName) {
if (typeof endPoint !== 'object' || !endPoint.hostname || !endPoint.port) throw new TypeError('endPoint must be have hostname and port properties.'); //if (typeof endPoint !== 'object' || !endPoint.hostname || !endPoint.port) throw new TypeError('endPoint must be have hostname and port properties.');
Object.defineProperties(this, { Object.defineProperties(this, {
endPoint: { endPoint: {
enumerable: true, enumerable: true,

View File

@ -69,7 +69,7 @@ function RecordedEvent(ev) {
createdEpoch: {enumerable: true, value: ev.created_epoch ? ev.created_epoch.toInt() : 0}, createdEpoch: {enumerable: true, value: ev.created_epoch ? ev.created_epoch.toInt() : 0},
data: {enumerable: true, value: ev.data ? ev.data.toBuffer() : new Buffer(0)}, data: {enumerable: true, value: ev.data ? ev.data.toBuffer() : new Buffer(0)},
metadata: {enumerable: true, value: ev.metadata ? ev.metadata.toBuffer() : new Buffer(0)}, metadata: {enumerable: true, value: ev.metadata ? ev.metadata.toBuffer() : new Buffer(0)},
isJson: {enumerable: true, value: ev.data_content_type == 1} isJson: {enumerable: true, value: ev.data_content_type === 1}
}); });
} }

View File

@ -29,7 +29,7 @@ TcpPackage.fromBufferSegment = function(data) {
var headerSize = MandatorySize; var headerSize = MandatorySize;
var login = null, pass = null; var login = null, pass = null;
if ((flags & TcpFlags.Authenticated) != 0) if ((flags & TcpFlags.Authenticated) !== 0)
{ {
var loginLen = data.buffer[data.offset + AuthOffset]; var loginLen = data.buffer[data.offset + AuthOffset];
if (AuthOffset + 1 + loginLen + 1 >= data.count) if (AuthOffset + 1 + loginLen + 1 >= data.count)
@ -48,7 +48,7 @@ TcpPackage.fromBufferSegment = function(data) {
}; };
TcpPackage.prototype.asBuffer = function() { TcpPackage.prototype.asBuffer = function() {
if ((this.flags & TcpFlags.Authenticated) != 0) { if ((this.flags & TcpFlags.Authenticated) !== 0) {
var loginBytes = new Buffer(this.login); var loginBytes = new Buffer(this.login);
if (loginBytes.length > 255) throw new Error("Login serialized length should be less than 256 bytes."); if (loginBytes.length > 255) throw new Error("Login serialized length should be less than 256 bytes.");
var passwordBytes = new Buffer(this.password); var passwordBytes = new Buffer(this.password);

View File

@ -29,7 +29,7 @@ LengthPrefixMessageFramer.prototype._parse = function(bytes) {
{ {
this._packageLength |= (buffer[i] << (this._headerBytes * 8)); // little-endian order this._packageLength |= (buffer[i] << (this._headerBytes * 8)); // little-endian order
++this._headerBytes; ++this._headerBytes;
if (this._headerBytes == HeaderLength) if (this._headerBytes === HeaderLength)
{ {
if (this._packageLength <= 0 || this._packageLength > this._maxPackageSize) if (this._packageLength <= 0 || this._packageLength > this._maxPackageSize)
throw new Error(["Package size is out of bounds: ", this._packageLength, "(max: ", this._maxPackageSize, "."].join('')); throw new Error(["Package size is out of bounds: ", this._packageLength, "(max: ", this._maxPackageSize, "."].join(''));
@ -44,9 +44,9 @@ LengthPrefixMessageFramer.prototype._parse = function(bytes) {
this._bufferIndex += copyCnt; this._bufferIndex += copyCnt;
i += copyCnt - 1; i += copyCnt - 1;
if (this._bufferIndex == this._packageLength) if (this._bufferIndex === this._packageLength)
{ {
if (this._receivedHandler != null) if (this._receivedHandler !== null)
this._receivedHandler(createBufferSegment(this._messageBuffer, 0, this._bufferIndex)); this._receivedHandler(createBufferSegment(this._messageBuffer, 0, this._bufferIndex));
this.reset(); this.reset();
} }

View File

@ -32,6 +32,7 @@ function TcpConnection(log, connectionId, remoteEndPoint, onConnectionClosed) {
TcpConnection.prototype._initSocket = function(socket) { TcpConnection.prototype._initSocket = function(socket) {
this._socket = socket; this._socket = socket;
this._localEndPoint = {host: socket.localAddress, port: socket.localPort}; this._localEndPoint = {host: socket.localAddress, port: socket.localPort};
this._remoteEndPoint.host = socket.remoteAddress;
this._socket.on('error', this._processError.bind(this)); this._socket.on('error', this._processError.bind(this));
this._socket.on('data', this._processReceive.bind(this)); this._socket.on('data', this._processReceive.bind(this));
@ -120,13 +121,13 @@ TcpConnection.prototype._closeInternal = function(err, reason) {
if (this._closed) return; if (this._closed) return;
this._closed = true; this._closed = true;
if (this._socket != null) { if (this._socket !== null) {
this._socket.end(); this._socket.end();
this._socket.unref(); this._socket.unref();
this._socket = null; this._socket = null;
} }
if (this._onConnectionClosed != null) if (this._onConnectionClosed !== null)
this._onConnectionClosed(this, err); this._onConnectionClosed(this, err);
}; };

View File

@ -120,26 +120,26 @@ TcpPackageConnection.prototype._incomingMessageArrived = function(data) {
var message = util.format("TcpPackageConnection: [%j, L%j, %s] ERROR for %s. Connection will be closed.", var message = util.format("TcpPackageConnection: [%j, L%j, %s] ERROR for %s. Connection will be closed.",
this.remoteEndPoint, this.localEndPoint, this._connectionId, this.remoteEndPoint, this.localEndPoint, this._connectionId,
valid ? TcpCommand.getName(pkg.command) : "<invalid package>"); valid ? TcpCommand.getName(pkg.command) : "<invalid package>");
if (this._onError != null) if (this._onError !== null)
this._onError(this, e); this._onError(this, e);
this._log.debug(e, message); this._log.debug(e, message);
} }
}; };
TcpPackageConnection.prototype.startReceiving = function() { TcpPackageConnection.prototype.startReceiving = function() {
if (this._connection == null) if (this._connection === null)
throw new Error("Failed connection."); throw new Error("Failed connection.");
this._connection.receive(this._onRawDataReceived.bind(this)); this._connection.receive(this._onRawDataReceived.bind(this));
}; };
TcpPackageConnection.prototype.enqueueSend = function(pkg) { TcpPackageConnection.prototype.enqueueSend = function(pkg) {
if (this._connection == null) if (this._connection === null)
throw new Error("Failed connection."); throw new Error("Failed connection.");
this._connection.enqueueSend(this._framer.frameData(pkg.asBufferSegment())); this._connection.enqueueSend(this._framer.frameData(pkg.asBufferSegment()));
}; };
TcpPackageConnection.prototype.close = function(reason) { TcpPackageConnection.prototype.close = function(reason) {
if (this._connection == null) if (this._connection === null)
throw new Error("Failed connection."); throw new Error("Failed connection.");
this._connection.close(reason); this._connection.close(reason);
}; };

View File

@ -31,7 +31,7 @@ module.exports = {
test.done(err); test.done(err);
}); });
conn.on('connected', function () { conn.on('connected', function () {
test.fail("Should not be able to connect."); test.ok(false, "Should not be able to connect.");
test.done(); test.done();
}); });
conn.on('error', function (err) { conn.on('error', function (err) {
@ -41,7 +41,7 @@ module.exports = {
test.ok(reason.indexOf("Reconnection limit reached") === 0, "Wrong expected reason."); test.ok(reason.indexOf("Reconnection limit reached") === 0, "Wrong expected reason.");
test.done(); test.done();
}); });
}, }/*,
'Connect to Cluster using gossip seeds': function (test) { 'Connect to Cluster using gossip seeds': function (test) {
test.expect(1); test.expect(1);
var gossipSeeds = [ var gossipSeeds = [
@ -65,7 +65,7 @@ module.exports = {
if (err) return test.done(err); if (err) return test.done(err);
test.done(); test.done();
} }
} }*/
}; };
testBase.init(module.exports, false); testBase.init(module.exports, false);

View File

@ -7,7 +7,7 @@ function createRandomEvent() {
return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent'); return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent');
} }
var testStreamName = 'test' + uuid.v4(); var testStreamName = 'test-' + uuid.v4();
module.exports = { module.exports = {
'Test Create Persistent Subscription': function(test) { 'Test Create Persistent Subscription': function(test) {
@ -29,7 +29,6 @@ module.exports = {
test.done(error); test.done(error);
} }
var subscription = this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped); var subscription = this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped);
this.log.info('ABC', subscription);
this.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent()]); this.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent()]);
}, },
'Test Delete Persistent Subscription': function(test) { 'Test Delete Persistent Subscription': function(test) {