Fixed failing samples

Updated uuid/webpack packages
Added froze on objects publicly exposed
Removed remaining while loops for actions/events processing
This commit is contained in:
2017-04-16 12:51:17 -07:00
parent 56c2dee6d6
commit f7c13634cc
23 changed files with 363 additions and 411 deletions

View File

@ -6,10 +6,12 @@ const expectedVersion = {
noStream: -1,
emptyStream: -1
};
Object.freeze(expectedVersion);
const positions = {
start: new results.Position(0, 0),
end: new results.Position(-1, -1)
};
Object.freeze(positions);
/**
* Create an EventData object from JavaScript event/metadata that will be serialized as json

View File

@ -1,5 +1,5 @@
var util = require('util');
var uuid = require('uuid');
var uuidParse = require('uuid-parse');
var TcpCommand = require('../systemData/tcpCommand');
var InspectionDecision = require('../systemData/inspectionDecision');
@ -26,7 +26,7 @@ util.inherits(AppendToStreamOperation, OperationBase);
AppendToStreamOperation.prototype._createRequestDto = function() {
var dtos = this._events.map(function(ev) {
var eventId = new Buffer(uuid.parse(ev.eventId));
var eventId = new Buffer(uuidParse.parse(ev.eventId));
return new ClientMessage.NewEvent({
event_id: eventId, event_type: ev.type,
data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0,

View File

@ -1,5 +1,5 @@
var util = require('util');
var uuid = require('uuid');
var uuidParse = require('uuid-parse');
var SubscriptionOperation = require('./subscriptionOperation');
var ClientMessage = require('../messages/clientMessage');
@ -88,7 +88,7 @@ ConnectToPersistentSubscriptionOperation.prototype.notifyEventsProcessed = funct
var dto = new ClientMessage.PersistentSubscriptionAckEvents({
subscription_id: this._subscriptionId,
processed_event_ids: processedEvents.map(function (x) {
return new Buffer(uuid.parse(x));
return new Buffer(uuidParse.parse(x));
})
});
@ -106,7 +106,7 @@ ConnectToPersistentSubscriptionOperation.prototype.notifyEventsFailed = function
ensure.notNull(reason, "reason");
var dto = new ClientMessage.PersistentSubscriptionNakEvents(
this._subscriptionId,
processedEvents.map(function(x) { return new Buffer(uuid.parse(x)); }),
processedEvents.map(function(x) { return new Buffer(uuidParse.parse(x)); }),
reason,
action);

View File

@ -244,21 +244,20 @@ SubscriptionOperation.prototype._executeAction = function(action) {
};
SubscriptionOperation.prototype._executeActions = function() {
//TODO: possible blocking loop for node.js
var action = this._actionQueue.shift();
while (action)
{
try
{
action();
}
catch (err)
{
this._log.error(err, "Exception during executing user callback: %s.", err.message);
}
action = this._actionQueue.shift();
if (!action) {
this._actionExecuting = false;
return;
}
this._actionExecuting = false;
try
{
action();
}
catch (err)
{
this._log.error(err, "Exception during executing user callback: %s.", err.message);
}
setImmediate(this._executeActions.bind(this));
};
SubscriptionOperation.prototype.toString = function() {

View File

@ -1,5 +1,5 @@
var util = require('util');
var uuid = require('uuid');
var uuidParse = require('uuid-parse');
var TcpCommand = require('../systemData/tcpCommand');
var InspectionDecision = require('../systemData/inspectionDecision');
@ -22,7 +22,7 @@ util.inherits(TransactionalWriteOperation, OperationBase);
TransactionalWriteOperation.prototype._createRequestDto = function() {
var dtos = this._events.map(function(ev) {
var eventId = new Buffer(uuid.parse(ev.eventId));
var eventId = new Buffer(uuidParse.parse(ev.eventId));
return new ClientMessage.NewEvent({
event_id: eventId, event_type: ev.type,
data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0,

View File

@ -12,5 +12,6 @@ const SystemMetadata = {
userStreamAcl: '$userStreamAcl',
systemStreamAcl: '$systemStreamAcl'
};
Object.freeze(SystemMetadata);
module.exports = SystemMetadata;

View File

@ -8,11 +8,13 @@ function AccessDeniedError(action, streamOrTransactionId) {
if (typeof streamOrTransactionId === 'string') {
this.message = util.format("%s access denied for stream '%s'.", action, streamOrTransactionId);
this.stream = streamOrTransactionId;
Object.freeze(this);
return;
}
if (Long.isLong(streamOrTransactionId)) {
this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId);
this.transactionId = streamOrTransactionId;
Object.freeze(this);
return;
}
throw new TypeError("second argument must be a stream name or transaction Id.");

View File

@ -7,11 +7,13 @@ function StreamDeletedError(streamOrTransactionId) {
if (typeof streamOrTransactionId === 'string') {
this.message = util.format("Event stream '%s' is deleted.", streamOrTransactionId);
this.stream = streamOrTransactionId;
Object.freeze(this);
return;
}
if (Long.isLong(streamOrTransactionId)) {
this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId);
this.transactionId = streamOrTransactionId;
Object.freeze(this);
return;
}
throw new TypeError("second argument must be a stream name or transaction Id.");

View File

@ -9,11 +9,13 @@ function WrongExpectedVersionError(action, streamOrTransactionId, expectedVersio
this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, streamOrTransactionId, expectedVersion);
this.stream = streamOrTransactionId;
this.expectedVersion = expectedVersion;
Object.freeze(this);
return;
}
if (Long.isLong(streamOrTransactionId)) {
this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId);
this.transactionId = streamOrTransactionId;
Object.freeze(this);
return;
}
throw new TypeError("second argument must be a stream name or a transaction Id.");

View File

@ -1,13 +1,9 @@
var uuid = require('uuid');
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
function isValidId(id) {
if (typeof id !== 'string') return false;
var buf = uuid.parse(id);
var valid = false;
for(var i=0;i<buf.length;i++)
if (buf[i] !== 0)
valid = true;
return valid;
return uuidRegex.test(id);
}
/**
@ -32,6 +28,7 @@ function EventData(eventId, type, isJson, data, metadata) {
this.isJson = isJson || false;
this.data = data || new Buffer(0);
this.metadata = metadata || new Buffer(0);
Object.freeze(this);
}
module.exports = EventData;

View File

@ -209,26 +209,25 @@ EventStoreCatchUpSubscription.prototype._ensureProcessingPushQueue = function()
EventStoreCatchUpSubscription.prototype._processLiveQueue = function() {
var ev = this._liveQueue.shift();
//TODO: possible blocking while, use when
while(ev) {
if (ev instanceof DropSubscriptionEvent) {
if (!this._dropData) this._dropData = {reason: SubscriptionDropReason.Unknown, error: new Error("Drop reason not specified.")};
this._dropSubscription(this._dropData.reason, this._dropData.error);
this._isProcessing = false;
return;
}
try {
this._tryProcess(ev);
}
catch(err) {
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
return;
}
ev = this._liveQueue.shift();
if (!ev) {
this._isProcessing = false;
return;
}
this._isProcessing = false;
if (ev instanceof DropSubscriptionEvent) {
if (!this._dropData) this._dropData = {reason: SubscriptionDropReason.Unknown, error: new Error("Drop reason not specified.")};
this._dropSubscription(this._dropData.reason, this._dropData.error);
this._isProcessing = false;
return;
}
try {
this._tryProcess(ev);
}
catch(err) {
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
this._isProcessing = false;
return;
}
setImmediate(this._processLiveQueue.bind(this));
};
EventStoreCatchUpSubscription.prototype._dropSubscription = function(reason, error) {

View File

@ -111,42 +111,43 @@ EventStorePersistentSubscriptionBase.prototype._enqueue = function(resolvedEvent
};
EventStorePersistentSubscriptionBase.prototype._processQueue = function() {
//do
//{
var e = this._queue.shift();
while (e)
{
if (e instanceof DropSubscriptionEvent) // drop subscription artificial ResolvedEvent
{
if (this._dropData === null) throw new Error("Drop reason not specified.");
this._dropSubscription(this._dropData.reason, this._dropData.error);
return;
}
if (this._dropData !== null)
{
this._dropSubscription(this._dropData.reason, this._dropData.error);
return;
}
try
{
this._eventAppeared(this, e);
if(this._autoAck)
this._subscription.notifyEventsProcessed([e.originalEvent.eventId]);
if (this._verbose)
this._log.debug("Persistent Subscription to %s: processed event (%s, %d, %s @ %d).",
this._streamId, e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType,
e.originalEventNumber);
}
catch (err)
{
//TODO GFY should we autonak here?
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
return;
}
e = this._queue.shift();
}
var ev = this._queue.shift();
if (!ev) {
this._isProcessing = false;
//} while (_queue.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) === 0);
return;
}
if (ev instanceof DropSubscriptionEvent) // drop subscription artificial ResolvedEvent
{
if (this._dropData === null) throw new Error("Drop reason not specified.");
this._dropSubscription(this._dropData.reason, this._dropData.error);
this._isProcessing = false;
return;
}
if (this._dropData !== null)
{
this._dropSubscription(this._dropData.reason, this._dropData.error);
this._isProcessing = false;
return;
}
try
{
this._eventAppeared(this, ev);
if(this._autoAck)
this._subscription.notifyEventsProcessed([ev.originalEvent.eventId]);
if (this._verbose)
this._log.debug("Persistent Subscription to %s: processed event (%s, %d, %s @ %d).",
this._streamId, ev.originalEvent.eventStreamId, ev.originalEvent.eventNumber, ev.originalEvent.eventType,
ev.originalEventNumber);
}
catch (err)
{
//TODO GFY should we autonak here?
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
this._isProcessing = false;
return;
}
setImmediate(this._processQueue.bind(this));
};
EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) {

View File

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

View File

@ -1,5 +1,5 @@
var util = require('util');
var uuid = require('uuid');
var uuidParse = require('uuid-parse');
var Long = require('long');
var ensure = require('./common/utils/ensure');
@ -14,17 +14,9 @@ var ensure = require('./common/utils/ensure');
function Position(commitPosition, preparePosition) {
ensure.notNull(commitPosition, "commitPosition");
ensure.notNull(preparePosition, "preparePosition");
commitPosition = Long.fromValue(commitPosition);
preparePosition = Long.fromValue(preparePosition);
Object.defineProperties(this, {
commitPosition: {
enumerable: true, value: commitPosition
},
preparePosition: {
enumerable: true, value: preparePosition
}
});
this.commitPosition = Long.fromValue(commitPosition);
this.preparePosition = Long.fromValue(preparePosition);
Object.freeze(this);
}
Position.prototype.compareTo = function(other) {
@ -46,6 +38,7 @@ const EventReadStatus = {
NoStream: 'noStream',
StreamDeleted: 'streamDeleted'
};
Object.freeze(EventReadStatus);
/**
* @param {object} ev
@ -60,18 +53,16 @@ const EventReadStatus = {
* @property {boolean} isJson
*/
function RecordedEvent(ev) {
Object.defineProperties(this, {
eventStreamId: {enumerable: true, value: ev.event_stream_id},
eventId: {enumerable: true, value: uuid.unparse(ev.event_id.buffer, ev.event_id.offset)},
eventNumber: {enumerable: true, value: ev.event_number},
eventType: {enumerable: true, value: ev.event_type},
//Javascript doesn't have .Net precision for time, so we use created_epoch for created
created: {enumerable: true, value: new Date(ev.created_epoch ? ev.created_epoch.toNumber() : 0)},
createdEpoch: {enumerable: true, value: ev.created_epoch ? ev.created_epoch.toNumber() : 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)},
isJson: {enumerable: true, value: ev.data_content_type === 1}
});
this.eventStreamId = ev.event_stream_id;
this.eventId = uuidParse.unparse(ev.event_id.buffer, ev.event_id.offset);
this.eventNumber = ev.event_number;
this.eventType = ev.event_type;
this.created = new Date(ev.created_epoch ? ev.created_epoch.toNumber() : 0);
this.createdEpoch = ev.created_epoch ? ev.created_epoch.toNumber() : 0;
this.data = ev.data ? ev.data.toBuffer() : new Buffer(0);
this.metadata = ev.metadata ? ev.metadata.toBuffer() : new Buffer(0);
this.isJson = ev.data_content_type === 1;
Object.freeze(this);
}
/**
@ -86,44 +77,14 @@ function RecordedEvent(ev) {
* @property {number} originalEventNumber
*/
function ResolvedEvent(ev) {
Object.defineProperties(this, {
event: {
enumerable: true,
value: ev.event === null ? null : new RecordedEvent(ev.event)
},
link: {
enumerable: true,
value: ev.link === null ? null : new RecordedEvent(ev.link)
},
originalEvent: {
enumerable: true,
get: function() {
return this.link || this.event;
}
},
isResolved: {
enumerable: true,
get: function() {
return this.link !== null && this.event !== null;
}
},
originalPosition: {
enumerable: true,
value: (ev.commit_position && ev.prepare_position) ? new Position(ev.commit_position, ev.prepare_position) : null
},
originalStreamId: {
enumerable: true,
get: function() {
return this.originalEvent.eventStreamId;
}
},
originalEventNumber: {
enumerable: true,
get: function() {
return this.originalEvent.eventNumber;
}
}
});
this.event = ev.event === null ? null : new RecordedEvent(ev.event);
this.link = ev.link === null ? null : new RecordedEvent(ev.link);
this.originalEvent = this.link || this.event;
this.isResolved = this.link !== null && this.event !== null;
this.originalPosition = (ev.commit_position && ev.prepare_position) ? new Position(ev.commit_position, ev.prepare_position) : null;
this.originalStreamId = this.originalEvent && this.originalEvent.eventStreamId;
this.originalEventNumber = this.originalEvent && this.originalEvent.eventNumber;
Object.freeze(this);
}
/**
@ -139,14 +100,11 @@ function ResolvedEvent(ev) {
* @property {ResolvedEvent} event
*/
function EventReadResult(status, stream, eventNumber, event) {
Object.defineProperties(this, {
status: {enumerable: true, value: status},
stream: {enumerable: true, value: stream},
eventNumber: {enumerable: true, value: eventNumber},
event: {
enumerable: true, value: status === EventReadStatus.Success ? new ResolvedEvent(event) : null
}
});
this.status = status;
this.stream = stream;
this.eventNumber = eventNumber;
this.event = status === EventReadStatus.Success ? new ResolvedEvent(event) : null;
Object.freeze(this);
}
/**
@ -157,14 +115,9 @@ function EventReadResult(status, stream, eventNumber, event) {
* @property {Position} logPosition
*/
function WriteResult(nextExpectedVersion, logPosition) {
Object.defineProperties(this, {
nextExpectedVersion: {
enumerable: true, value: nextExpectedVersion
},
logPosition: {
enumerable: true, value: logPosition
}
});
this.nextExpectedVersion = nextExpectedVersion;
this.logPosition = logPosition;
Object.freeze(this);
}
/**
@ -189,32 +142,15 @@ function WriteResult(nextExpectedVersion, logPosition) {
function StreamEventsSlice(
status, stream, fromEventNumber, readDirection, events, nextEventNumber, lastEventNumber, isEndOfStream
) {
Object.defineProperties(this, {
status: {
enumerable: true, value: status
},
stream: {
enumerable: true, value: stream
},
fromEventNumber: {
enumerable: true, value: fromEventNumber
},
readDirection: {
enumerable: true, value: readDirection
},
events: {
enumerable: true, value: events ? events.map(function(ev) { return new ResolvedEvent(ev); }) : []
},
nextEventNumber: {
enumerable: true, value: nextEventNumber
},
lastEventNumber: {
enumerable: true, value: lastEventNumber
},
isEndOfStream: {
enumerable: true, value: isEndOfStream
}
})
this.status = status;
this.stream = stream;
this.fromEventNumber = fromEventNumber;
this.readDirection = readDirection;
this.events = events ? events.map(function(ev) { return new ResolvedEvent(ev); }) : [];
this.nextEventNumber = nextEventNumber;
this.lastEventNumber = lastEventNumber;
this.isEndOfStream = isEndOfStream;
Object.freeze(this);
}
/**
@ -229,23 +165,12 @@ function StreamEventsSlice(
* @property {ResolvedEvent[]} events
*/
function AllEventsSlice(readDirection, fromPosition, nextPosition, events) {
Object.defineProperties(this, {
readDirection: {
enumerable: true, value: readDirection
},
fromPosition: {
enumerable: true, value: fromPosition
},
nextPosition: {
enumerable: true, value: nextPosition
},
events: {
enumerable: true, value: events ? events.map(function(ev){ return new ResolvedEvent(ev); }) : []
},
isEndOfStream: {
enumerable: true, value: events === null || events.length === 0
}
});
this.readDirection = readDirection;
this.fromPosition = fromPosition;
this.nextPosition = nextPosition;
this.events = events ? events.map(function(ev){ return new ResolvedEvent(ev); }) : [];
this.isEndOfStream = events === null || events.length === 0;
Object.freeze(this);
}
/**
@ -254,11 +179,8 @@ function AllEventsSlice(readDirection, fromPosition, nextPosition, events) {
* @property {Position} logPosition
*/
function DeleteResult(logPosition) {
Object.defineProperties(this, {
logPosition: {
enumerable: true, value: logPosition
}
});
this.logPosition = logPosition;
Object.freeze(this);
}
/**
@ -274,12 +196,11 @@ function DeleteResult(logPosition) {
*/
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
ensure.notNullOrEmpty(stream);
Object.defineProperties(this, {
stream: {enumerable: true, value: stream},
isStreamDeleted: {enumerable: true, value: isStreamDeleted},
metastreamVersion: {enumerable: true, value: metastreamVersion},
streamMetadata: {enumerable: true, value: streamMetadata}
});
this.stream = stream;
this.isStreamDeleted = isStreamDeleted;
this.metastreamVersion = metastreamVersion;
this.streamMetadata = streamMetadata;
Object.freeze(this);
}
const PersistentSubscriptionCreateStatus = {
@ -287,6 +208,7 @@ const PersistentSubscriptionCreateStatus = {
NotFound: 'notFound',
Failure: 'failure'
};
Object.freeze(PersistentSubscriptionCreateStatus);
/**
* @param {string} status
@ -294,9 +216,8 @@ const PersistentSubscriptionCreateStatus = {
* @property {string} status
*/
function PersistentSubscriptionCreateResult(status) {
Object.defineProperties(this, {
status: {enumerable: true, value: status}
});
this.status = status;
Object.freeze(this);
}
const PersistentSubscriptionUpdateStatus = {
@ -305,6 +226,7 @@ const PersistentSubscriptionUpdateStatus = {
Failure: 'failure',
AccessDenied: 'accessDenied'
};
Object.freeze(PersistentSubscriptionUpdateStatus);
/**
* @param {string} status
@ -312,15 +234,15 @@ const PersistentSubscriptionUpdateStatus = {
* @property {string} status
*/
function PersistentSubscriptionUpdateResult(status) {
Object.defineProperties(this, {
status: {enumerable: true, value: status}
});
this.status = status;
Object.freeze(this);
}
const PersistentSubscriptionDeleteStatus = {
Success: 'success',
Failure: 'failure'
};
Object.freeze(PersistentSubscriptionDeleteStatus);
/**
* @param {string} status
@ -328,9 +250,8 @@ const PersistentSubscriptionDeleteStatus = {
* @property {string} status
*/
function PersistentSubscriptionDeleteResult(status) {
Object.defineProperties(this, {
status: {enumerable: true, value: status}
});
this.status = status;
Object.freeze(this);
}
// Exports Constructors

View File

@ -3,5 +3,6 @@ const SliceReadStatus = {
StreamNotFound: 'streamNotFound',
StreamDeleted: 'streamDeleted'
};
Object.freeze(SliceReadStatus);
module.exports = SliceReadStatus;

View File

@ -3,5 +3,6 @@ const SystemConsumerStrategies = {
RoundRobin: 'RoundRobin',
Pinned: 'Pinned'
};
Object.freeze(SystemConsumerStrategies);
module.exports = SystemConsumerStrategies;

View File

@ -1,4 +1,4 @@
var uuid = require('uuid');
var uuidParse = require('uuid-parse');
var createBufferSegment = require('../common/bufferSegment');
var TcpFlags = require('./tcpFlags');
@ -25,7 +25,7 @@ TcpPackage.fromBufferSegment = function(data) {
var command = data.buffer[data.offset + CommandOffset];
var flags = data.buffer[data.offset + FlagsOffset];
var correlationId = uuid.unparse(data.buffer, data.offset + CorrelationOffset);
var correlationId = uuidParse.unparse(data.buffer, data.offset + CorrelationOffset);
var headerSize = MandatorySize;
var login = null, pass = null;
@ -57,7 +57,7 @@ TcpPackage.prototype.asBuffer = function() {
var res = new Buffer(MandatorySize + 2 + loginBytes.length + passwordBytes.length + (this.data ? this.data.count : 0));
res[CommandOffset] = this.command;
res[FlagsOffset] = this.flags;
uuid.parse(this.correlationId, res, CorrelationOffset);
uuidParse.parse(this.correlationId, res, CorrelationOffset);
res[AuthOffset] = loginBytes.length;
loginBytes.copy(res, AuthOffset + 1);
@ -72,7 +72,7 @@ TcpPackage.prototype.asBuffer = function() {
var res = new Buffer(MandatorySize + (this.data ? this.data.count : 0));
res[CommandOffset] = this.command;
res[FlagsOffset] = this.flags;
uuid.parse(this.correlationId, res, CorrelationOffset);
uuidParse.parse(this.correlationId, res, CorrelationOffset);
if (this.data)
this.data.copyTo(res, AuthOffset);
return res;

View File

@ -10,11 +10,9 @@ var ensure = require('../common/utils/ensure');
function UserCredentials(username, password) {
ensure.notNullOrEmpty(username, 'username');
ensure.notNullOrEmpty(password, 'password');
Object.defineProperties(this, {
username: {enumerable: true, value: username},
password: {enumerable: true, value: password}
});
this.username = username;
this.password = password;
Object.freeze(this);
}
module.exports = UserCredentials;