Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
e79ad8f9c4 | |||
4584517ede | |||
e6af223f0d | |||
990351738c | |||
18e35c56f9 | |||
20de4c3715 | |||
60d2a1e5ee | |||
a8081a280a | |||
7c94e26055 | |||
0b968c40e8 | |||
21ab49845f | |||
6634dee5f3 | |||
1d21facd2c | |||
8735b23bf9 | |||
f66decdfb3 | |||
121e248dd8 | |||
917b89cf3d | |||
a1b9d6db9b | |||
83b88fc015 | |||
4130ab646c | |||
83cfa8fe1c | |||
e0446cfb3e | |||
0302099a16 | |||
f7c13634cc | |||
56c2dee6d6 | |||
85814ed03f | |||
361330629d | |||
883e89abfe | |||
e39280a2dc | |||
05b36f22bc | |||
217c1c6bb8 | |||
eaec15fe74 | |||
d71d565197 | |||
9e29e60cfa |
14
README.md
14
README.md
@ -1,4 +1,4 @@
|
|||||||
# eventstore-node
|
# node-eventstore-client
|
||||||
A port of the EventStore .Net ClientAPI to Node.js
|
A port of the EventStore .Net ClientAPI to Node.js
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
@ -19,7 +19,7 @@ A port of the EventStore .Net ClientAPI to Node.js
|
|||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Install using `npm install eventstore-node`
|
Install using `npm install node-eventstore-client`
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
@ -30,11 +30,11 @@ Install using `npm install eventstore-node`
|
|||||||
|
|
||||||
#### Offline
|
#### Offline
|
||||||
|
|
||||||
The offline documentation can be found in the module folder `./node_modules/eventstore-node/docs`.
|
The offline documentation can be found in the module folder `./node_modules/node-eventstore-client/docs`.
|
||||||
|
|
||||||
#### Online
|
#### Online
|
||||||
|
|
||||||
The online documentation can be found at [https://dev.nicdex.com/eventstore-node/docs/](https://dev.nicdex.com/eventstore-node/docs/)
|
The online documentation can be found at [https://dev.nicdex.com/node-eventstore-client/docs/](https://dev.nicdex.com/node-eventstore-client/docs/)
|
||||||
|
|
||||||
### Install & run an Eventstore on localhost
|
### Install & run an Eventstore on localhost
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ See http://docs.geteventstore.com/introduction/3.9.0/ .
|
|||||||
Save to ```app.js:```
|
Save to ```app.js:```
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var esClient = require('eventstore-node');
|
var esClient = require('node-eventstore-client');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
|
|
||||||
var streamName = "testStream";
|
var streamName = "testStream";
|
||||||
@ -88,7 +88,7 @@ Run:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
npm install uuid
|
npm install uuid
|
||||||
npm install eventstore-node
|
npm install node-eventstore-client
|
||||||
node app.js
|
node app.js
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -125,6 +125,6 @@ Any async commands returns a [Promise](https://developer.mozilla.org/en/docs/Web
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Ported code is released under the MIT license, see [LICENSE](https://github.com/nicdex/eventstore-node/blob/master/LICENSE).
|
Ported code is released under the MIT license, see [LICENSE](https://github.com/nicdex/node-eventstore-client/blob/master/LICENSE).
|
||||||
|
|
||||||
Original code is released under the EventStore license and can be found at https://github.com/eventstore/eventstore.
|
Original code is released under the EventStore license and can be found at https://github.com/eventstore/eventstore.
|
||||||
|
92
index.d.ts
vendored
92
index.d.ts
vendored
@ -16,11 +16,11 @@ export class UserCredentials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PersistentSubscriptionSettings {
|
export class PersistentSubscriptionSettings {
|
||||||
constructor(resolveLinkTos: boolean, startFrom: number, extraStatistics: boolean, messageTimeout: number,
|
constructor(resolveLinkTos: boolean, startFrom: Long|number, extraStatistics: boolean, messageTimeout: number,
|
||||||
maxRetryCount: number, liveBufferSize: number, readBatchSize: number, historyBufferSize: number,
|
maxRetryCount: number, liveBufferSize: number, readBatchSize: number, historyBufferSize: number,
|
||||||
checkPointAfter: number, minCheckPointCount: number, maxCheckPointCount: number,
|
checkPointAfter: number, minCheckPointCount: number, maxCheckPointCount: number,
|
||||||
maxSubscriberCount: number, namedConsumerStrategy: string)
|
maxSubscriberCount: number, namedConsumerStrategy: string)
|
||||||
static create();
|
static create(): PersistentSubscriptionSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace SystemConsumerStrategies {
|
export namespace SystemConsumerStrategies {
|
||||||
@ -41,7 +41,7 @@ export class WrongExpectedVersionError {
|
|||||||
readonly action: string;
|
readonly action: string;
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly stream?: string;
|
readonly stream?: string;
|
||||||
readonly expectedVersion?: number;
|
readonly expectedVersion?: Long;
|
||||||
readonly transactionId?: Long;
|
readonly transactionId?: Long;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,17 +98,16 @@ export class FileLogger implements Logger {
|
|||||||
error(fmt: string, ...args: any[]): void;
|
error(fmt: string, ...args: any[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Expose results
|
||||||
|
|
||||||
export interface WriteResult {
|
export interface WriteResult {
|
||||||
readonly nextExpectedVersion: number;
|
readonly nextExpectedVersion: Long;
|
||||||
readonly logPosition: Position;
|
readonly logPosition: Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecordedEvent {
|
export interface RecordedEvent {
|
||||||
readonly eventStreamId: string;
|
readonly eventStreamId: string;
|
||||||
readonly eventId: string;
|
readonly eventId: string;
|
||||||
readonly eventNumber: number;
|
readonly eventNumber: Long;
|
||||||
readonly eventType: string;
|
readonly eventType: string;
|
||||||
readonly createdEpoch: number;
|
readonly createdEpoch: number;
|
||||||
readonly data?: Buffer;
|
readonly data?: Buffer;
|
||||||
@ -123,17 +122,17 @@ export interface ResolvedEvent {
|
|||||||
readonly isResolved: boolean;
|
readonly isResolved: boolean;
|
||||||
readonly originalPosition?: Position;
|
readonly originalPosition?: Position;
|
||||||
readonly originalStreamId: string;
|
readonly originalStreamId: string;
|
||||||
readonly originalEventNumber: number;
|
readonly originalEventNumber: Long;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamEventsSlice {
|
export interface StreamEventsSlice {
|
||||||
readonly status: string; // TODO: enum
|
readonly status: string; // TODO: enum
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly fromEventNumber: number;
|
readonly fromEventNumber: Long;
|
||||||
readonly readDirection: string; // TODO: enum
|
readonly readDirection: string; // TODO: enum
|
||||||
readonly events: ResolvedEvent[];
|
readonly events: ResolvedEvent[];
|
||||||
readonly nextEventNumber: number;
|
readonly nextEventNumber: Long;
|
||||||
readonly lastEventNumber: number;
|
readonly lastEventNumber: Long;
|
||||||
readonly isEndOfStream: boolean;
|
readonly isEndOfStream: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ export interface EventStoreTransaction {
|
|||||||
export interface EventReadResult {
|
export interface EventReadResult {
|
||||||
readonly status: string;
|
readonly status: string;
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly eventNumber: number;
|
readonly eventNumber: Long;
|
||||||
readonly event: ResolvedEvent | null;
|
readonly event: ResolvedEvent | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,27 +166,52 @@ export interface EventStoreSubscription {
|
|||||||
readonly isSubscribedToAll: boolean;
|
readonly isSubscribedToAll: boolean;
|
||||||
readonly streamId: string;
|
readonly streamId: string;
|
||||||
readonly lastCommitPosition: Position;
|
readonly lastCommitPosition: Position;
|
||||||
readonly lastEventNumber: number;
|
readonly lastEventNumber: Long;
|
||||||
|
|
||||||
close(): void;
|
close(): void;
|
||||||
unsubscribe(): void;
|
unsubscribe(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventStoreCatchUpSubscription {
|
export interface EventStoreCatchUpSubscription {
|
||||||
start(): void;
|
stop(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PersistentSubscriptionNakEventAction {
|
||||||
|
Unknown = 0,
|
||||||
|
Park = 1,
|
||||||
|
Retry = 2,
|
||||||
|
Skip = 3,
|
||||||
|
Stop = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventStorePersistentSubscription {
|
||||||
|
acknowledge(events: ResolvedEvent | ResolvedEvent[]): void;
|
||||||
|
fail(events: ResolvedEvent | ResolvedEvent[], action: PersistentSubscriptionNakEventAction, reason: string): void;
|
||||||
stop(): void;
|
stop(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RawStreamMetadataResult {
|
export interface RawStreamMetadataResult {
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly isStreamDeleted: boolean;
|
readonly isStreamDeleted: boolean;
|
||||||
readonly metastreamVersion: number;
|
readonly metastreamVersion: Long;
|
||||||
readonly streamMetadata: any;
|
readonly streamMetadata: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PersistentSubscriptionCreateResult {
|
||||||
|
readonly status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PersistentSubscriptionUpdateResult {
|
||||||
|
readonly status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PersistentSubscriptionDeleteResult {
|
||||||
|
readonly status: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
export interface EventAppearedCallback<TSubscription> {
|
export interface EventAppearedCallback<TSubscription> {
|
||||||
(subscription: TSubscription, event: ResolvedEvent): void;
|
(subscription: TSubscription, event: ResolvedEvent): void | Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LiveProcessingStartedCallback {
|
export interface LiveProcessingStartedCallback {
|
||||||
@ -203,6 +227,15 @@ export interface TcpEndPoint {
|
|||||||
host: string;
|
host: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HeartbeatInfo {
|
||||||
|
connectionId: string;
|
||||||
|
remoteEndPoint: TcpEndPoint;
|
||||||
|
requestSentAt: number;
|
||||||
|
requestPkgNumber: number;
|
||||||
|
responseReceivedAt: number;
|
||||||
|
responsePkgNumber: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EventData {
|
export interface EventData {
|
||||||
readonly eventId: string;
|
readonly eventId: string;
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
@ -215,27 +248,32 @@ export interface EventStoreNodeConnection {
|
|||||||
connect(): Promise<void>;
|
connect(): Promise<void>;
|
||||||
close(): void;
|
close(): void;
|
||||||
// write actions
|
// write actions
|
||||||
deleteStream(stream: string, expectedVersion: number, hardDelete?: boolean, userCredentials?: UserCredentials): Promise<DeleteResult>;
|
deleteStream(stream: string, expectedVersion: Long|number, hardDelete?: boolean, userCredentials?: UserCredentials): Promise<DeleteResult>;
|
||||||
appendToStream(stream: string, expectedVersion: number, eventOrEvents: EventData | EventData[], userCredentials?: UserCredentials): Promise<WriteResult>;
|
appendToStream(stream: string, expectedVersion: Long|number, eventOrEvents: EventData | EventData[], userCredentials?: UserCredentials): Promise<WriteResult>;
|
||||||
startTransaction(stream: string, expectedVersion: number, userCredentials?: UserCredentials): Promise<EventStoreTransaction>;
|
startTransaction(stream: string, expectedVersion: Long|number, userCredentials?: UserCredentials): Promise<EventStoreTransaction>;
|
||||||
continueTransaction(transactionId: number, userCredentials?: UserCredentials): EventStoreTransaction;
|
continueTransaction(transactionId: number, userCredentials?: UserCredentials): EventStoreTransaction;
|
||||||
// read actions
|
// read actions
|
||||||
readEvent(stream: string, eventNumber: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<EventReadResult>;
|
readEvent(stream: string, eventNumber: Long|number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<EventReadResult>;
|
||||||
readStreamEventsForward(stream: string, start: number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
readStreamEventsForward(stream: string, start: Long|number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
||||||
readStreamEventsBackward(stream: string, start: number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
readStreamEventsBackward(stream: string, start: Long|number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
||||||
readAllEventsForward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
readAllEventsForward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
||||||
readAllEventsBackward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
readAllEventsBackward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
||||||
// subscription actions
|
// subscription actions
|
||||||
subscribeToStream(stream: string, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
subscribeToStream(stream: string, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
||||||
subscribeToStreamFrom(stream: string, lastCheckpoint: number | null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
subscribeToStreamFrom(stream: string, lastCheckpoint: Long|number|null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
||||||
subscribeToAll(resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
subscribeToAll(resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
||||||
subscribeToAllFrom(lastCheckpoint: Position | null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
subscribeToAllFrom(lastCheckpoint: Position|null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
||||||
|
// persistent subscriptions
|
||||||
|
createPersistentSubscription(stream: string, groupName: string, settings: PersistentSubscriptionSettings, userCredentials?: PersistentSubscriptionSettings): Promise<PersistentSubscriptionCreateResult>;
|
||||||
|
updatePersistentSubscription(stream: string, groupName: string, settings: PersistentSubscriptionSettings, userCredentials?: PersistentSubscriptionSettings): Promise<PersistentSubscriptionUpdateResult>;
|
||||||
|
deletePersistentSubscription(stream: string, groupName: string, userCredentials?: PersistentSubscriptionSettings): Promise<PersistentSubscriptionDeleteResult>
|
||||||
|
connectToPersistentSubscription(stream: string, groupName: string, eventAppeared: EventAppearedCallback<EventStorePersistentSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStorePersistentSubscription>, userCredentials?: UserCredentials, bufferSize?: number, autoAck?: boolean): Promise<EventStorePersistentSubscription>;
|
||||||
// metadata actions
|
// metadata actions
|
||||||
setStreamMetadataRaw(stream: string, expectedMetastreamVersion: number, metadata: any, userCredentials?: UserCredentials): Promise<WriteResult>;
|
setStreamMetadataRaw(stream: string, expectedMetastreamVersion: Long|number, metadata: any, userCredentials?: UserCredentials): Promise<WriteResult>;
|
||||||
getStreamMetadataRaw(stream: string, userCredentials?: UserCredentials): Promise<RawStreamMetadataResult>;
|
getStreamMetadataRaw(stream: string, userCredentials?: UserCredentials): Promise<RawStreamMetadataResult>;
|
||||||
|
|
||||||
on(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error", listener: (arg: Error | string | TcpEndPoint) => void): this;
|
on(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error" | "heartbeatInfo", listener: (arg: Error | string | TcpEndPoint | HeartbeatInfo) => void): this;
|
||||||
once(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error", listener: (arg: Error | string | TcpEndPoint) => void): this;
|
once(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error" | "heartbeatInfo", listener: (arg: Error | string | TcpEndPoint | HeartbeatInfo) => void): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose helper functions
|
// Expose helper functions
|
||||||
|
2
index.js
2
index.js
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* eventstore-node A port of EventStore .Net ClientAPI to Node.js
|
* node-eventstore-client A port of EventStore .Net ClientAPI to Node.js
|
||||||
* see README.md for more details
|
* see README.md for more details
|
||||||
* see LICENSE for license info
|
* see LICENSE for license info
|
||||||
*/
|
*/
|
||||||
|
20
package.json
20
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eventstore-node",
|
"name": "node-eventstore-client",
|
||||||
"version": "0.0.28",
|
"version": "0.2.0",
|
||||||
"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",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nicdex/eventstore-node.git"
|
"url": "git+https://github.com/nicdex/node-eventstore-client.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"eventstore",
|
"eventstore",
|
||||||
@ -37,19 +37,19 @@
|
|||||||
"author": "Nicolas Dextraze",
|
"author": "Nicolas Dextraze",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nicdex/eventstore-node/issues"
|
"url": "https://github.com/nicdex/node-eventstore-client/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/nicdex/eventstore-node#readme",
|
"homepage": "https://github.com/nicdex/node-eventstore-client#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/long": "^3.0.31",
|
"@types/long": "^3.0.31",
|
||||||
"@types/node": "^6.0.47",
|
"@types/node": "^6.0.47",
|
||||||
"long": "^3.2",
|
"long": "^3.2",
|
||||||
"protobufjs": "^5.0",
|
"protobufjs": "^6.7.3",
|
||||||
"uuid": "^2.0"
|
"uuid": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jsdoc": "^3.4.2",
|
"jsdoc": "^3.5.3",
|
||||||
"nodeunit": "^0.10.2",
|
"nodeunit": "^0.11.1",
|
||||||
"webpack": "^1.13.2"
|
"webpack": "^3.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,55 @@
|
|||||||
var client = require('../src/client');
|
const client = require('../src/client')
|
||||||
var uuid = require('uuid');
|
// const client = require("node-eventstore-client")
|
||||||
|
const uuid = require("uuid")
|
||||||
|
|
||||||
var settings = {
|
const settings = {
|
||||||
verboseLogging: true,
|
verboseLogging: true,
|
||||||
log: new client.FileLogger('./simple-verbose.log')
|
log: new client.FileLogger("./simple-verbose.log")
|
||||||
};
|
}
|
||||||
var gossipSeeds = [
|
/*
|
||||||
new client.GossipSeed({host: '192.168.33.10', port: 2113}),
|
// connecting to Cluster using hard-coded gossip seeds
|
||||||
new client.GossipSeed({host: '192.168.33.11', port: 2113}),
|
const gossipSeeds = [
|
||||||
new client.GossipSeed({host: '192.168.33.12', port: 2113})
|
new client.GossipSeed({host: "192.168.33.10", port: 2113}),
|
||||||
];
|
new client.GossipSeed({host: "192.168.33.11", port: 2113}),
|
||||||
var conn = client.createConnection(settings, gossipSeeds);
|
new client.GossipSeed({host: "192.168.33.12", port: 2113})
|
||||||
conn.connect()
|
]
|
||||||
.catch(function (err) {
|
const connection = client.createConnection(settings, gossipSeeds)
|
||||||
console.log(err);
|
*/
|
||||||
//process.exit(-1);
|
/*
|
||||||
});
|
// connecting to Cluster using dns discovery, note that cluster gossip over external http port not tcp port
|
||||||
conn.on('connected', function (endPoint) {
|
const connection = client.createConnection(settings, 'discover://my.dns:2113')
|
||||||
console.log('connected to endPoint', endPoint);
|
*/
|
||||||
//Start some work
|
const connection = client.createConnection(settings, 'tcp://localhost:1113')
|
||||||
setInterval(function () {
|
|
||||||
conn.appendToStream('test-' + uuid.v4(), client.expectedVersion.noStream, [
|
connection.connect().catch(err => console.log(err))
|
||||||
client.createJsonEventData(uuid.v4(), {abc: 123}, null, 'MyEvent')
|
|
||||||
]).then(function (writeResult) {
|
connection.on("connected", tcpEndPoint => {
|
||||||
console.log(writeResult);
|
console.log(`connected to endPoint ${tcpEndPoint.host}:${tcpEndPoint.port}`)
|
||||||
});
|
|
||||||
}, 1000);
|
setInterval(() => {
|
||||||
});
|
connection.appendToStream(
|
||||||
conn.on('error', function (err) {
|
`test-${uuid.v4()}`,
|
||||||
console.log('Error occurred on connection:', err);
|
client.expectedVersion.noStream,
|
||||||
});
|
[
|
||||||
conn.on('closed', function (reason) {
|
client.createJsonEventData(
|
||||||
console.log('Connection closed, reason:', reason);
|
uuid.v4(),
|
||||||
//process.exit(-1);
|
{ abc: 123 },
|
||||||
});
|
null,
|
||||||
process.stdin.setRawMode(true);
|
"MyEvent"
|
||||||
process.stdin.resume();
|
)
|
||||||
process.stdin.on('data', process.exit.bind(process, 0));
|
]
|
||||||
|
).then(writeResult => console.log(writeResult))
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
connection.on("error", error =>
|
||||||
|
console.log(`Error occurred on connection: ${error}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
connection.on("closed", reason =>
|
||||||
|
console.log(`Connection closed, reason: ${reason}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
process.stdin.setRawMode(true)
|
||||||
|
process.stdin.resume()
|
||||||
|
process.stdin.on("data", process.exit.bind(process, 0))
|
||||||
|
108
samples/speed-tests.js
Normal file
108
samples/speed-tests.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
//NOTE: this script require node.js v8+ to run (native async/await)
|
||||||
|
var uuid = require('uuid');
|
||||||
|
var client = require('../src/client');
|
||||||
|
var conn = client.createConnection({}, 'tcp://localhost:1113');
|
||||||
|
conn.on('connected', onConnected);
|
||||||
|
|
||||||
|
var batchSize = parseInt(process.argv[2], 10) || 500;
|
||||||
|
const MB = 1024*1024;
|
||||||
|
const adminCreds = new client.UserCredentials("admin", "changeit");
|
||||||
|
const nbEvents = 50000;
|
||||||
|
const events = [];
|
||||||
|
const streams = [];
|
||||||
|
const writeOneStream = 'testWrite-' + uuid.v4();
|
||||||
|
for(var i = 0; i < nbEvents; i++) {
|
||||||
|
streams.push('testWrite-' + uuid.v4());
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {a:i, b:i+1, c:i+2}, null, 'myEvent'))
|
||||||
|
}
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
function rssMB() {
|
||||||
|
return (process.memoryUsage().rss / MB).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportResult(action, nbEvents, elapsedMs) {
|
||||||
|
console.log(action, nbEvents, 'events took', elapsedMs, 'ms, avg', (nbEvents/(elapsedMs/1000)).toFixed(2), '/s');
|
||||||
|
console.log('Memory usage:', rssMB(), 'MB\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testWriteOneStreamAnyVersion(batchSize) {
|
||||||
|
console.log(`Test Write One Stream Any Version (batchSize = ${batchSize})...`);
|
||||||
|
const start = Date.now();
|
||||||
|
const promises = [];
|
||||||
|
for(let i = 0; i < nbEvents; i += batchSize) {
|
||||||
|
promises.push(conn.appendToStream(writeOneStream, client.expectedVersion.any, events.slice(i, i + batchSize)))
|
||||||
|
}
|
||||||
|
await Promise.all(promises);
|
||||||
|
var diff = Date.now() - start;
|
||||||
|
reportResult("Writing", nbEvents, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testWriteOneStreamWithVersion(batchSize) {
|
||||||
|
console.log(`Test Write One Stream With Version (batchSize = ${batchSize})...`);
|
||||||
|
const writeStream = 'testWrite-' + uuid.v4();
|
||||||
|
const start = Date.now();
|
||||||
|
const promises = [];
|
||||||
|
for(let i = 0; i < nbEvents; i += batchSize) {
|
||||||
|
promises.push(conn.appendToStream(writeStream, i-1, events.slice(i, i + batchSize)))
|
||||||
|
}
|
||||||
|
await Promise.all(promises);
|
||||||
|
var diff = Date.now() - start;
|
||||||
|
reportResult("Writing", nbEvents, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testWriteMultipleStream() {
|
||||||
|
console.log('Test Write Multiple Streams...');
|
||||||
|
var start = Date.now();
|
||||||
|
var promises = [];
|
||||||
|
for(var i = 0; i < nbEvents; i++) {
|
||||||
|
promises.push(conn.appendToStream(streams[i], client.expectedVersion.emptyStream, events[i]))
|
||||||
|
}
|
||||||
|
await Promise.all(promises);
|
||||||
|
const diff = Date.now() - start;
|
||||||
|
reportResult("Writing", nbEvents, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testRead(batchSize) {
|
||||||
|
console.log(`Test Read One Stream (batchSize = ${batchSize})...`);
|
||||||
|
const start = Date.now();
|
||||||
|
const promises = [];
|
||||||
|
for(let i = 0; i < nbEvents; i += batchSize) {
|
||||||
|
promises.push(conn.readStreamEventsForward(writeOneStream, i, batchSize, false));
|
||||||
|
}
|
||||||
|
const results = await Promise.all(promises);
|
||||||
|
const diff = Date.now() - start;
|
||||||
|
const readEvents = results.reduce((x,y) => x + y.events.length, 0);
|
||||||
|
reportResult("Reading", readEvents, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testReadAll(batchSize) {
|
||||||
|
console.log(`Test Read from $all (batchSize = ${batchSize})...`);
|
||||||
|
const start = Date.now();
|
||||||
|
let pos = client.positions.start;
|
||||||
|
let eventsCount = 0;
|
||||||
|
for(;;) {
|
||||||
|
var result = await conn.readAllEventsForward(pos, batchSize, false, adminCreds);
|
||||||
|
pos = result.nextPosition;
|
||||||
|
eventsCount += result.events.length;
|
||||||
|
if (result.isEndOfStream) break;
|
||||||
|
}
|
||||||
|
const diff = Date.now() - start;
|
||||||
|
reportResult("Reading", eventsCount, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onConnected() {
|
||||||
|
try {
|
||||||
|
await testWriteOneStreamAnyVersion(1);
|
||||||
|
await testWriteOneStreamAnyVersion(batchSize);
|
||||||
|
await testWriteOneStreamWithVersion(1);
|
||||||
|
await testWriteOneStreamWithVersion(batchSize);
|
||||||
|
await testWriteMultipleStream();
|
||||||
|
await testRead(1);
|
||||||
|
await testRead(batchSize);
|
||||||
|
await testReadAll(batchSize);
|
||||||
|
conn.close();
|
||||||
|
} catch (e) {
|
||||||
|
console.log('ERROR', e);
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +1,53 @@
|
|||||||
var esClient = require('../src/client'); // When running in 'eventstore-node/samples' folder.
|
const client = require('../src/client')
|
||||||
// var esClient = require('eventstore-node'); // Otherwise
|
// const client = require("node-eventstore-client")
|
||||||
var uuid = require('uuid');
|
const uuid = require("uuid")
|
||||||
|
|
||||||
var esConnection = esClient.createConnection({}, {"hostname": "localhost", "port": 1113});
|
const settings = {}
|
||||||
esConnection.connect();
|
const endpoint = "tcp://localhost:1113"
|
||||||
esConnection.once('connected', function (tcpEndPoint) {
|
const connection = client.createConnection(settings, endpoint)
|
||||||
console.log('Connected to eventstore at ' + tcpEndPoint.host + ":" + tcpEndPoint.port);
|
|
||||||
var userId = uuid.v4();
|
connection.connect().catch(err => console.log(err))
|
||||||
// This event could happen as a result of (e.g.) a 'CreateUser(id, username, password)' command.
|
|
||||||
var userCreatedEvent = {
|
connection.once("connected", tcpEndPoint => {
|
||||||
|
const userId = uuid.v4()
|
||||||
|
|
||||||
|
const userCreatedEvent = {
|
||||||
id: userId,
|
id: userId,
|
||||||
username: "user" + uuid.v4().substring(0,6), // Hard-to-spell exotic username.
|
username: `user${uuid.v4().substring(0,6)}`,
|
||||||
password: Math.random().toString() // Hard-to-guess password.
|
password: Math.random().toString()
|
||||||
};
|
}
|
||||||
var eventId = uuid.v4();
|
|
||||||
var event = esClient.createJsonEventData(eventId, userCreatedEvent, null, "UserCreated");
|
const eventId = uuid.v4();
|
||||||
// Every user has her/his own stream of events:
|
const event = client.createJsonEventData(
|
||||||
var streamName = "user-" + userId;
|
eventId,
|
||||||
console.log("Storing event. Look for it at http://localhost:2113/web/index.html#/streams/user-" + userId);
|
userCreatedEvent,
|
||||||
esConnection.appendToStream(streamName, esClient.expectedVersion.any, event)
|
null,
|
||||||
.then(function(result) {
|
"UserCreated"
|
||||||
console.log("Event stored.");
|
)
|
||||||
process.exit(0);
|
|
||||||
|
// Every user has their own stream of events:
|
||||||
|
const streamName = `user-${userId}`
|
||||||
|
|
||||||
|
console.log(`Connected to eventstore at ${tcpEndPoint.host}:${tcpEndPoint.port}`)
|
||||||
|
console.log(`Storing event ${eventId}. Look for it at http://localhost:2113/web/index.html#/streams/user-${userId}`)
|
||||||
|
|
||||||
|
connection.appendToStream(streamName, client.expectedVersion.any, event)
|
||||||
|
.then(result => {
|
||||||
|
console.log("Event stored.")
|
||||||
|
process.exit(0)
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(error => {
|
||||||
console.log(err);
|
console.log(error)
|
||||||
process.exit(-1);
|
process.exit(-1)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
esConnection.on('error', function (err) {
|
connection.on("error", error => {
|
||||||
console.log('Error occurred on connection:', err);
|
console.log(`Error occurred on connection: ${error}`)
|
||||||
process.exit(-1);
|
process.exit(-1)
|
||||||
});
|
})
|
||||||
|
|
||||||
esConnection.on('closed', function (reason) {
|
connection.on("closed", reason => {
|
||||||
console.log('Connection closed, reason:', reason);
|
console.log(`Connection closed, reason: ${reason}`)
|
||||||
process.exit(-1);
|
process.exit(-1)
|
||||||
});
|
})
|
||||||
|
@ -1,48 +1,56 @@
|
|||||||
// Subscribe to all new events on the $all stream. Filter out any which aren't about "user" aggregates.
|
// Subscribe to all new events on the $all stream. Filter out any which aren"t about "user" aggregates.
|
||||||
|
|
||||||
var esClient = require('../src/client'); // When running in 'eventstore-node/samples' folder.
|
const client = require('../src/client')
|
||||||
// var esClient = require('eventstore-node'); // Otherwise
|
// const client = require("node-eventstore-client")
|
||||||
|
|
||||||
const credentialsForAllEventsStream = new esClient.UserCredentials("admin", "changeit");
|
const resolveLinkTos = false
|
||||||
const resolveLinkTos = false;
|
|
||||||
|
|
||||||
var esConnection = esClient.createConnection({}, {"hostname": "localhost", "port": 1113});
|
const belongsToAUserAggregate = event =>
|
||||||
esConnection.connect();
|
event.originalEvent.eventStreamId.startsWith("user-")
|
||||||
esConnection.once('connected', function (tcpEndPoint) {
|
|
||||||
console.log('Connected to eventstore at ' + tcpEndPoint.host + ":" + tcpEndPoint.port);
|
const eventAppeared = (subscription, event) => {
|
||||||
esConnection.subscribeToAll(resolveLinkTos, eventAppeared, subscriptionDropped, credentialsForAllEventsStream)
|
if (belongsToAUserAggregate(event)) {
|
||||||
.then(function(subscription) {
|
const aggregateId = event.originalEvent.eventStreamId
|
||||||
console.log("subscription.isSubscribedToAll: " + subscription.isSubscribedToAll);
|
const eventId = event.originalEvent.eventId
|
||||||
|
const eventType = event.originalEvent.eventType
|
||||||
|
console.log(aggregateId, eventType, eventId)
|
||||||
|
console.log(event.originalEvent.data.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const subscriptionDropped = (subscription, reason, error) =>
|
||||||
|
console.log(error ? error : "Subscription dropped.")
|
||||||
|
|
||||||
|
const credentials = new client.UserCredentials("admin", "changeit")
|
||||||
|
|
||||||
|
const settings = {}
|
||||||
|
const endpoint = "tcp://localhost:1113"
|
||||||
|
const connection = client.createConnection(settings, endpoint)
|
||||||
|
|
||||||
|
connection.connect().catch(err => console.log(err))
|
||||||
|
|
||||||
|
connection.on('heartbeatInfo', heartbeatInfo => {
|
||||||
|
console.log('Connected to endpoint', heartbeatInfo.remoteEndPoint)
|
||||||
|
console.log('Heartbeat latency', heartbeatInfo.responseReceivedAt - heartbeatInfo.requestSentAt)
|
||||||
|
})
|
||||||
|
|
||||||
|
connection.once("connected", tcpEndPoint => {
|
||||||
|
console.log(`Connected to eventstore at ${tcpEndPoint.host}:${tcpEndPoint.port}`)
|
||||||
|
connection.subscribeToAll(
|
||||||
|
resolveLinkTos,
|
||||||
|
eventAppeared,
|
||||||
|
subscriptionDropped,
|
||||||
|
credentials
|
||||||
|
).then(subscription => {
|
||||||
|
console.log(`subscription.isSubscribedToAll: ${subscription.isSubscribedToAll}`),
|
||||||
console.log("(To generate a test event, try running 'node store-event.js' in a separate console.)")
|
console.log("(To generate a test event, try running 'node store-event.js' in a separate console.)")
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
function belongsToAUserAggregate(event) {
|
connection.on("error", error =>
|
||||||
return event.originalEvent.eventStreamId.startsWith("user-")
|
console.log(`Error occurred on connection: ${error}`)
|
||||||
}
|
)
|
||||||
|
|
||||||
function eventAppeared(subscription, event) {
|
connection.on("closed", reason =>
|
||||||
// Ignore all events which aren't about users:
|
console.log(`Connection closed, reason: ${reason}`)
|
||||||
if(belongsToAUserAggregate(event)) {
|
)
|
||||||
var aggregateId = event.originalEvent.eventStreamId;
|
|
||||||
var eventId = event.originalEvent.eventId;
|
|
||||||
var eventType = event.originalEvent.eventType;
|
|
||||||
console.log(aggregateId, eventType, eventId);
|
|
||||||
console.log(event.originalEvent.data.toString() + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscriptionDropped(subscription, reason, error) {
|
|
||||||
if (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
console.log('Subscription dropped.');
|
|
||||||
}
|
|
||||||
|
|
||||||
esConnection.on('error', function (err) {
|
|
||||||
console.log('Error occurred on connection:', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
esConnection.on('closed', function (reason) {
|
|
||||||
console.log('Connection closed, reason:', reason);
|
|
||||||
});
|
|
||||||
|
@ -1,51 +1,49 @@
|
|||||||
// Subscribe to all events on the $all stream. Catch up from the beginning, then listen for any new events as they occur.
|
// Subscribe to all events on the $all stream. Catch up from the beginning, then listen for any new events as they occur.
|
||||||
// This can be used (e.g.) for subscribers which populate read models.
|
// This could be used for subscribers which populate read models.
|
||||||
|
|
||||||
var esClient = require('../src/client'); // When running in 'eventstore-node/samples' folder.
|
const client = require('../src/client')
|
||||||
// var esClient = require('eventstore-node'); // Otherwise
|
// const client = require("node-eventstore-client")
|
||||||
|
|
||||||
const credentialsForAllEventsStream = new esClient.UserCredentials("admin", "changeit");
|
const eventAppeared = (stream, event) =>
|
||||||
|
console.log(
|
||||||
|
event.originalEvent.eventStreamId,
|
||||||
|
event.originalEvent.eventId,
|
||||||
|
event.originalEvent.eventType
|
||||||
|
)
|
||||||
|
|
||||||
var esConnection = esClient.createConnection({}, {"hostname": "localhost", "port": 1113});
|
const liveProcessingStarted = () => {
|
||||||
esConnection.connect();
|
console.log("Caught up with previously stored events. Listening for new events.")
|
||||||
esConnection.once('connected', function (tcpEndPoint) {
|
|
||||||
console.log('Connected to eventstore at ' + tcpEndPoint.host + ":" + tcpEndPoint.port);
|
|
||||||
var subscription = esConnection.subscribeToAllFrom(null, true, eventAppeared, liveProcessingStarted, subscriptionDropped, credentialsForAllEventsStream);
|
|
||||||
console.log("subscription.isSubscribedToAll: " + subscription.isSubscribedToAll);
|
|
||||||
});
|
|
||||||
|
|
||||||
function eventAppeared(subscription, event) {
|
|
||||||
// This is where to filter out events which the subscriber isn't interested in.
|
|
||||||
// For an example, see 'subscribe-all-events.js'.
|
|
||||||
console.log(event.originalEvent.eventStreamId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscriptionDropped(subscription, reason, error) {
|
|
||||||
if (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
console.log('Subscription dropped.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function liveProcessingStarted() {
|
|
||||||
console.log("Caught up with previously stored events. Listening for new events.");
|
|
||||||
console.log("(To generate a test event, try running 'node store-event.js' in a separate console.)")
|
console.log("(To generate a test event, try running 'node store-event.js' in a separate console.)")
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventAppeared(stream, event) {
|
const subscriptionDropped = (subscription, reason, error) =>
|
||||||
console.log(event.originalEvent.eventStreamId, event.originalEvent.eventId, event.originalEvent.eventType);
|
console.log(error ? error : "Subscription dropped.")
|
||||||
// Data:
|
|
||||||
// console.log(event.originalEvent.data.toString());
|
|
||||||
|
|
||||||
// Position in the event stream. Can be persisted and used to catch up with missed events when re-starting subscribers instead of re-reading
|
const credentials = new client.UserCredentials("admin", "changeit")
|
||||||
// all events from the beginning.
|
|
||||||
// console.log(event.originalPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
esConnection.on('error', function (err) {
|
const settings = {}
|
||||||
console.log('Error occurred on connection:', err);
|
const endpoint = "tcp://localhost:1113"
|
||||||
});
|
const connection = client.createConnection(settings, endpoint)
|
||||||
|
|
||||||
esConnection.on('closed', function (reason) {
|
connection.connect().catch(err => console.log(err))
|
||||||
console.log('Connection closed, reason:', reason);
|
|
||||||
});
|
connection.once("connected", tcpEndPoint => {
|
||||||
|
const subscription = connection.subscribeToAllFrom(
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
eventAppeared,
|
||||||
|
liveProcessingStarted,
|
||||||
|
subscriptionDropped,
|
||||||
|
credentials
|
||||||
|
)
|
||||||
|
console.log(`Connected to eventstore at ${tcpEndPoint.host}:${tcpEndPoint.port}`)
|
||||||
|
console.log(`subscription.isSubscribedToAll: ${subscription.isSubscribedToAll}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
connection.on("error", err =>
|
||||||
|
console.log(`Error occurred on connection: ${err}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
connection.on("closed", reason =>
|
||||||
|
console.log(`Connection closed, reason: ${reason}`)
|
||||||
|
)
|
||||||
|
@ -6,10 +6,12 @@ const expectedVersion = {
|
|||||||
noStream: -1,
|
noStream: -1,
|
||||||
emptyStream: -1
|
emptyStream: -1
|
||||||
};
|
};
|
||||||
|
Object.freeze(expectedVersion);
|
||||||
const positions = {
|
const positions = {
|
||||||
start: new results.Position(0, 0),
|
start: new results.Position(0, 0),
|
||||||
end: new results.Position(-1, -1)
|
end: new results.Position(-1, -1)
|
||||||
};
|
};
|
||||||
|
Object.freeze(positions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an EventData object from JavaScript event/metadata that will be serialized as json
|
* Create an EventData object from JavaScript event/metadata that will be serialized as json
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var guidParse = require('../common/guid-parse');
|
||||||
|
|
||||||
var TcpCommand = require('../systemData/tcpCommand');
|
var TcpCommand = require('../systemData/tcpCommand');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
@ -26,17 +26,18 @@ util.inherits(AppendToStreamOperation, OperationBase);
|
|||||||
|
|
||||||
AppendToStreamOperation.prototype._createRequestDto = function() {
|
AppendToStreamOperation.prototype._createRequestDto = function() {
|
||||||
var dtos = this._events.map(function(ev) {
|
var dtos = this._events.map(function(ev) {
|
||||||
var eventId = new Buffer(uuid.parse(ev.eventId));
|
var eventId = guidParse.parse(ev.eventId);
|
||||||
return new ClientMessage.NewEvent({
|
return {
|
||||||
event_id: eventId, event_type: ev.type,
|
eventId: eventId, eventType: ev.type,
|
||||||
data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0,
|
dataContentType: ev.isJson ? 1 : 0, metadataContentType: 0,
|
||||||
data: ev.data, metadata: ev.metadata});
|
data: ev.data, metadata: ev.metadata
|
||||||
|
};
|
||||||
});
|
});
|
||||||
return new ClientMessage.WriteEvents({
|
return new ClientMessage.WriteEvents({
|
||||||
event_stream_id: this._stream,
|
eventStreamId: this._stream,
|
||||||
expected_version: this._expectedVersion,
|
expectedVersion: this._expectedVersion,
|
||||||
events: dtos,
|
events: dtos,
|
||||||
require_master: this._requireMaster});
|
requireMaster: this._requireMaster});
|
||||||
};
|
};
|
||||||
|
|
||||||
AppendToStreamOperation.prototype._inspectResponse = function(response) {
|
AppendToStreamOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -72,7 +73,7 @@ AppendToStreamOperation.prototype._inspectResponse = function(response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
AppendToStreamOperation.prototype._transformResponse = function(response) {
|
AppendToStreamOperation.prototype._transformResponse = function(response) {
|
||||||
return new WriteResult(response.last_event_number, new Position(response.prepare_position || -1, response.commit_position || -1));
|
return new WriteResult(response.lastEventNumber, new Position(response.preparePosition || -1, response.commitPosition || -1));
|
||||||
};
|
};
|
||||||
|
|
||||||
AppendToStreamOperation.prototype.toString = function() {
|
AppendToStreamOperation.prototype.toString = function() {
|
||||||
|
@ -23,7 +23,10 @@ function CommitTransactionOperation(log, cb, requireMaster, transactionId, userC
|
|||||||
util.inherits(CommitTransactionOperation, OperationBase);
|
util.inherits(CommitTransactionOperation, OperationBase);
|
||||||
|
|
||||||
CommitTransactionOperation.prototype._createRequestDto = function() {
|
CommitTransactionOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.TransactionCommit(this._transactionId, this._requireMaster);
|
return new ClientMessage.TransactionCommit({
|
||||||
|
transactionId: this._transactionId,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CommitTransactionOperation.prototype._inspectResponse = function(response) {
|
CommitTransactionOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -56,8 +59,8 @@ CommitTransactionOperation.prototype._inspectResponse = function(response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CommitTransactionOperation.prototype._transformResponse = function(response) {
|
CommitTransactionOperation.prototype._transformResponse = function(response) {
|
||||||
var logPosition = new results.Position(response.prepare_position || -1, response.commit_position || -1);
|
var logPosition = new results.Position(response.preparePosition || -1, response.commitPosition || -1);
|
||||||
return new results.WriteResult(response.last_event_number, logPosition);
|
return new results.WriteResult(response.lastEventNumber, logPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
CommitTransactionOperation.prototype.toString = function() {
|
CommitTransactionOperation.prototype.toString = function() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var guidParse = require('../common/guid-parse');
|
||||||
|
|
||||||
var SubscriptionOperation = require('./subscriptionOperation');
|
var SubscriptionOperation = require('./subscriptionOperation');
|
||||||
var ClientMessage = require('../messages/clientMessage');
|
var ClientMessage = require('../messages/clientMessage');
|
||||||
@ -27,21 +27,25 @@ function ConnectToPersistentSubscriptionOperation(
|
|||||||
util.inherits(ConnectToPersistentSubscriptionOperation, SubscriptionOperation);
|
util.inherits(ConnectToPersistentSubscriptionOperation, SubscriptionOperation);
|
||||||
|
|
||||||
ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionPackage = function() {
|
ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionPackage = function() {
|
||||||
var dto = new ClientMessage.ConnectToPersistentSubscription(this._groupName, this._streamId, this._bufferSize);
|
var dto = new ClientMessage.ConnectToPersistentSubscription({
|
||||||
|
subscriptionId: this._groupName,
|
||||||
|
eventStreamId: this._streamId,
|
||||||
|
allowedInFlightMessages: this._bufferSize
|
||||||
|
});
|
||||||
return new TcpPackage(TcpCommand.ConnectToPersistentSubscription,
|
return new TcpPackage(TcpCommand.ConnectToPersistentSubscription,
|
||||||
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(ClientMessage.ConnectToPersistentSubscription.encode(dto).finish()));
|
||||||
};
|
};
|
||||||
|
|
||||||
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.lastCommitPosition, dto.lastEventNumber);
|
||||||
this._subscriptionId = dto.subscription_id;
|
this._subscriptionId = dto.subscriptionId;
|
||||||
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
|
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
|
||||||
}
|
}
|
||||||
if (pkg.command === TcpCommand.PersistentSubscriptionStreamEventAppeared)
|
if (pkg.command === TcpCommand.PersistentSubscriptionStreamEventAppeared)
|
||||||
@ -86,9 +90,9 @@ ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionObject = f
|
|||||||
ConnectToPersistentSubscriptionOperation.prototype.notifyEventsProcessed = function(processedEvents) {
|
ConnectToPersistentSubscriptionOperation.prototype.notifyEventsProcessed = function(processedEvents) {
|
||||||
ensure.notNull(processedEvents, "processedEvents");
|
ensure.notNull(processedEvents, "processedEvents");
|
||||||
var dto = new ClientMessage.PersistentSubscriptionAckEvents({
|
var dto = new ClientMessage.PersistentSubscriptionAckEvents({
|
||||||
subscription_id: this._subscriptionId,
|
subscriptionId: this._subscriptionId,
|
||||||
processed_event_ids: processedEvents.map(function (x) {
|
processedEventIds: processedEvents.map(function (x) {
|
||||||
return new Buffer(uuid.parse(x));
|
return guidParse.parse(x);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -97,25 +101,26 @@ ConnectToPersistentSubscriptionOperation.prototype.notifyEventsProcessed = funct
|
|||||||
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.encode().toBuffer()));
|
createBufferSegment(ClientMessage.PersistentSubscriptionAckEvents.encode(dto).finish()));
|
||||||
this._enqueueSend(pkg);
|
this._enqueueSend(pkg);
|
||||||
};
|
};
|
||||||
|
|
||||||
ConnectToPersistentSubscriptionOperation.prototype.notifyEventsFailed = function(processedEvents, action, reason) {
|
ConnectToPersistentSubscriptionOperation.prototype.notifyEventsFailed = function(processedEvents, action, reason) {
|
||||||
ensure.notNull(processedEvents, "processedEvents");
|
ensure.notNull(processedEvents, "processedEvents");
|
||||||
ensure.notNull(reason, "reason");
|
ensure.notNull(reason, "reason");
|
||||||
var dto = new ClientMessage.PersistentSubscriptionNakEvents(
|
var dto = new ClientMessage.PersistentSubscriptionNakEvents({
|
||||||
this._subscriptionId,
|
subscriptionId: this._subscriptionId,
|
||||||
processedEvents.map(function(x) { return new Buffer(uuid.parse(x)); }),
|
processedEventIds: processedEvents.map(function(x) { return guidParse.parse(x); }),
|
||||||
reason,
|
message: reason,
|
||||||
action);
|
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(ClientMessage.PersistentSubscriptionNakEvents.encode(dto).finish()));
|
||||||
this._enqueueSend(pkg);
|
this._enqueueSend(pkg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,11 +36,24 @@ function CreatePersistentSubscriptionOperation(log, cb, stream, groupName, setti
|
|||||||
util.inherits(CreatePersistentSubscriptionOperation, OperationBase);
|
util.inherits(CreatePersistentSubscriptionOperation, OperationBase);
|
||||||
|
|
||||||
CreatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
CreatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.CreatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos,
|
return new ClientMessage.CreatePersistentSubscription({
|
||||||
this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize,
|
subscriptionGroupName: this._groupName,
|
||||||
this._readBatchSize, this._bufferSize, this._maxRetryCount,
|
eventStreamId: this._stream,
|
||||||
this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin, this._checkPointAfter,
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy);
|
startFrom: this._startFromBeginning,
|
||||||
|
messageTimeoutMilliseconds: this._messageTimeoutMilliseconds,
|
||||||
|
recordStatistics: this._recordStatistics,
|
||||||
|
liveBufferSize: this._liveBufferSize,
|
||||||
|
readBatchSize: this._readBatchSize,
|
||||||
|
bufferSize: this._bufferSize,
|
||||||
|
maxRetryCount: this._maxRetryCount,
|
||||||
|
preferRoundRobin: this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin,
|
||||||
|
checkpointAfterTime: this._checkPointAfter,
|
||||||
|
checkpointMaxCount: this._maxCheckPointCount,
|
||||||
|
checkpointMinCount: this._minCheckPointCount,
|
||||||
|
subscriberMaxCount: this._maxSubscriberCount,
|
||||||
|
namedConsumerStrategy: this._namedConsumerStrategy
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
CreatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
||||||
|
@ -21,7 +21,10 @@ function DeletePersistentSubscriptionOperation(log, cb, stream, groupName, userC
|
|||||||
util.inherits(DeletePersistentSubscriptionOperation, OperationBase);
|
util.inherits(DeletePersistentSubscriptionOperation, OperationBase);
|
||||||
|
|
||||||
DeletePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
DeletePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.DeletePersistentSubscription(this._groupName, this._stream);
|
return new ClientMessage.DeletePersistentSubscription({
|
||||||
|
subscriptionGroupName: this._groupName,
|
||||||
|
eventStreamId: this._stream
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
DeletePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
DeletePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
||||||
|
@ -25,7 +25,12 @@ function DeleteStreamOperation(log, cb, requireMaster, stream, expectedVersion,
|
|||||||
util.inherits(DeleteStreamOperation, OperationBase);
|
util.inherits(DeleteStreamOperation, OperationBase);
|
||||||
|
|
||||||
DeleteStreamOperation.prototype._createRequestDto = function() {
|
DeleteStreamOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.DeleteStream(this._stream, this._expectedVersion, this._requireMaster, this._hardDelete);
|
return new ClientMessage.DeleteStream({
|
||||||
|
eventStreamId: this._stream,
|
||||||
|
expectedVersion: this._expectedVersion,
|
||||||
|
requireMaster: this._requireMaster,
|
||||||
|
hardDelete: this._hardDelete
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
DeleteStreamOperation.prototype._inspectResponse = function(response) {
|
DeleteStreamOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -58,7 +63,7 @@ DeleteStreamOperation.prototype._inspectResponse = function(response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DeleteStreamOperation.prototype._transformResponse = function(response) {
|
DeleteStreamOperation.prototype._transformResponse = function(response) {
|
||||||
return new results.DeleteResult(new results.Position(response.prepare_position || -1, response.commit_position || -1));
|
return new results.DeleteResult(new results.Position(response.preparePosition || -1, response.commitPosition || -1));
|
||||||
};
|
};
|
||||||
|
|
||||||
DeleteStreamOperation.prototype.toString = function() {
|
DeleteStreamOperation.prototype.toString = function() {
|
||||||
|
@ -51,7 +51,7 @@ OperationBase.prototype._succeed = function() {
|
|||||||
|
|
||||||
OperationBase.prototype.createNetworkPackage = function(correlationId) {
|
OperationBase.prototype.createNetworkPackage = function(correlationId) {
|
||||||
var dto = this._createRequestDto();
|
var dto = this._createRequestDto();
|
||||||
var buf = dto.toBuffer();
|
var buf = dto.constructor.encode(dto).finish();
|
||||||
return new TcpPackage(
|
return new TcpPackage(
|
||||||
this._requestCommand,
|
this._requestCommand,
|
||||||
this.userCredentials ? TcpFlags.Authenticated : TcpFlags.None,
|
this.userCredentials ? TcpFlags.Authenticated : TcpFlags.None,
|
||||||
@ -117,10 +117,10 @@ OperationBase.prototype._inspectNotHandled = function(pkg)
|
|||||||
return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
|
return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
|
||||||
|
|
||||||
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.additionalInfo);
|
||||||
return 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.externalTcpAddress, port: masterInfo.externalTcpPort},
|
||||||
{host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port});
|
{host: masterInfo.externalSecureTcpAddress, port: masterInfo.externalSecureTcpPort});
|
||||||
|
|
||||||
default:
|
default:
|
||||||
this.log.error("Unknown NotHandledReason: %s.", message.reason);
|
this.log.error("Unknown NotHandledReason: %s.", message.reason);
|
||||||
|
@ -25,7 +25,13 @@ function ReadAllEventsBackwardOperation(
|
|||||||
util.inherits(ReadAllEventsBackwardOperation, OperationBase);
|
util.inherits(ReadAllEventsBackwardOperation, OperationBase);
|
||||||
|
|
||||||
ReadAllEventsBackwardOperation.prototype._createRequestDto = function() {
|
ReadAllEventsBackwardOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.ReadAllEvents(this._position.commitPosition, this._position.preparePosition, this._maxCount, this._resolveLinkTos, this._requireMaster);
|
return new ClientMessage.ReadAllEvents({
|
||||||
|
commitPosition: this._position.commitPosition,
|
||||||
|
preparePosition: this._position.preparePosition,
|
||||||
|
maxCount: this._maxCount,
|
||||||
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadAllEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
ReadAllEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -48,8 +54,8 @@ ReadAllEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
|||||||
ReadAllEventsBackwardOperation.prototype._transformResponse = function(response) {
|
ReadAllEventsBackwardOperation.prototype._transformResponse = function(response) {
|
||||||
return new results.AllEventsSlice(
|
return new results.AllEventsSlice(
|
||||||
ReadDirection.Backward,
|
ReadDirection.Backward,
|
||||||
new results.Position(response.commit_position, response.prepare_position),
|
new results.Position(response.commitPosition, response.preparePosition),
|
||||||
new results.Position(response.next_commit_position, response.next_prepare_position),
|
new results.Position(response.nextCommitPosition, response.nextPreparePosition),
|
||||||
response.events
|
response.events
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,13 @@ function ReadAllEventsForwardOperation(
|
|||||||
util.inherits(ReadAllEventsForwardOperation, OperationBase);
|
util.inherits(ReadAllEventsForwardOperation, OperationBase);
|
||||||
|
|
||||||
ReadAllEventsForwardOperation.prototype._createRequestDto = function() {
|
ReadAllEventsForwardOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.ReadAllEvents(this._position.commitPosition, this._position.preparePosition, this._maxCount, this._resolveLinkTos, this._requireMaster);
|
return new ClientMessage.ReadAllEvents({
|
||||||
|
commitPosition: this._position.commitPosition,
|
||||||
|
preparePosition: this._position.preparePosition,
|
||||||
|
maxCount: this._maxCount,
|
||||||
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadAllEventsForwardOperation.prototype._inspectResponse = function(response) {
|
ReadAllEventsForwardOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -48,8 +54,8 @@ ReadAllEventsForwardOperation.prototype._inspectResponse = function(response) {
|
|||||||
ReadAllEventsForwardOperation.prototype._transformResponse = function(response) {
|
ReadAllEventsForwardOperation.prototype._transformResponse = function(response) {
|
||||||
return new results.AllEventsSlice(
|
return new results.AllEventsSlice(
|
||||||
ReadDirection.Forward,
|
ReadDirection.Forward,
|
||||||
new results.Position(response.commit_position, response.prepare_position),
|
new results.Position(response.commitPosition, response.preparePosition),
|
||||||
new results.Position(response.next_commit_position, response.next_prepare_position),
|
new results.Position(response.nextCommitPosition, response.nextPreparePosition),
|
||||||
response.events
|
response.events
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,12 @@ function ReadEventOperation(log, cb, stream, eventNumber, resolveLinkTos, requir
|
|||||||
util.inherits(ReadEventOperation, OperationBase);
|
util.inherits(ReadEventOperation, OperationBase);
|
||||||
|
|
||||||
ReadEventOperation.prototype._createRequestDto = function() {
|
ReadEventOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.ReadEvent(this._stream, this._eventNumber, this._resolveLinkTos, this._requireMaster);
|
return new ClientMessage.ReadEvent({
|
||||||
|
eventStreamId: this._stream,
|
||||||
|
eventNumber: this._eventNumber,
|
||||||
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadEventOperation.prototype._inspectResponse = function(response) {
|
ReadEventOperation.prototype._inspectResponse = function(response) {
|
||||||
|
@ -27,7 +27,13 @@ function ReadStreamEventsBackwardOperation(
|
|||||||
util.inherits(ReadStreamEventsBackwardOperation, OperationBase);
|
util.inherits(ReadStreamEventsBackwardOperation, OperationBase);
|
||||||
|
|
||||||
ReadStreamEventsBackwardOperation.prototype._createRequestDto = function() {
|
ReadStreamEventsBackwardOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.ReadStreamEvents(this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster);
|
return new ClientMessage.ReadStreamEvents({
|
||||||
|
eventStreamId: this._stream,
|
||||||
|
fromEventNumber: this._fromEventNumber,
|
||||||
|
maxCount: this._maxCount,
|
||||||
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadStreamEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
ReadStreamEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -60,9 +66,9 @@ ReadStreamEventsBackwardOperation.prototype._transformResponse = function(respon
|
|||||||
this._fromEventNumber,
|
this._fromEventNumber,
|
||||||
ReadDirection.Backward,
|
ReadDirection.Backward,
|
||||||
response.events,
|
response.events,
|
||||||
response.next_event_number,
|
response.nextEventNumber,
|
||||||
response.last_event_number,
|
response.lastEventNumber,
|
||||||
response.is_end_of_stream
|
response.isEndOfStream
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +27,13 @@ function ReadStreamEventsForwardOperation(
|
|||||||
util.inherits(ReadStreamEventsForwardOperation, OperationBase);
|
util.inherits(ReadStreamEventsForwardOperation, OperationBase);
|
||||||
|
|
||||||
ReadStreamEventsForwardOperation.prototype._createRequestDto = function() {
|
ReadStreamEventsForwardOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.ReadStreamEvents(this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster);
|
return new ClientMessage.ReadStreamEvents({
|
||||||
|
eventStreamId: this._stream,
|
||||||
|
fromEventNumber: this._fromEventNumber,
|
||||||
|
maxCount: this._maxCount,
|
||||||
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadStreamEventsForwardOperation.prototype._inspectResponse = function(response) {
|
ReadStreamEventsForwardOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -60,9 +66,9 @@ ReadStreamEventsForwardOperation.prototype._transformResponse = function(respons
|
|||||||
this._fromEventNumber,
|
this._fromEventNumber,
|
||||||
ReadDirection.Forward,
|
ReadDirection.Forward,
|
||||||
response.events,
|
response.events,
|
||||||
response.next_event_number,
|
response.nextEventNumber,
|
||||||
response.last_event_number,
|
response.lastEventNumber,
|
||||||
response.is_end_of_stream
|
response.isEndOfStream
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,11 @@ function StartTransactionOperation(log, cb, requireMaster, stream, expectedVersi
|
|||||||
util.inherits(StartTransactionOperation, OperationBase);
|
util.inherits(StartTransactionOperation, OperationBase);
|
||||||
|
|
||||||
StartTransactionOperation.prototype._createRequestDto = function() {
|
StartTransactionOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.TransactionStart(this._stream, this._expectedVersion, this._requireMaster);
|
return new ClientMessage.TransactionStart({
|
||||||
|
eventStreamId: this._stream,
|
||||||
|
expectedVersion: this._expectedVersion,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
StartTransactionOperation.prototype._inspectResponse = function(response) {
|
StartTransactionOperation.prototype._inspectResponse = function(response) {
|
||||||
@ -57,7 +61,7 @@ StartTransactionOperation.prototype._inspectResponse = function(response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
StartTransactionOperation.prototype._transformResponse = function(response) {
|
StartTransactionOperation.prototype._transformResponse = function(response) {
|
||||||
return new EventStoreTransaction(response.transaction_id, this.userCredentials, this._parentConnection);
|
return new EventStoreTransaction(response.transactionId, this.userCredentials, this._parentConnection);
|
||||||
};
|
};
|
||||||
|
|
||||||
StartTransactionOperation.prototype.toString = function() {
|
StartTransactionOperation.prototype.toString = function() {
|
||||||
|
@ -64,7 +64,7 @@ SubscriptionOperation.prototype.unsubscribe = function() {
|
|||||||
|
|
||||||
SubscriptionOperation.prototype._createUnsubscriptionPackage = function() {
|
SubscriptionOperation.prototype._createUnsubscriptionPackage = function() {
|
||||||
var msg = new ClientMessage.UnsubscribeFromStream();
|
var msg = new ClientMessage.UnsubscribeFromStream();
|
||||||
var data = new BufferSegment(msg.toBuffer());
|
var data = new BufferSegment(ClientMessage.UnsubscribeFromStream.encode(msg).finish());
|
||||||
return new TcpPackage(TcpCommand.UnsubscribeFromStream, TcpFlags.None, this._correlationId, null, null, data);
|
return new TcpPackage(TcpCommand.UnsubscribeFromStream, TcpFlags.None, this._correlationId, null, null, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,10 +141,10 @@ SubscriptionOperation.prototype.inspectPackage = function(pkg) {
|
|||||||
return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
|
return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
|
||||||
|
|
||||||
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.additionalInfo);
|
||||||
return 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.externalTcpAddress, port: masterInfo.externalTcpPort},
|
||||||
{host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port});
|
{host: masterInfo.externalSecureTcpAddress, port: masterInfo.externalSecureTcpPort});
|
||||||
|
|
||||||
default:
|
default:
|
||||||
this._log.error("Unknown NotHandledReason: %s.", message.reason);
|
this._log.error("Unknown NotHandledReason: %s.", message.reason);
|
||||||
@ -232,7 +232,7 @@ SubscriptionOperation.prototype._onEventAppeared = function(e) {
|
|||||||
e.originalStreamId, e.originalEventNumber, e.originalEvent.eventType, e.originalPosition);
|
e.originalStreamId, e.originalEventNumber, e.originalEvent.eventType, e.originalPosition);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this._executeAction(function() { self._eventAppeared(self._subscription, e); });
|
this._executeAction(function() { return self._eventAppeared(self._subscription, e); });
|
||||||
};
|
};
|
||||||
|
|
||||||
SubscriptionOperation.prototype._executeAction = function(action) {
|
SubscriptionOperation.prototype._executeAction = function(action) {
|
||||||
@ -244,21 +244,30 @@ SubscriptionOperation.prototype._executeAction = function(action) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SubscriptionOperation.prototype._executeActions = function() {
|
SubscriptionOperation.prototype._executeActions = function() {
|
||||||
//TODO: possible blocking loop for node.js
|
|
||||||
var action = this._actionQueue.shift();
|
var action = this._actionQueue.shift();
|
||||||
while (action)
|
if (!action) {
|
||||||
{
|
this._actionExecuting = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var promise;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
action();
|
promise = action();
|
||||||
}
|
}
|
||||||
catch (err)
|
catch (err)
|
||||||
{
|
{
|
||||||
this._log.error(err, "Exception during executing user callback: %s.", err.message);
|
this._log.error(err, "Exception during executing user callback: %s.", err.message);
|
||||||
}
|
}
|
||||||
action = this._actionQueue.shift();
|
if (promise && promise.then) {
|
||||||
|
var self = this;
|
||||||
|
promise
|
||||||
|
.catch(function (err) {
|
||||||
|
self._log.error(err, "Exception during executing user callback: %s.", err.message);
|
||||||
|
})
|
||||||
|
.then(this._executeActions.bind(this));
|
||||||
|
} else {
|
||||||
|
setImmediate(this._executeActions.bind(this));
|
||||||
}
|
}
|
||||||
this._actionExecuting = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SubscriptionOperation.prototype.toString = function() {
|
SubscriptionOperation.prototype.toString = function() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var guidParse = require('../common/guid-parse');
|
||||||
|
|
||||||
var TcpCommand = require('../systemData/tcpCommand');
|
var TcpCommand = require('../systemData/tcpCommand');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
@ -22,13 +22,18 @@ util.inherits(TransactionalWriteOperation, OperationBase);
|
|||||||
|
|
||||||
TransactionalWriteOperation.prototype._createRequestDto = function() {
|
TransactionalWriteOperation.prototype._createRequestDto = function() {
|
||||||
var dtos = this._events.map(function(ev) {
|
var dtos = this._events.map(function(ev) {
|
||||||
var eventId = new Buffer(uuid.parse(ev.eventId));
|
var eventId = guidParse.parse(ev.eventId);
|
||||||
return new ClientMessage.NewEvent({
|
return {
|
||||||
event_id: eventId, event_type: ev.type,
|
eventId: eventId, eventType: ev.type,
|
||||||
data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0,
|
dataContentType: ev.isJson ? 1 : 0, metadataContentType: 0,
|
||||||
data: ev.data, metadata: ev.metadata});
|
data: ev.data, metadata: ev.metadata
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return new ClientMessage.TransactionWrite({
|
||||||
|
transactionId: this._transactionId,
|
||||||
|
events: dtos,
|
||||||
|
requireMaster: this._requireMaster
|
||||||
});
|
});
|
||||||
return new ClientMessage.TransactionWrite(this._transactionId, dtos, this._requireMaster);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionalWriteOperation.prototype._inspectResponse = function(response) {
|
TransactionalWriteOperation.prototype._inspectResponse = function(response) {
|
||||||
|
@ -36,11 +36,24 @@ function UpdatePersistentSubscriptionOperation(log, cb, stream, groupName, setti
|
|||||||
util.inherits(UpdatePersistentSubscriptionOperation, OperationBase);
|
util.inherits(UpdatePersistentSubscriptionOperation, OperationBase);
|
||||||
|
|
||||||
UpdatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
UpdatePersistentSubscriptionOperation.prototype._createRequestDto = function() {
|
||||||
return new ClientMessage.UpdatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos,
|
return new ClientMessage.UpdatePersistentSubscription({
|
||||||
this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize,
|
subscriptionGroupName: this._groupName,
|
||||||
this._readBatchSize, this._bufferSize, this._maxRetryCount,
|
eventStreamId: this._stream,
|
||||||
this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin, this._checkPointAfter,
|
resolveLinkTos: this._resolveLinkTos,
|
||||||
this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy);
|
startFrom: this._startFromBeginning,
|
||||||
|
messageTimeoutMilliseconds: this._messageTimeoutMilliseconds,
|
||||||
|
recordStatistics: this._recordStatistics,
|
||||||
|
liveBufferSize: this._liveBufferSize,
|
||||||
|
readBatchSize: this._readBatchSize,
|
||||||
|
bufferSize: this._bufferSize,
|
||||||
|
maxRetryCount: this._maxRetryCount,
|
||||||
|
preferRoundRobin: this._namedConsumerStrategy === SystemConsumerStrategies.RoundRobin,
|
||||||
|
checkpointAfterTime: this._checkPointAfter,
|
||||||
|
checkpointMaxCount: this._maxCheckPointCount,
|
||||||
|
checkpointMinCount: this._minCheckPointCount,
|
||||||
|
subscriberMaxCount: this._maxSubscriberCount,
|
||||||
|
namedConsumerStrategy: this._namedConsumerStrategy
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
UpdatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) {
|
||||||
|
@ -20,20 +20,23 @@ function VolatileSubscriptionOperation(
|
|||||||
util.inherits(VolatileSubscriptionOperation, SubscriptionOperation);
|
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({
|
||||||
|
eventStreamId: this._streamId,
|
||||||
|
resolveLinkTos: 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(ClientMessage.SubscribeToStream.encode(dto).finish()));
|
||||||
};
|
};
|
||||||
|
|
||||||
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.lastCommitPosition, dto.lastEventNumber);
|
||||||
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
|
return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
|
||||||
}
|
}
|
||||||
if (pkg.command === TcpCommand.StreamEventAppeared) {
|
if (pkg.command === TcpCommand.StreamEventAppeared) {
|
||||||
|
47
src/common/guid-parse.js
Normal file
47
src/common/guid-parse.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Maps for number <-> hex string conversion
|
||||||
|
var _byteToHex = [];
|
||||||
|
var _hexToByte = {};
|
||||||
|
for (var i = 0; i < 256; i++) {
|
||||||
|
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||||
|
_hexToByte[_byteToHex[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`parse()` - Parse a UUID into it's component bytes**
|
||||||
|
function parse(s, buf, offset) {
|
||||||
|
const i = (buf && offset) || 0;
|
||||||
|
var ii = 0;
|
||||||
|
|
||||||
|
if (buf) buf.fill(0, i, i + 16);
|
||||||
|
buf = buf || new Buffer(16);
|
||||||
|
s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
|
||||||
|
if (ii < 16) { // Don't overflow!
|
||||||
|
buf[i + ii++] = _hexToByte[oct];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var buf2 = new Buffer(buf.slice(i, i + 16));
|
||||||
|
buf[i + 0] = buf2[3];
|
||||||
|
buf[i + 1] = buf2[2];
|
||||||
|
buf[i + 2] = buf2[1];
|
||||||
|
buf[i + 3] = buf2[0];
|
||||||
|
buf[i + 4] = buf2[5];
|
||||||
|
buf[i + 5] = buf2[4];
|
||||||
|
buf[i + 6] = buf2[7];
|
||||||
|
buf[i + 7] = buf2[6];
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
|
||||||
|
function unparse(buf, offset) {
|
||||||
|
var i = offset || 0;
|
||||||
|
return '03020100-0504-0706-0809-101112131415'.replace(/\d{2}/g, function (num) {
|
||||||
|
var j = parseInt(num, 10);
|
||||||
|
return _byteToHex[buf[i+j]];
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.parse = parse;
|
||||||
|
exports.unparse = unparse;
|
@ -12,5 +12,6 @@ const SystemMetadata = {
|
|||||||
userStreamAcl: '$userStreamAcl',
|
userStreamAcl: '$userStreamAcl',
|
||||||
systemStreamAcl: '$systemStreamAcl'
|
systemStreamAcl: '$systemStreamAcl'
|
||||||
};
|
};
|
||||||
|
Object.freeze(SystemMetadata);
|
||||||
|
|
||||||
module.exports = SystemMetadata;
|
module.exports = SystemMetadata;
|
@ -1,3 +1,5 @@
|
|||||||
|
var Long = require('long');
|
||||||
|
|
||||||
module.exports.notNullOrEmpty = function(value, name) {
|
module.exports.notNullOrEmpty = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new TypeError(name + " should not be null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
@ -10,9 +12,18 @@ module.exports.notNull = function(value, name) {
|
|||||||
throw new TypeError(name + " should not be null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isInteger = function(value, name) {
|
function isInteger(value, name) {
|
||||||
if (typeof value !== 'number' || value % 1 !== 0)
|
if (typeof value !== 'number' || value % 1 !== 0)
|
||||||
throw new TypeError(name + " should be an integer.");
|
throw new TypeError(name + " should be an integer.");
|
||||||
|
}
|
||||||
|
module.exports.isInteger = isInteger;
|
||||||
|
|
||||||
|
module.exports.isLongOrInteger = function(value, name) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
return isInteger(value, name);
|
||||||
|
} else if (!Long.isLong(value)) {
|
||||||
|
throw new TypeError(name + " should be a Long|number.");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isArrayOf = function(expectedType, value, name) {
|
module.exports.isArrayOf = function(expectedType, value, name) {
|
||||||
|
@ -9,6 +9,8 @@ var SubscriptionsManager = require('./subscriptionsManager');
|
|||||||
var VolatileSubscriptionOperation = require('../clientOperations/volatileSubscriptionOperation');
|
var VolatileSubscriptionOperation = require('../clientOperations/volatileSubscriptionOperation');
|
||||||
var ConnectToPersistentSubscriptionOperation = require('../clientOperations/connectToPersistentSubscriptionOperation');
|
var ConnectToPersistentSubscriptionOperation = require('../clientOperations/connectToPersistentSubscriptionOperation');
|
||||||
var messages = require('./messages');
|
var messages = require('./messages');
|
||||||
|
var ClientMessage = require('../messages/clientMessage');
|
||||||
|
var createBufferSegment = require('../common/bufferSegment');
|
||||||
|
|
||||||
var TcpPackage = require('../systemData/tcpPackage');
|
var TcpPackage = require('../systemData/tcpPackage');
|
||||||
var TcpCommand = require('../systemData/tcpCommand');
|
var TcpCommand = require('../systemData/tcpCommand');
|
||||||
@ -28,12 +30,14 @@ const ConnectingPhase = {
|
|||||||
EndPointDiscovery: 'endpointDiscovery',
|
EndPointDiscovery: 'endpointDiscovery',
|
||||||
ConnectionEstablishing: 'connectionEstablishing',
|
ConnectionEstablishing: 'connectionEstablishing',
|
||||||
Authentication: 'authentication',
|
Authentication: 'authentication',
|
||||||
|
Identification: 'identification',
|
||||||
Connected: 'connected'
|
Connected: 'connected'
|
||||||
};
|
};
|
||||||
|
|
||||||
const TimerPeriod = 200;
|
const TimerPeriod = 200;
|
||||||
const TimerTickMessage = new messages.TimerTickMessage();
|
const TimerTickMessage = new messages.TimerTickMessage();
|
||||||
const EmptyGuid = '00000000-0000-0000-0000-000000000000';
|
const EmptyGuid = '00000000-0000-0000-0000-000000000000';
|
||||||
|
const ClientVersion = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -391,10 +395,21 @@ EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._goToConnectedState();
|
this._goToIdentifiedState();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EventStoreConnectionLogicHandler.prototype._goToIdentifiedState = function() {
|
||||||
|
this._connectingPhase = ConnectingPhase.Identification;
|
||||||
|
this._identityInfo = {
|
||||||
|
correlationId: uuid.v4(),
|
||||||
|
timeStamp: Date.now()
|
||||||
|
};
|
||||||
|
var dto = new ClientMessage.IdentifyClient({version: ClientVersion, connectionName: this._esConnection.connectionName});
|
||||||
|
var buf = dto.constructor.encode(dto).finish();
|
||||||
|
this._connection.enqueueSend(new TcpPackage(TcpCommand.IdentifyClient, TcpFlags.None, this._identityInfo.correlationId, null, null, createBufferSegment(buf)))
|
||||||
|
};
|
||||||
|
|
||||||
EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
|
EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
|
||||||
this._state = ConnectionState.Connected;
|
this._state = ConnectionState.Connected;
|
||||||
this._connectingPhase = ConnectingPhase.Connected;
|
this._connectingPhase = ConnectingPhase.Connected;
|
||||||
@ -460,7 +475,26 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
|
|||||||
this._packageNumber += 1;
|
this._packageNumber += 1;
|
||||||
|
|
||||||
if (pkg.command === TcpCommand.HeartbeatResponseCommand)
|
if (pkg.command === TcpCommand.HeartbeatResponseCommand)
|
||||||
|
{
|
||||||
|
if (pkg.correlationId === this._heartbeatInfo.correlationId)
|
||||||
|
{
|
||||||
|
var now = Date.now();
|
||||||
|
var heartbeatEvent = {
|
||||||
|
connectionId: this._connection.connectionId,
|
||||||
|
remoteEndPoint: this._connection.remoteEndPoint,
|
||||||
|
requestSentAt: this._heartbeatInfo.timeStamp,
|
||||||
|
requestPkgNumber: this._heartbeatInfo.lastPackageNumber,
|
||||||
|
responseReceivedAt: now,
|
||||||
|
responsePkgNumber: this._packageNumber
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
this.emit('heartbeatInfo', heartbeatEvent);
|
||||||
|
} catch(e) {
|
||||||
|
this._logDebug("IGNORED: emit heartbeat event failed.\n%s", e.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (pkg.command === TcpCommand.HeartbeatRequestCommand)
|
if (pkg.command === TcpCommand.HeartbeatRequestCommand)
|
||||||
{
|
{
|
||||||
this._connection.enqueueSend(new TcpPackage(
|
this._connection.enqueueSend(new TcpPackage(
|
||||||
@ -479,6 +513,16 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
|
|||||||
if (pkg.command === TcpCommand.NotAuthenticated)
|
if (pkg.command === TcpCommand.NotAuthenticated)
|
||||||
this.emit('authenticationFailed', "Not authenticated");
|
this.emit('authenticationFailed', "Not authenticated");
|
||||||
|
|
||||||
|
this._goToIdentifiedState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkg.command === TcpCommand.ClientIdentified)
|
||||||
|
{
|
||||||
|
if (this._state === ConnectionState.Connecting
|
||||||
|
&& this._identityInfo.correlationId === pkg.correlationId)
|
||||||
|
{
|
||||||
this._goToConnectedState();
|
this._goToConnectedState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -598,8 +642,12 @@ EventStoreConnectionLogicHandler.prototype._timerTick = function() {
|
|||||||
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.");
|
||||||
|
if (this._clientVersion === 1) {
|
||||||
|
this._goToIdentifiedState();
|
||||||
|
} else {
|
||||||
this._goToConnectedState();
|
this._goToConnectedState();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (this._connectingPhase === ConnectingPhase.Authentication || this._connectingPhase === ConnectingPhase.Connected)
|
else if (this._connectingPhase === ConnectingPhase.Authentication || this._connectingPhase === ConnectingPhase.Connected)
|
||||||
this._manageHeartbeats();
|
this._manageHeartbeats();
|
||||||
break;
|
break;
|
||||||
@ -640,12 +688,13 @@ EventStoreConnectionLogicHandler.prototype._manageHeartbeats = function() {
|
|||||||
|
|
||||||
if (this._heartbeatInfo.isIntervalStage)
|
if (this._heartbeatInfo.isIntervalStage)
|
||||||
{
|
{
|
||||||
|
var correlationId = uuid.v4();
|
||||||
// TcpMessage.Heartbeat analog
|
// TcpMessage.Heartbeat analog
|
||||||
this._connection.enqueueSend(new TcpPackage(
|
this._connection.enqueueSend(new TcpPackage(
|
||||||
TcpCommand.HeartbeatRequestCommand,
|
TcpCommand.HeartbeatRequestCommand,
|
||||||
TcpFlags.None,
|
TcpFlags.None,
|
||||||
uuid.v4()));
|
correlationId));
|
||||||
this._heartbeatInfo = {lastPackageNumber: this._heartbeatInfo.lastPackageNumber, isIntervalStage: false, timeStamp: Date.now()};
|
this._heartbeatInfo = {correlationId: correlationId, lastPackageNumber: this._heartbeatInfo.lastPackageNumber, isIntervalStage: false, timeStamp: Date.now()};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8,11 +8,13 @@ function AccessDeniedError(action, streamOrTransactionId) {
|
|||||||
if (typeof streamOrTransactionId === 'string') {
|
if (typeof streamOrTransactionId === 'string') {
|
||||||
this.message = util.format("%s access denied for stream '%s'.", action, streamOrTransactionId);
|
this.message = util.format("%s access denied for stream '%s'.", action, streamOrTransactionId);
|
||||||
this.stream = streamOrTransactionId;
|
this.stream = streamOrTransactionId;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Long.isLong(streamOrTransactionId)) {
|
if (Long.isLong(streamOrTransactionId)) {
|
||||||
this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId);
|
this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId);
|
||||||
this.transactionId = streamOrTransactionId;
|
this.transactionId = streamOrTransactionId;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new TypeError("second argument must be a stream name or transaction Id.");
|
throw new TypeError("second argument must be a stream name or transaction Id.");
|
||||||
|
@ -7,11 +7,13 @@ function StreamDeletedError(streamOrTransactionId) {
|
|||||||
if (typeof streamOrTransactionId === 'string') {
|
if (typeof streamOrTransactionId === 'string') {
|
||||||
this.message = util.format("Event stream '%s' is deleted.", streamOrTransactionId);
|
this.message = util.format("Event stream '%s' is deleted.", streamOrTransactionId);
|
||||||
this.stream = streamOrTransactionId;
|
this.stream = streamOrTransactionId;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Long.isLong(streamOrTransactionId)) {
|
if (Long.isLong(streamOrTransactionId)) {
|
||||||
this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId);
|
this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId);
|
||||||
this.transactionId = streamOrTransactionId;
|
this.transactionId = streamOrTransactionId;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new TypeError("second argument must be a stream name or transaction Id.");
|
throw new TypeError("second argument must be a stream name or transaction Id.");
|
||||||
|
@ -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.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, streamOrTransactionId, expectedVersion);
|
||||||
this.stream = streamOrTransactionId;
|
this.stream = streamOrTransactionId;
|
||||||
this.expectedVersion = expectedVersion;
|
this.expectedVersion = expectedVersion;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Long.isLong(streamOrTransactionId)) {
|
if (Long.isLong(streamOrTransactionId)) {
|
||||||
this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId);
|
this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId);
|
||||||
this.transactionId = streamOrTransactionId;
|
this.transactionId = streamOrTransactionId;
|
||||||
|
Object.freeze(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new TypeError("second argument must be a stream name or a transaction Id.");
|
throw new TypeError("second argument must be a stream name or a transaction Id.");
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
|
|
||||||
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||||
function isValidId(id) {
|
function isValidId(id) {
|
||||||
if (typeof id !== 'string') return false;
|
if (typeof id !== 'string') return false;
|
||||||
var buf = uuid.parse(id);
|
return uuidRegex.test(id);
|
||||||
var valid = false;
|
|
||||||
for(var i=0;i<buf.length;i++)
|
|
||||||
if (buf[i] !== 0)
|
|
||||||
valid = true;
|
|
||||||
return valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,6 +28,7 @@ function EventData(eventId, type, isJson, data, metadata) {
|
|||||||
this.isJson = isJson || false;
|
this.isJson = isJson || false;
|
||||||
this.data = data || new Buffer(0);
|
this.data = data || new Buffer(0);
|
||||||
this.metadata = metadata || new Buffer(0);
|
this.metadata = metadata || new Buffer(0);
|
||||||
|
Object.freeze(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = EventData;
|
module.exports = EventData;
|
||||||
|
@ -24,14 +24,10 @@ EventStoreAllCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
function processEvents(events, index) {
|
function processEvents(events, index) {
|
||||||
index = index || 0;
|
|
||||||
if (index >= events.length) return Promise.resolve();
|
if (index >= events.length) return Promise.resolve();
|
||||||
if (events[index].originalPosition === null) throw new Error("Subscription event came up with no OriginalPosition.");
|
if (events[index].originalPosition === null) throw new Error("Subscription event came up with no OriginalPosition.");
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return self._tryProcess(events[index])
|
||||||
self._tryProcess(events[index]);
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return processEvents(events, index + 1);
|
return processEvents(events, index + 1);
|
||||||
});
|
});
|
||||||
@ -40,13 +36,12 @@ EventStoreAllCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
function readNext() {
|
function readNext() {
|
||||||
return connection.readAllEventsForward(self._nextReadPosition, self.readBatchSize, resolveLinkTos, userCredentials)
|
return connection.readAllEventsForward(self._nextReadPosition, self.readBatchSize, resolveLinkTos, userCredentials)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
return processEvents(slice.events)
|
return processEvents(slice.events, 0)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
self._nextReadPosition = slice.nextPosition;
|
self._nextReadPosition = slice.nextPosition;
|
||||||
var done = lastCommitPosition === null
|
return (lastCommitPosition === null)
|
||||||
? slice.isEndOfStream
|
? slice.isEndOfStream
|
||||||
: slice.nextPosition.compareTo(new results.Position(lastCommitPosition, lastCommitPosition)) >= 0;
|
: slice.nextPosition.compareTo(new results.Position(lastCommitPosition, lastCommitPosition)) >= 0;
|
||||||
return Promise.resolve(done);
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(function(done) {
|
.then(function(done) {
|
||||||
@ -67,9 +62,10 @@ EventStoreAllCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
|
|
||||||
EventStoreAllCatchUpSubscription.prototype._tryProcess = function(e) {
|
EventStoreAllCatchUpSubscription.prototype._tryProcess = function(e) {
|
||||||
var processed = false;
|
var processed = false;
|
||||||
|
var promise;
|
||||||
if (e.originalPosition.compareTo(this._lastProcessedPosition) > 0)
|
if (e.originalPosition.compareTo(this._lastProcessedPosition) > 0)
|
||||||
{
|
{
|
||||||
this._eventAppeared(this, e);
|
promise = this._eventAppeared(this, e);
|
||||||
this._lastProcessedPosition = e.originalPosition;
|
this._lastProcessedPosition = e.originalPosition;
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
@ -77,6 +73,7 @@ EventStoreAllCatchUpSubscription.prototype._tryProcess = function(e) {
|
|||||||
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %s).",
|
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %s).",
|
||||||
this.streamId || '<all>', processed ? "processed" : "skipping",
|
this.streamId || '<all>', processed ? "processed" : "skipping",
|
||||||
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalPosition);
|
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalPosition);
|
||||||
|
return (promise && promise.then) ? promise : Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = EventStoreAllCatchUpSubscription;
|
module.exports = EventStoreAllCatchUpSubscription;
|
||||||
|
@ -209,26 +209,35 @@ EventStoreCatchUpSubscription.prototype._ensureProcessingPushQueue = function()
|
|||||||
|
|
||||||
EventStoreCatchUpSubscription.prototype._processLiveQueue = function() {
|
EventStoreCatchUpSubscription.prototype._processLiveQueue = function() {
|
||||||
var ev = this._liveQueue.shift();
|
var ev = this._liveQueue.shift();
|
||||||
//TODO: possible blocking while, use when
|
if (!ev) {
|
||||||
while(ev) {
|
this._isProcessing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (ev instanceof DropSubscriptionEvent) {
|
if (ev instanceof DropSubscriptionEvent) {
|
||||||
if (!this._dropData) this._dropData = {reason: SubscriptionDropReason.Unknown, error: new Error("Drop reason not specified.")};
|
if (!this._dropData) this._dropData = {reason: SubscriptionDropReason.Unknown, error: new Error("Drop reason not specified.")};
|
||||||
this._dropSubscription(this._dropData.reason, this._dropData.error);
|
this._dropSubscription(this._dropData.reason, this._dropData.error);
|
||||||
this._isProcessing = false;
|
this._isProcessing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var promise;
|
||||||
try {
|
try {
|
||||||
this._tryProcess(ev);
|
promise = this._tryProcess(ev);
|
||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
|
this._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
|
||||||
|
this._isProcessing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ev = this._liveQueue.shift();
|
if (promise && promise.then) {
|
||||||
|
var self = this;
|
||||||
|
promise
|
||||||
|
.then(this._processLiveQueue.bind(this), function(err) {
|
||||||
|
self._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
|
||||||
|
self._isProcessing = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setImmediate(this._processLiveQueue.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._isProcessing = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EventStoreCatchUpSubscription.prototype._dropSubscription = function(reason, error) {
|
EventStoreCatchUpSubscription.prototype._dropSubscription = function(reason, error) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
|
var Long = require('long');
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var ensure = require('./common/utils/ensure');
|
var ensure = require('./common/utils/ensure');
|
||||||
|
|
||||||
@ -59,6 +60,9 @@ function EventStoreNodeConnection(settings, clusterSettings, endpointDiscoverer,
|
|||||||
this._handler.on('error', function(e) {
|
this._handler.on('error', function(e) {
|
||||||
self.emit('error', e);
|
self.emit('error', e);
|
||||||
});
|
});
|
||||||
|
this._handler.on('heartbeatInfo', function(e) {
|
||||||
|
self.emit('heartbeatInfo', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
util.inherits(EventStoreNodeConnection, EventEmitter);
|
util.inherits(EventStoreNodeConnection, EventEmitter);
|
||||||
|
|
||||||
@ -97,15 +101,16 @@ EventStoreNodeConnection.prototype.close = function() {
|
|||||||
* Delete a stream (async)
|
* Delete a stream (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} expectedVersion
|
* @param {Long|number} expectedVersion
|
||||||
* @param {boolean} [hardDelete]
|
* @param {boolean} [hardDelete]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<DeleteResult>}
|
* @returns {Promise.<DeleteResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) {
|
EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(expectedVersion, "expectedVersion");
|
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
||||||
hardDelete = !!hardDelete;
|
expectedVersion = Long.fromValue(expectedVersion);
|
||||||
|
hardDelete = Boolean(hardDelete);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -125,14 +130,15 @@ EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersi
|
|||||||
* Append events to a stream (async)
|
* Append events to a stream (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream The name of the stream to which to append.
|
* @param {string} stream The name of the stream to which to append.
|
||||||
* @param {number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed.
|
* @param {Long|number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed.
|
||||||
* @param {EventData[]|EventData} events The event(s) to append.
|
* @param {EventData[]|EventData} events The event(s) to append.
|
||||||
* @param {UserCredentials} [userCredentials] User credentials
|
* @param {UserCredentials} [userCredentials] User credentials
|
||||||
* @returns {Promise.<WriteResult>}
|
* @returns {Promise.<WriteResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) {
|
EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(expectedVersion, "expectedVersion");
|
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
||||||
|
expectedVersion = Long.fromValue(expectedVersion);
|
||||||
if (!Array.isArray(events))
|
if (!Array.isArray(events))
|
||||||
events = [events];
|
events = [events];
|
||||||
ensure.isArrayOf(EventData, events, "events");
|
ensure.isArrayOf(EventData, events, "events");
|
||||||
@ -154,13 +160,14 @@ EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVer
|
|||||||
* Start a transaction (async)
|
* Start a transaction (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} expectedVersion
|
* @param {Long|number} expectedVersion
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<EventStoreTransaction>}
|
* @returns {Promise.<EventStoreTransaction>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) {
|
EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(expectedVersion, "expectedVersion");
|
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
||||||
|
expectedVersion = Long.fromValue(expectedVersion);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -231,21 +238,20 @@ EventStoreNodeConnection.prototype.commitTransaction = function(transaction, use
|
|||||||
* Read a single event (async)
|
* Read a single event (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} eventNumber
|
* @param {Long|number} eventNumber
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<EventReadResult>}
|
* @returns {Promise.<EventReadResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(eventNumber, "eventNumber");
|
ensure.isLongOrInteger(eventNumber, "eventNumber");
|
||||||
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
eventNumber = Long.fromValue(eventNumber);
|
||||||
resolveLinkTos = !!resolveLinkTos;
|
resolveLinkTos = Boolean(resolveLinkTos);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
||||||
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
if (eventNumber.compare(-1) < 0) throw new Error("eventNumber out of range.");
|
||||||
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -264,7 +270,7 @@ EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, res
|
|||||||
* Reading a specific stream forwards (async)
|
* Reading a specific stream forwards (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} start
|
* @param {Long|number} start
|
||||||
* @param {number} count
|
* @param {number} count
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
@ -274,12 +280,13 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
|||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(start, "start");
|
ensure.isLongOrInteger(start, "start");
|
||||||
|
start = Long.fromValue(start);
|
||||||
ensure.nonNegative(start, "start");
|
ensure.nonNegative(start, "start");
|
||||||
ensure.isInteger(count, "count");
|
ensure.isInteger(count, "count");
|
||||||
ensure.positive(count, "count");
|
ensure.positive(count, "count");
|
||||||
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = !!resolveLinkTos;
|
resolveLinkTos = Boolean(resolveLinkTos);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -298,7 +305,7 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
|||||||
* Reading a specific stream backwards (async)
|
* Reading a specific stream backwards (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} start
|
* @param {Long|number} start
|
||||||
* @param {number} count
|
* @param {number} count
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
@ -308,11 +315,12 @@ EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
|||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isInteger(start, "start");
|
ensure.isLongOrInteger(start, "start");
|
||||||
|
start = Long.fromValue(start);
|
||||||
ensure.isInteger(count, "count");
|
ensure.isInteger(count, "count");
|
||||||
ensure.positive(count, "count");
|
ensure.positive(count, "count");
|
||||||
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = !!resolveLinkTos;
|
resolveLinkTos = Boolean(resolveLinkTos);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -343,7 +351,7 @@ EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
|||||||
ensure.isInteger(maxCount, "maxCount");
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
ensure.positive(maxCount, "maxCount");
|
ensure.positive(maxCount, "maxCount");
|
||||||
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = !!resolveLinkTos;
|
resolveLinkTos = Boolean(resolveLinkTos);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -374,7 +382,7 @@ EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
|||||||
ensure.isInteger(maxCount, "maxCount");
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
ensure.positive(maxCount, "maxCount");
|
ensure.positive(maxCount, "maxCount");
|
||||||
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = !!resolveLinkTos;
|
resolveLinkTos = Boolean(resolveLinkTos);
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -424,7 +432,7 @@ EventStoreNodeConnection.prototype.subscribeToStream = function(
|
|||||||
* Subscribe to a stream from position
|
* Subscribe to a stream from position
|
||||||
* @public
|
* @public
|
||||||
* @param {!string} stream
|
* @param {!string} stream
|
||||||
* @param {?number} lastCheckpoint
|
* @param {?number|Position} lastCheckpoint
|
||||||
* @param {!boolean} resolveLinkTos
|
* @param {!boolean} resolveLinkTos
|
||||||
* @param {!function} eventAppeared
|
* @param {!function} eventAppeared
|
||||||
* @param {function} [liveProcessingStarted]
|
* @param {function} [liveProcessingStarted]
|
||||||
@ -438,6 +446,10 @@ EventStoreNodeConnection.prototype.subscribeToStreamFrom = function(
|
|||||||
userCredentials, readBatchSize
|
userCredentials, readBatchSize
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string.");
|
||||||
|
if (lastCheckpoint !== null) {
|
||||||
|
ensure.isLongOrInteger(lastCheckpoint);
|
||||||
|
lastCheckpoint = Long.fromValue(lastCheckpoint);
|
||||||
|
}
|
||||||
if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function.");
|
if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function.");
|
||||||
|
|
||||||
var catchUpSubscription =
|
var catchUpSubscription =
|
||||||
@ -515,7 +527,7 @@ EventStoreNodeConnection.prototype.subscribeToAllFrom = function(
|
|||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @param {number} [bufferSize]
|
* @param {number} [bufferSize]
|
||||||
* @param {boolean} [autoAck]
|
* @param {boolean} [autoAck]
|
||||||
* @return {EventStorePersistentSubscription}
|
* @return {Promise<EventStorePersistentSubscription>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.connectToPersistentSubscription = function(
|
EventStoreNodeConnection.prototype.connectToPersistentSubscription = function(
|
||||||
stream, groupName, eventAppeared, subscriptionDropped, userCredentials, bufferSize, autoAck
|
stream, groupName, eventAppeared, subscriptionDropped, userCredentials, bufferSize, autoAck
|
||||||
@ -527,14 +539,12 @@ EventStoreNodeConnection.prototype.connectToPersistentSubscription = function(
|
|||||||
subscriptionDropped = subscriptionDropped || null;
|
subscriptionDropped = subscriptionDropped || null;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
bufferSize = bufferSize === undefined ? 10 : bufferSize;
|
bufferSize = bufferSize === undefined ? 10 : bufferSize;
|
||||||
autoAck = autoAck === undefined ? true : !!autoAck;
|
autoAck = autoAck === undefined ? true : Boolean(autoAck);
|
||||||
|
|
||||||
var subscription = new EventStorePersistentSubscription(
|
var subscription = new EventStorePersistentSubscription(
|
||||||
groupName, stream, eventAppeared, subscriptionDropped, userCredentials, this._settings.log,
|
groupName, stream, eventAppeared, subscriptionDropped, userCredentials, this._settings.log,
|
||||||
this._settings.verboseLogging, this._settings, this._handler, bufferSize, autoAck);
|
this._settings.verboseLogging, this._settings, this._handler, bufferSize, autoAck);
|
||||||
subscription.start();
|
return subscription.start();
|
||||||
|
|
||||||
return subscription;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -567,7 +577,7 @@ EventStoreNodeConnection.prototype.createPersistentSubscription = function(strea
|
|||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {string} groupName
|
* @param {string} groupName
|
||||||
* @param {string} settings
|
* @param {PersistentSubscriptionSettings} settings
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<PersistentSubscriptionUpdateResult>}
|
* @returns {Promise.<PersistentSubscriptionUpdateResult>}
|
||||||
*/
|
*/
|
||||||
@ -621,7 +631,7 @@ EventStoreNodeConnection.prototype.setStreamMetadata = function() {
|
|||||||
* Set stream metadata with raw object (async)
|
* Set stream metadata with raw object (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} expectedMetastreamVersion
|
* @param {Long|number} expectedMetastreamVersion
|
||||||
* @param {object} metadata
|
* @param {object} metadata
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<WriteResult>}
|
* @returns {Promise.<WriteResult>}
|
||||||
@ -632,6 +642,8 @@ EventStoreNodeConnection.prototype.setStreamMetadataRaw = function(
|
|||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (systemStreams.isMetastream(stream))
|
if (systemStreams.isMetastream(stream))
|
||||||
throw new Error(util.format("Setting metadata for metastream '%s' is not supported.", stream));
|
throw new Error(util.format("Setting metadata for metastream '%s' is not supported.", stream));
|
||||||
|
ensure.isLongOrInteger(expectedMetastreamVersion, "expectedMetastreamVersion");
|
||||||
|
expectedMetastreamVersion = Long.fromValue(expectedMetastreamVersion);
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
function cb(err, result) {
|
function cb(err, result) {
|
||||||
@ -674,12 +686,12 @@ EventStoreNodeConnection.prototype.getStreamMetadataRaw = function(stream, userC
|
|||||||
var evnt = res.event.originalEvent;
|
var evnt = res.event.originalEvent;
|
||||||
var version = evnt ? evnt.eventNumber : -1;
|
var version = evnt ? evnt.eventNumber : -1;
|
||||||
var data = evnt ? JSON.parse(evnt.data.toString()) : null;
|
var data = evnt ? JSON.parse(evnt.data.toString()) : null;
|
||||||
return new results.RawStreamMetadataResult(stream, false, version, data);
|
return new results.RawStreamMetadataResult(stream, false, Long.fromValue(version), data);
|
||||||
case results.EventReadStatus.NotFound:
|
case results.EventReadStatus.NotFound:
|
||||||
case results.EventReadStatus.NoStream:
|
case results.EventReadStatus.NoStream:
|
||||||
return new results.RawStreamMetadataResult(stream, false, -1, null);
|
return new results.RawStreamMetadataResult(stream, false, Long.fromValue(-1), null);
|
||||||
case results.EventReadStatus.StreamDeleted:
|
case results.EventReadStatus.StreamDeleted:
|
||||||
return new results.RawStreamMetadataResult(stream, true, 0x7fffffff, null);
|
return new results.RawStreamMetadataResult(stream, true, Long.fromValue(0x7fffffff), null);
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status));
|
throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status));
|
||||||
}
|
}
|
||||||
|
@ -35,11 +35,12 @@ EventStorePersistentSubscriptionBase.prototype.start = function() {
|
|||||||
this._stopped = false;
|
this._stopped = false;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this._startSubscription(this._subscriptionId, this._streamId, this._bufferSize, this._userCredentials,
|
return 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.');
|
console.log('Subscription started.');
|
||||||
self._subscription = subscription;
|
self._subscription = subscription;
|
||||||
|
return self;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ EventStorePersistentSubscriptionBase.prototype.fail = function(events, action, r
|
|||||||
this._subscription.notifyEventsFailed(ids, action, reason);
|
this._subscription.notifyEventsFailed(ids, action, reason);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//TODO: this should return a promise
|
||||||
EventStorePersistentSubscriptionBase.prototype.stop = function() {
|
EventStorePersistentSubscriptionBase.prototype.stop = function() {
|
||||||
if (this._verbose) this._log.debug("Persistent Subscription to %s: requesting stop...", this._streamId);
|
if (this._verbose) this._log.debug("Persistent Subscription to %s: requesting stop...", this._streamId);
|
||||||
this._enqueueSubscriptionDropNotification(SubscriptionDropReason.UserInitiated, null);
|
this._enqueueSubscriptionDropNotification(SubscriptionDropReason.UserInitiated, null);
|
||||||
@ -110,43 +112,56 @@ EventStorePersistentSubscriptionBase.prototype._enqueue = function(resolvedEvent
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function runAsync(fn) {
|
||||||
|
try {
|
||||||
|
return Promise.resolve(fn());
|
||||||
|
} catch(e) {
|
||||||
|
return Promise.reject(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EventStorePersistentSubscriptionBase.prototype._processQueue = function() {
|
EventStorePersistentSubscriptionBase.prototype._processQueue = function() {
|
||||||
//do
|
var ev = this._queue.shift();
|
||||||
//{
|
if (!ev) {
|
||||||
var e = this._queue.shift();
|
this._isProcessing = false;
|
||||||
while (e)
|
return;
|
||||||
{
|
}
|
||||||
if (e instanceof DropSubscriptionEvent) // drop subscription artificial ResolvedEvent
|
|
||||||
|
if (ev instanceof DropSubscriptionEvent) // drop subscription artificial ResolvedEvent
|
||||||
{
|
{
|
||||||
if (this._dropData === null) throw new Error("Drop reason not specified.");
|
if (this._dropData === null) throw new Error("Drop reason not specified.");
|
||||||
this._dropSubscription(this._dropData.reason, this._dropData.error);
|
this._dropSubscription(this._dropData.reason, this._dropData.error);
|
||||||
|
this._isProcessing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._dropData !== null)
|
if (this._dropData !== null)
|
||||||
{
|
{
|
||||||
this._dropSubscription(this._dropData.reason, this._dropData.error);
|
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();
|
|
||||||
}
|
|
||||||
this._isProcessing = false;
|
this._isProcessing = false;
|
||||||
//} while (_queue.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) === 0);
|
return;
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
|
runAsync(function() {
|
||||||
|
return self._eventAppeared(self, ev);
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
if(self._autoAck)
|
||||||
|
self._subscription.notifyEventsProcessed([ev.originalEvent.eventId]);
|
||||||
|
if (self._verbose)
|
||||||
|
self._log.debug("Persistent Subscription to %s: processed event (%s, %d, %s @ %d).",
|
||||||
|
self._streamId, ev.originalEvent.eventStreamId, ev.originalEvent.eventNumber, ev.originalEvent.eventType,
|
||||||
|
ev.originalEventNumber);
|
||||||
|
return false;
|
||||||
|
}, function(err) {
|
||||||
|
//TODO GFY should we autonak here?
|
||||||
|
self._dropSubscription(SubscriptionDropReason.EventHandlerException, err);
|
||||||
|
self._isProcessing = false;
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.then(function (faulted) {
|
||||||
|
if (faulted) return;
|
||||||
|
self._processQueue();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) {
|
EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) {
|
||||||
@ -159,8 +174,13 @@ EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reas
|
|||||||
|
|
||||||
if (this._subscription !== null)
|
if (this._subscription !== null)
|
||||||
this._subscription.unsubscribe();
|
this._subscription.unsubscribe();
|
||||||
if (this._subscriptionDropped !== null)
|
if (this._subscriptionDropped !== null) {
|
||||||
|
try {
|
||||||
this._subscriptionDropped(this, reason, error);
|
this._subscriptionDropped(this, reason, error);
|
||||||
|
} catch (e) {
|
||||||
|
this._log.error(e, "Persistent Subscription to %s: subscriptionDropped callback failed.", this._streamId);
|
||||||
|
}
|
||||||
|
}
|
||||||
this._stopped = true;
|
this._stopped = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
var EventStoreCatchUpSubscription = require('./eventStoreCatchUpSubscription');
|
var EventStoreCatchUpSubscription = require('./eventStoreCatchUpSubscription');
|
||||||
var SliceReadStatus = require('./sliceReadStatus');
|
var SliceReadStatus = require('./sliceReadStatus');
|
||||||
@ -14,24 +15,26 @@ function EventStoreStreamCatchUpSubscription(
|
|||||||
|
|
||||||
//Ensure.NotNullOrEmpty(streamId, "streamId");
|
//Ensure.NotNullOrEmpty(streamId, "streamId");
|
||||||
|
|
||||||
this._lastProcessedEventNumber = fromEventNumberExclusive || -1;
|
this._lastProcessedEventNumber = fromEventNumberExclusive === null ? Long.fromNumber(-1) : fromEventNumberExclusive;
|
||||||
this._nextReadEventNumber = fromEventNumberExclusive || 0;
|
this._nextReadEventNumber = fromEventNumberExclusive === null ? Long.fromNumber(0) : fromEventNumberExclusive.add(1);
|
||||||
}
|
}
|
||||||
util.inherits(EventStoreStreamCatchUpSubscription, EventStoreCatchUpSubscription);
|
util.inherits(EventStoreStreamCatchUpSubscription, EventStoreCatchUpSubscription);
|
||||||
|
|
||||||
|
function delay(ms, result) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms, result);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
||||||
connection, resolveLinkTos, userCredentials, lastCommitPosition, lastEventNumber
|
connection, resolveLinkTos, userCredentials, lastCommitPosition, lastEventNumber
|
||||||
) {
|
) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
function processEvents(events, index) {
|
function processEvents(events, index) {
|
||||||
index = index || 0;
|
|
||||||
if (index >= events.length) return Promise.resolve();
|
if (index >= events.length) return Promise.resolve();
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return self._tryProcess(events[index])
|
||||||
self._tryProcess(events[index]);
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return processEvents(events, index + 1);
|
return processEvents(events, index + 1);
|
||||||
});
|
});
|
||||||
@ -42,17 +45,17 @@ EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
switch(slice.status) {
|
switch(slice.status) {
|
||||||
case SliceReadStatus.Success:
|
case SliceReadStatus.Success:
|
||||||
return processEvents(slice.events)
|
return processEvents(slice.events, 0)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
self._nextReadEventNumber = slice.nextEventNumber;
|
self._nextReadEventNumber = slice.nextEventNumber;
|
||||||
var done = Promise.resolve(lastEventNumber === null ? slice.isEndOfStream : slice.nextEventNumber > lastEventNumber);
|
var done = Promise.resolve(lastEventNumber === null ? slice.isEndOfStream : slice.nextEventNumber.compare(lastEventNumber) > 0);
|
||||||
if (!done && slice.isEndOfStream)
|
if (!done && slice.isEndOfStream)
|
||||||
return done.delay(10);
|
return delay(100, false);
|
||||||
return done;
|
return done;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case SliceReadStatus.StreamNotFound:
|
case SliceReadStatus.StreamNotFound:
|
||||||
if (lastEventNumber && lastEventNumber !== -1)
|
if (lastEventNumber && lastEventNumber.compare(-1) !== 0)
|
||||||
throw new Error(util.format("Impossible: stream %s disappeared in the middle of catching up subscription.", self.streamId));
|
throw new Error(util.format("Impossible: stream %s disappeared in the middle of catching up subscription.", self.streamId));
|
||||||
return true;
|
return true;
|
||||||
case SliceReadStatus.StreamDeleted:
|
case SliceReadStatus.StreamDeleted:
|
||||||
@ -77,15 +80,17 @@ EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
|
|
||||||
EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) {
|
EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) {
|
||||||
var processed = false;
|
var processed = false;
|
||||||
if (e.originalEventNumber > this._lastProcessedEventNumber) {
|
var promise;
|
||||||
this._eventAppeared(this, e);
|
if (e.originalEventNumber.compare(this._lastProcessedEventNumber) > 0) {
|
||||||
|
promise = this._eventAppeared(this, e);
|
||||||
this._lastProcessedEventNumber = e.originalEventNumber;
|
this._lastProcessedEventNumber = e.originalEventNumber;
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
if (this._verbose)
|
if (this._verbose)
|
||||||
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %d).",
|
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %d).",
|
||||||
this.isSubscribedToAll ? '<all>' : this.streamId, processed ? "processed" : "skipping",
|
this.isSubscribedToAll ? '<all>' : this.streamId, processed ? "processed" : "skipping",
|
||||||
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalEventNumber)
|
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalEventNumber);
|
||||||
|
return (promise && promise.then) ? promise : Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
module.exports = function GossipSeed(endPoint, hostName) {
|
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.');
|
if (typeof endPoint !== 'object' || !endPoint.host || !endPoint.port) throw new TypeError('endPoint must be have host and port properties.');
|
||||||
Object.defineProperties(this, {
|
this.endPoint = endPoint;
|
||||||
endPoint: {
|
this.hostName = hostName;
|
||||||
enumerable: true,
|
Object.freeze(this);
|
||||||
value: endPoint
|
|
||||||
},
|
|
||||||
hostName: {
|
|
||||||
enumerable: true,
|
|
||||||
value: hostName
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
12811
src/messages/messages.js
12811
src/messages/messages.js
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ message NewEvent {
|
|||||||
|
|
||||||
message EventRecord {
|
message EventRecord {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 event_number = 2;
|
required int64 event_number = 2;
|
||||||
required bytes event_id = 3;
|
required bytes event_id = 3;
|
||||||
required string event_type = 4;
|
required string event_type = 4;
|
||||||
required int32 data_content_type = 5;
|
required int32 data_content_type = 5;
|
||||||
@ -48,7 +48,7 @@ message ResolvedEvent {
|
|||||||
|
|
||||||
message WriteEvents {
|
message WriteEvents {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 expected_version = 2;
|
required int64 expected_version = 2;
|
||||||
repeated NewEvent events = 3;
|
repeated NewEvent events = 3;
|
||||||
required bool require_master = 4;
|
required bool require_master = 4;
|
||||||
}
|
}
|
||||||
@ -56,15 +56,16 @@ message WriteEvents {
|
|||||||
message WriteEventsCompleted {
|
message WriteEventsCompleted {
|
||||||
required OperationResult result = 1;
|
required OperationResult result = 1;
|
||||||
optional string message = 2;
|
optional string message = 2;
|
||||||
required int32 first_event_number = 3;
|
required int64 first_event_number = 3;
|
||||||
required int32 last_event_number = 4;
|
required int64 last_event_number = 4;
|
||||||
optional int64 prepare_position = 5;
|
optional int64 prepare_position = 5;
|
||||||
optional int64 commit_position = 6;
|
optional int64 commit_position = 6;
|
||||||
|
optional int64 current_version = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteStream {
|
message DeleteStream {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 expected_version = 2;
|
required int64 expected_version = 2;
|
||||||
required bool require_master = 3;
|
required bool require_master = 3;
|
||||||
optional bool hard_delete = 4;
|
optional bool hard_delete = 4;
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ message DeleteStreamCompleted {
|
|||||||
|
|
||||||
message TransactionStart {
|
message TransactionStart {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 expected_version = 2;
|
required int64 expected_version = 2;
|
||||||
required bool require_master = 3;
|
required bool require_master = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,15 +110,15 @@ message TransactionCommitCompleted {
|
|||||||
required int64 transaction_id = 1;
|
required int64 transaction_id = 1;
|
||||||
required OperationResult result = 2;
|
required OperationResult result = 2;
|
||||||
optional string message = 3;
|
optional string message = 3;
|
||||||
required int32 first_event_number = 4;
|
required int64 first_event_number = 4;
|
||||||
required int32 last_event_number = 5;
|
required int64 last_event_number = 5;
|
||||||
optional int64 prepare_position = 6;
|
optional int64 prepare_position = 6;
|
||||||
optional int64 commit_position = 7;
|
optional int64 commit_position = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ReadEvent {
|
message ReadEvent {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 event_number = 2;
|
required int64 event_number = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required bool require_master = 4;
|
required bool require_master = 4;
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ message ReadEventCompleted {
|
|||||||
|
|
||||||
message ReadStreamEvents {
|
message ReadStreamEvents {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int32 from_event_number = 2;
|
required int64 from_event_number = 2;
|
||||||
required int32 max_count = 3;
|
required int32 max_count = 3;
|
||||||
required bool resolve_link_tos = 4;
|
required bool resolve_link_tos = 4;
|
||||||
required bool require_master = 5;
|
required bool require_master = 5;
|
||||||
@ -160,8 +161,8 @@ message ReadStreamEventsCompleted {
|
|||||||
|
|
||||||
repeated ResolvedIndexedEvent events = 1;
|
repeated ResolvedIndexedEvent events = 1;
|
||||||
required ReadStreamResult result = 2;
|
required ReadStreamResult result = 2;
|
||||||
required int32 next_event_number = 3;
|
required int64 next_event_number = 3;
|
||||||
required int32 last_event_number = 4;
|
required int64 last_event_number = 4;
|
||||||
required bool is_end_of_stream = 5;
|
required bool is_end_of_stream = 5;
|
||||||
required int64 last_commit_position = 6;
|
required int64 last_commit_position = 6;
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ message CreatePersistentSubscription {
|
|||||||
required string subscription_group_name = 1;
|
required string subscription_group_name = 1;
|
||||||
required string event_stream_id = 2;
|
required string event_stream_id = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required int32 start_from = 4;
|
required int64 start_from = 4;
|
||||||
required int32 message_timeout_milliseconds = 5;
|
required int32 message_timeout_milliseconds = 5;
|
||||||
required bool record_statistics = 6;
|
required bool record_statistics = 6;
|
||||||
required int32 live_buffer_size = 7;
|
required int32 live_buffer_size = 7;
|
||||||
@ -223,7 +224,7 @@ message UpdatePersistentSubscription {
|
|||||||
required string subscription_group_name = 1;
|
required string subscription_group_name = 1;
|
||||||
required string event_stream_id = 2;
|
required string event_stream_id = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required int32 start_from = 4;
|
required int64 start_from = 4;
|
||||||
required int32 message_timeout_milliseconds = 5;
|
required int32 message_timeout_milliseconds = 5;
|
||||||
required bool record_statistics = 6;
|
required bool record_statistics = 6;
|
||||||
required int32 live_buffer_size = 7;
|
required int32 live_buffer_size = 7;
|
||||||
@ -301,7 +302,7 @@ message PersistentSubscriptionNakEvents {
|
|||||||
message PersistentSubscriptionConfirmation {
|
message PersistentSubscriptionConfirmation {
|
||||||
required int64 last_commit_position = 1;
|
required int64 last_commit_position = 1;
|
||||||
required string subscription_id = 2;
|
required string subscription_id = 2;
|
||||||
optional int32 last_event_number = 3;
|
optional int64 last_event_number = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PersistentSubscriptionStreamEventAppeared {
|
message PersistentSubscriptionStreamEventAppeared {
|
||||||
@ -315,7 +316,7 @@ message SubscribeToStream {
|
|||||||
|
|
||||||
message SubscriptionConfirmation {
|
message SubscriptionConfirmation {
|
||||||
required int64 last_commit_position = 1;
|
required int64 last_commit_position = 1;
|
||||||
optional int32 last_event_number = 2;
|
optional int64 last_event_number = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StreamEventAppeared {
|
message StreamEventAppeared {
|
||||||
@ -375,3 +376,11 @@ message ScavengeDatabaseCompleted {
|
|||||||
required int32 total_time_ms = 3;
|
required int32 total_time_ms = 3;
|
||||||
required int64 total_space_saved = 4;
|
required int64 total_space_saved = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message IdentifyClient {
|
||||||
|
required int32 version = 1;
|
||||||
|
optional string connection_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ClientIdentified {
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
var SystemConsumerStrategies = require('./systemConsumerStrategies');
|
var SystemConsumerStrategies = require('./systemConsumerStrategies');
|
||||||
|
var ensure = require('./common/utils/ensure');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
function PersistentSubscriptionSettings(
|
function PersistentSubscriptionSettings(
|
||||||
resolveLinkTos, startFrom, extraStatistics, messageTimeout,
|
resolveLinkTos, startFrom, extraStatistics, messageTimeout,
|
||||||
@ -6,6 +8,9 @@ function PersistentSubscriptionSettings(
|
|||||||
checkPointAfter, minCheckPointCount, maxCheckPointCount,
|
checkPointAfter, minCheckPointCount, maxCheckPointCount,
|
||||||
maxSubscriberCount, namedConsumerStrategy
|
maxSubscriberCount, namedConsumerStrategy
|
||||||
) {
|
) {
|
||||||
|
ensure.isLongOrInteger(startFrom);
|
||||||
|
startFrom = Long.fromValue(startFrom);
|
||||||
|
|
||||||
this.resolveLinkTos = resolveLinkTos;
|
this.resolveLinkTos = resolveLinkTos;
|
||||||
this.startFrom = startFrom;
|
this.startFrom = startFrom;
|
||||||
this.extraStatistics = extraStatistics;
|
this.extraStatistics = extraStatistics;
|
||||||
|
230
src/results.js
230
src/results.js
@ -1,5 +1,4 @@
|
|||||||
var util = require('util');
|
var guidParse = require('./common/guid-parse');
|
||||||
var uuid = require('uuid');
|
|
||||||
var Long = require('long');
|
var Long = require('long');
|
||||||
var ensure = require('./common/utils/ensure');
|
var ensure = require('./common/utils/ensure');
|
||||||
|
|
||||||
@ -14,17 +13,9 @@ var ensure = require('./common/utils/ensure');
|
|||||||
function Position(commitPosition, preparePosition) {
|
function Position(commitPosition, preparePosition) {
|
||||||
ensure.notNull(commitPosition, "commitPosition");
|
ensure.notNull(commitPosition, "commitPosition");
|
||||||
ensure.notNull(preparePosition, "preparePosition");
|
ensure.notNull(preparePosition, "preparePosition");
|
||||||
commitPosition = Long.fromValue(commitPosition);
|
this.commitPosition = Long.fromValue(commitPosition);
|
||||||
preparePosition = Long.fromValue(preparePosition);
|
this.preparePosition = Long.fromValue(preparePosition);
|
||||||
|
Object.freeze(this);
|
||||||
Object.defineProperties(this, {
|
|
||||||
commitPosition: {
|
|
||||||
enumerable: true, value: commitPosition
|
|
||||||
},
|
|
||||||
preparePosition: {
|
|
||||||
enumerable: true, value: preparePosition
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Position.prototype.compareTo = function(other) {
|
Position.prototype.compareTo = function(other) {
|
||||||
@ -46,13 +37,14 @@ const EventReadStatus = {
|
|||||||
NoStream: 'noStream',
|
NoStream: 'noStream',
|
||||||
StreamDeleted: 'streamDeleted'
|
StreamDeleted: 'streamDeleted'
|
||||||
};
|
};
|
||||||
|
Object.freeze(EventReadStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} ev
|
* @param {object} ev
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} eventStreamId
|
* @property {string} eventStreamId
|
||||||
* @property {string} eventId
|
* @property {string} eventId
|
||||||
* @property {number} eventNumber
|
* @property {Long} eventNumber
|
||||||
* @property {string} eventType
|
* @property {string} eventType
|
||||||
* @property {number} createdEpoch
|
* @property {number} createdEpoch
|
||||||
* @property {?Buffer} data
|
* @property {?Buffer} data
|
||||||
@ -60,18 +52,16 @@ const EventReadStatus = {
|
|||||||
* @property {boolean} isJson
|
* @property {boolean} isJson
|
||||||
*/
|
*/
|
||||||
function RecordedEvent(ev) {
|
function RecordedEvent(ev) {
|
||||||
Object.defineProperties(this, {
|
this.eventStreamId = ev.eventStreamId;
|
||||||
eventStreamId: {enumerable: true, value: ev.event_stream_id},
|
this.eventId = guidParse.unparse(ev.eventId);
|
||||||
eventId: {enumerable: true, value: uuid.unparse(ev.event_id.buffer, ev.event_id.offset)},
|
this.eventNumber = ev.eventNumber;
|
||||||
eventNumber: {enumerable: true, value: ev.event_number},
|
this.eventType = ev.eventType;
|
||||||
eventType: {enumerable: true, value: ev.event_type},
|
this.created = new Date(ev.createdEpoch ? ev.createdEpoch.toNumber() : 0);
|
||||||
//Javascript doesn't have .Net precision for time, so we use created_epoch for created
|
this.createdEpoch = ev.createdEpoch ? ev.createdEpoch.toNumber() : 0;
|
||||||
created: {enumerable: true, value: new Date(ev.created_epoch ? ev.created_epoch.toNumber() : 0)},
|
this.data = ev.data ? ev.data : new Buffer(0);
|
||||||
createdEpoch: {enumerable: true, value: ev.created_epoch ? ev.created_epoch.toNumber() : 0},
|
this.metadata = ev.metadata ? ev.metadata : new Buffer(0);
|
||||||
data: {enumerable: true, value: ev.data ? ev.data.toBuffer() : new Buffer(0)},
|
this.isJson = ev.dataContentType === 1;
|
||||||
metadata: {enumerable: true, value: ev.metadata ? ev.metadata.toBuffer() : new Buffer(0)},
|
Object.freeze(this);
|
||||||
isJson: {enumerable: true, value: ev.data_content_type === 1}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,138 +73,83 @@ function RecordedEvent(ev) {
|
|||||||
* @property {boolean} isResolved
|
* @property {boolean} isResolved
|
||||||
* @property {?Position} originalPosition
|
* @property {?Position} originalPosition
|
||||||
* @property {string} originalStreamId
|
* @property {string} originalStreamId
|
||||||
* @property {number} originalEventNumber
|
* @property {Long} originalEventNumber
|
||||||
*/
|
*/
|
||||||
function ResolvedEvent(ev) {
|
function ResolvedEvent(ev) {
|
||||||
Object.defineProperties(this, {
|
this.event = ev.event === null ? null : new RecordedEvent(ev.event);
|
||||||
event: {
|
this.link = ev.link === null ? null : new RecordedEvent(ev.link);
|
||||||
enumerable: true,
|
this.originalEvent = this.link || this.event;
|
||||||
value: ev.event === null ? null : new RecordedEvent(ev.event)
|
this.isResolved = this.link !== null && this.event !== null;
|
||||||
},
|
this.originalPosition = (ev.commitPosition && ev.preparePosition) ? new Position(ev.commitPosition, ev.preparePosition) : null;
|
||||||
link: {
|
this.originalStreamId = this.originalEvent && this.originalEvent.eventStreamId;
|
||||||
enumerable: true,
|
this.originalEventNumber = this.originalEvent && this.originalEvent.eventNumber;
|
||||||
value: ev.link === null ? null : new RecordedEvent(ev.link)
|
Object.freeze(this);
|
||||||
},
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} eventNumber
|
* @param {Long} eventNumber
|
||||||
* @param {object} event
|
* @param {object} event
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} status
|
* @property {string} status
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {number} eventNumber
|
* @property {Long} eventNumber
|
||||||
* @property {ResolvedEvent} event
|
* @property {ResolvedEvent} event
|
||||||
*/
|
*/
|
||||||
function EventReadResult(status, stream, eventNumber, event) {
|
function EventReadResult(status, stream, eventNumber, event) {
|
||||||
Object.defineProperties(this, {
|
this.status = status;
|
||||||
status: {enumerable: true, value: status},
|
this.stream = stream;
|
||||||
stream: {enumerable: true, value: stream},
|
this.eventNumber = eventNumber;
|
||||||
eventNumber: {enumerable: true, value: eventNumber},
|
this.event = status === EventReadStatus.Success ? new ResolvedEvent(event) : null;
|
||||||
event: {
|
Object.freeze(this);
|
||||||
enumerable: true, value: status === EventReadStatus.Success ? new ResolvedEvent(event) : null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} nextExpectedVersion
|
* @param {number} nextExpectedVersion
|
||||||
* @param {Position} logPosition
|
* @param {Position} logPosition
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {number} nextExpectedVersion
|
* @property {Long} nextExpectedVersion
|
||||||
* @property {Position} logPosition
|
* @property {Position} logPosition
|
||||||
*/
|
*/
|
||||||
function WriteResult(nextExpectedVersion, logPosition) {
|
function WriteResult(nextExpectedVersion, logPosition) {
|
||||||
Object.defineProperties(this, {
|
this.nextExpectedVersion = nextExpectedVersion;
|
||||||
nextExpectedVersion: {
|
this.logPosition = logPosition;
|
||||||
enumerable: true, value: nextExpectedVersion
|
Object.freeze(this);
|
||||||
},
|
|
||||||
logPosition: {
|
|
||||||
enumerable: true, value: logPosition
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {number} fromEventNumber
|
* @param {Long} fromEventNumber
|
||||||
* @param {string} readDirection
|
* @param {string} readDirection
|
||||||
* @param {object[]} events
|
* @param {object[]} events
|
||||||
* @param {number} nextEventNumber
|
* @param {Long} nextEventNumber
|
||||||
* @param {number} lastEventNumber
|
* @param {Long} lastEventNumber
|
||||||
* @param {boolean} isEndOfStream
|
* @param {boolean} isEndOfStream
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} status
|
* @property {string} status
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {number} fromEventNumber
|
* @property {Long} fromEventNumber
|
||||||
* @property {string} readDirection
|
* @property {string} readDirection
|
||||||
* @property {ResolvedEvent[]} events
|
* @property {ResolvedEvent[]} events
|
||||||
* @property {number} nextEventNumber
|
* @property {Long} nextEventNumber
|
||||||
* @property {number} lastEventNumber
|
* @property {Long} lastEventNumber
|
||||||
* @property {boolean} isEndOfStream
|
* @property {boolean} isEndOfStream
|
||||||
*/
|
*/
|
||||||
function StreamEventsSlice(
|
function StreamEventsSlice(
|
||||||
status, stream, fromEventNumber, readDirection, events, nextEventNumber, lastEventNumber, isEndOfStream
|
status, stream, fromEventNumber, readDirection, events, nextEventNumber, lastEventNumber, isEndOfStream
|
||||||
) {
|
) {
|
||||||
Object.defineProperties(this, {
|
this.status = status;
|
||||||
status: {
|
this.stream = stream;
|
||||||
enumerable: true, value: status
|
this.fromEventNumber = fromEventNumber;
|
||||||
},
|
this.readDirection = readDirection;
|
||||||
stream: {
|
this.events = events ? events.map(function(ev) { return new ResolvedEvent(ev); }) : [];
|
||||||
enumerable: true, value: stream
|
this.nextEventNumber = nextEventNumber;
|
||||||
},
|
this.lastEventNumber = lastEventNumber;
|
||||||
fromEventNumber: {
|
this.isEndOfStream = isEndOfStream;
|
||||||
enumerable: true, value: fromEventNumber
|
Object.freeze(this);
|
||||||
},
|
|
||||||
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
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,23 +164,12 @@ function StreamEventsSlice(
|
|||||||
* @property {ResolvedEvent[]} events
|
* @property {ResolvedEvent[]} events
|
||||||
*/
|
*/
|
||||||
function AllEventsSlice(readDirection, fromPosition, nextPosition, events) {
|
function AllEventsSlice(readDirection, fromPosition, nextPosition, events) {
|
||||||
Object.defineProperties(this, {
|
this.readDirection = readDirection;
|
||||||
readDirection: {
|
this.fromPosition = fromPosition;
|
||||||
enumerable: true, value: readDirection
|
this.nextPosition = nextPosition;
|
||||||
},
|
this.events = events ? events.map(function(ev){ return new ResolvedEvent(ev); }) : [];
|
||||||
fromPosition: {
|
this.isEndOfStream = events === null || events.length === 0;
|
||||||
enumerable: true, value: fromPosition
|
Object.freeze(this);
|
||||||
},
|
|
||||||
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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,32 +178,28 @@ function AllEventsSlice(readDirection, fromPosition, nextPosition, events) {
|
|||||||
* @property {Position} logPosition
|
* @property {Position} logPosition
|
||||||
*/
|
*/
|
||||||
function DeleteResult(logPosition) {
|
function DeleteResult(logPosition) {
|
||||||
Object.defineProperties(this, {
|
this.logPosition = logPosition;
|
||||||
logPosition: {
|
Object.freeze(this);
|
||||||
enumerable: true, value: logPosition
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {boolean} isStreamDeleted
|
* @param {boolean} isStreamDeleted
|
||||||
* @param {number} metastreamVersion
|
* @param {Long} metastreamVersion
|
||||||
* @param {object} streamMetadata
|
* @param {object} streamMetadata
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {boolean} isStreamDeleted
|
* @property {boolean} isStreamDeleted
|
||||||
* @property {number} metastreamVersion
|
* @property {Long} metastreamVersion
|
||||||
* @property {object} streamMetadata
|
* @property {object} streamMetadata
|
||||||
*/
|
*/
|
||||||
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
|
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
|
||||||
ensure.notNullOrEmpty(stream);
|
ensure.notNullOrEmpty(stream);
|
||||||
Object.defineProperties(this, {
|
this.stream = stream;
|
||||||
stream: {enumerable: true, value: stream},
|
this.isStreamDeleted = isStreamDeleted;
|
||||||
isStreamDeleted: {enumerable: true, value: isStreamDeleted},
|
this.metastreamVersion = metastreamVersion;
|
||||||
metastreamVersion: {enumerable: true, value: metastreamVersion},
|
this.streamMetadata = streamMetadata;
|
||||||
streamMetadata: {enumerable: true, value: streamMetadata}
|
Object.freeze(this);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PersistentSubscriptionCreateStatus = {
|
const PersistentSubscriptionCreateStatus = {
|
||||||
@ -287,6 +207,7 @@ const PersistentSubscriptionCreateStatus = {
|
|||||||
NotFound: 'notFound',
|
NotFound: 'notFound',
|
||||||
Failure: 'failure'
|
Failure: 'failure'
|
||||||
};
|
};
|
||||||
|
Object.freeze(PersistentSubscriptionCreateStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
@ -294,9 +215,8 @@ const PersistentSubscriptionCreateStatus = {
|
|||||||
* @property {string} status
|
* @property {string} status
|
||||||
*/
|
*/
|
||||||
function PersistentSubscriptionCreateResult(status) {
|
function PersistentSubscriptionCreateResult(status) {
|
||||||
Object.defineProperties(this, {
|
this.status = status;
|
||||||
status: {enumerable: true, value: status}
|
Object.freeze(this);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PersistentSubscriptionUpdateStatus = {
|
const PersistentSubscriptionUpdateStatus = {
|
||||||
@ -305,6 +225,7 @@ const PersistentSubscriptionUpdateStatus = {
|
|||||||
Failure: 'failure',
|
Failure: 'failure',
|
||||||
AccessDenied: 'accessDenied'
|
AccessDenied: 'accessDenied'
|
||||||
};
|
};
|
||||||
|
Object.freeze(PersistentSubscriptionUpdateStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
@ -312,15 +233,15 @@ const PersistentSubscriptionUpdateStatus = {
|
|||||||
* @property {string} status
|
* @property {string} status
|
||||||
*/
|
*/
|
||||||
function PersistentSubscriptionUpdateResult(status) {
|
function PersistentSubscriptionUpdateResult(status) {
|
||||||
Object.defineProperties(this, {
|
this.status = status;
|
||||||
status: {enumerable: true, value: status}
|
Object.freeze(this);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PersistentSubscriptionDeleteStatus = {
|
const PersistentSubscriptionDeleteStatus = {
|
||||||
Success: 'success',
|
Success: 'success',
|
||||||
Failure: 'failure'
|
Failure: 'failure'
|
||||||
};
|
};
|
||||||
|
Object.freeze(PersistentSubscriptionDeleteStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
@ -328,9 +249,8 @@ const PersistentSubscriptionDeleteStatus = {
|
|||||||
* @property {string} status
|
* @property {string} status
|
||||||
*/
|
*/
|
||||||
function PersistentSubscriptionDeleteResult(status) {
|
function PersistentSubscriptionDeleteResult(status) {
|
||||||
Object.defineProperties(this, {
|
this.status = status;
|
||||||
status: {enumerable: true, value: status}
|
Object.freeze(this);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exports Constructors
|
// Exports Constructors
|
||||||
|
@ -3,5 +3,6 @@ const SliceReadStatus = {
|
|||||||
StreamNotFound: 'streamNotFound',
|
StreamNotFound: 'streamNotFound',
|
||||||
StreamDeleted: 'streamDeleted'
|
StreamDeleted: 'streamDeleted'
|
||||||
};
|
};
|
||||||
|
Object.freeze(SliceReadStatus);
|
||||||
|
|
||||||
module.exports = SliceReadStatus;
|
module.exports = SliceReadStatus;
|
||||||
|
@ -3,5 +3,6 @@ const SystemConsumerStrategies = {
|
|||||||
RoundRobin: 'RoundRobin',
|
RoundRobin: 'RoundRobin',
|
||||||
Pinned: 'Pinned'
|
Pinned: 'Pinned'
|
||||||
};
|
};
|
||||||
|
Object.freeze(SystemConsumerStrategies);
|
||||||
|
|
||||||
module.exports = SystemConsumerStrategies;
|
module.exports = SystemConsumerStrategies;
|
||||||
|
@ -71,7 +71,9 @@ const TcpCommand = {
|
|||||||
NotHandled: 0xF1,
|
NotHandled: 0xF1,
|
||||||
Authenticate: 0xF2,
|
Authenticate: 0xF2,
|
||||||
Authenticated: 0xF3,
|
Authenticated: 0xF3,
|
||||||
NotAuthenticated: 0xF4
|
NotAuthenticated: 0xF4,
|
||||||
|
IdentifyClient: 0xF5,
|
||||||
|
ClientIdentified: 0xF6
|
||||||
};
|
};
|
||||||
|
|
||||||
var _reverseLookup = {};
|
var _reverseLookup = {};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
var uuid = require('uuid');
|
var guidParse = require('../common/guid-parse');
|
||||||
|
|
||||||
var createBufferSegment = require('../common/bufferSegment');
|
var createBufferSegment = require('../common/bufferSegment');
|
||||||
var TcpFlags = require('./tcpFlags');
|
var TcpFlags = require('./tcpFlags');
|
||||||
@ -25,7 +25,7 @@ TcpPackage.fromBufferSegment = function(data) {
|
|||||||
var command = data.buffer[data.offset + CommandOffset];
|
var command = data.buffer[data.offset + CommandOffset];
|
||||||
var flags = data.buffer[data.offset + FlagsOffset];
|
var flags = data.buffer[data.offset + FlagsOffset];
|
||||||
|
|
||||||
var correlationId = uuid.unparse(data.buffer, data.offset + CorrelationOffset);
|
var correlationId = guidParse.unparse(data.buffer, data.offset + CorrelationOffset);
|
||||||
|
|
||||||
var headerSize = MandatorySize;
|
var headerSize = MandatorySize;
|
||||||
var login = null, pass = null;
|
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));
|
var res = new Buffer(MandatorySize + 2 + loginBytes.length + passwordBytes.length + (this.data ? this.data.count : 0));
|
||||||
res[CommandOffset] = this.command;
|
res[CommandOffset] = this.command;
|
||||||
res[FlagsOffset] = this.flags;
|
res[FlagsOffset] = this.flags;
|
||||||
uuid.parse(this.correlationId, res, CorrelationOffset);
|
guidParse.parse(this.correlationId, res, CorrelationOffset);
|
||||||
|
|
||||||
res[AuthOffset] = loginBytes.length;
|
res[AuthOffset] = loginBytes.length;
|
||||||
loginBytes.copy(res, AuthOffset + 1);
|
loginBytes.copy(res, AuthOffset + 1);
|
||||||
@ -72,7 +72,7 @@ TcpPackage.prototype.asBuffer = function() {
|
|||||||
var res = new Buffer(MandatorySize + (this.data ? this.data.count : 0));
|
var res = new Buffer(MandatorySize + (this.data ? this.data.count : 0));
|
||||||
res[CommandOffset] = this.command;
|
res[CommandOffset] = this.command;
|
||||||
res[FlagsOffset] = this.flags;
|
res[FlagsOffset] = this.flags;
|
||||||
uuid.parse(this.correlationId, res, CorrelationOffset);
|
guidParse.parse(this.correlationId, res, CorrelationOffset);
|
||||||
if (this.data)
|
if (this.data)
|
||||||
this.data.copyTo(res, AuthOffset);
|
this.data.copyTo(res, AuthOffset);
|
||||||
return res;
|
return res;
|
||||||
|
@ -10,11 +10,9 @@ var ensure = require('../common/utils/ensure');
|
|||||||
function UserCredentials(username, password) {
|
function UserCredentials(username, password) {
|
||||||
ensure.notNullOrEmpty(username, 'username');
|
ensure.notNullOrEmpty(username, 'username');
|
||||||
ensure.notNullOrEmpty(password, 'password');
|
ensure.notNullOrEmpty(password, 'password');
|
||||||
|
this.username = username;
|
||||||
Object.defineProperties(this, {
|
this.password = password;
|
||||||
username: {enumerable: true, value: username},
|
Object.freeze(this);
|
||||||
password: {enumerable: true, value: password}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = UserCredentials;
|
module.exports = UserCredentials;
|
@ -1,7 +1,7 @@
|
|||||||
var net = require('net');
|
var net = require('net');
|
||||||
var createBufferSegment = require('../../common/bufferSegment');
|
var createBufferSegment = require('../../common/bufferSegment');
|
||||||
|
|
||||||
const MaxSendPacketSize = 64 * 1000;
|
const MaxSendPacketSize = 64 * 1024;
|
||||||
|
|
||||||
function TcpConnection(log, connectionId, remoteEndPoint, onConnectionClosed) {
|
function TcpConnection(log, connectionId, remoteEndPoint, onConnectionClosed) {
|
||||||
this._socket = null;
|
this._socket = null;
|
||||||
@ -34,8 +34,11 @@ TcpConnection.prototype._initSocket = function(socket) {
|
|||||||
this._localEndPoint = {host: socket.localAddress, port: socket.localPort};
|
this._localEndPoint = {host: socket.localAddress, port: socket.localPort};
|
||||||
this._remoteEndPoint.host = socket.remoteAddress;
|
this._remoteEndPoint.host = socket.remoteAddress;
|
||||||
|
|
||||||
|
this._socket.on('drain', this._trySend.bind(this));
|
||||||
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));
|
||||||
|
|
||||||
|
this._trySend();
|
||||||
};
|
};
|
||||||
|
|
||||||
TcpConnection.prototype.enqueueSend = function(bufSegmentArray) {
|
TcpConnection.prototype.enqueueSend = function(bufSegmentArray) {
|
||||||
@ -54,19 +57,20 @@ TcpConnection.prototype._trySend = function() {
|
|||||||
|
|
||||||
var buffers = [];
|
var buffers = [];
|
||||||
var bytes = 0;
|
var bytes = 0;
|
||||||
var sendPiece = this._sendQueue.shift();
|
var sendPiece;
|
||||||
while(sendPiece) {
|
while(sendPiece = this._sendQueue.shift()) {
|
||||||
if (bytes + sendPiece.length > MaxSendPacketSize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
buffers.push(sendPiece);
|
buffers.push(sendPiece);
|
||||||
bytes += sendPiece.length;
|
bytes += sendPiece.length;
|
||||||
|
if (bytes > MaxSendPacketSize)
|
||||||
sendPiece = this._sendQueue.shift();
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var joinedBuffers = Buffer.concat(buffers, bytes);
|
var joinedBuffers = Buffer.concat(buffers, bytes);
|
||||||
this._socket.write(joinedBuffers);
|
if (!this._socket.write(joinedBuffers)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setImmediate(this._trySend.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
TcpConnection.prototype._processError = function(err) {
|
TcpConnection.prototype._processError = function(err) {
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
|
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
||||||
|
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Append One Event To Stream Happy Path': function(test) {
|
'Append One Event To Stream Happy Path': function(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, event)
|
this.conn.appendToStream(this.testStreamName, ANY_VERSION, event)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("nextExpectedVersion", result.nextExpectedVersion, 0);
|
test.areEqual("nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(0));
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -25,9 +29,44 @@ module.exports = {
|
|||||||
else
|
else
|
||||||
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
||||||
}
|
}
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
|
this.conn.appendToStream(this.testStreamName, ANY_VERSION, events)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, expectedVersion);
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(expectedVersion));
|
||||||
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Append Multiple Events To Stream Happy Path Stress Test': function(test) {
|
||||||
|
test.expect(2);
|
||||||
|
const expectedVersion = 1000;
|
||||||
|
var events = [];
|
||||||
|
for(var i = 0; i <= expectedVersion; i++) {
|
||||||
|
if (i % 2 === 0)
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent'));
|
||||||
|
else
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
||||||
|
}
|
||||||
|
this.conn.appendToStream(this.testStreamName, ANY_VERSION, events)
|
||||||
|
.then(function(result) {
|
||||||
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(expectedVersion));
|
||||||
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Append Large event': function(test) {
|
||||||
|
test.expect(2);
|
||||||
|
const largeData = Buffer.alloc(3 * 1024 *1024, " ");
|
||||||
|
const event = client.createJsonEventData(uuid.v4(), {a: largeData.toString()}, null, 'largePayloadEvent');
|
||||||
|
|
||||||
|
this.conn.appendToStream(this.testStreamName, ANY_VERSION, event)
|
||||||
|
.then(function(result) {
|
||||||
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(0));
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -38,7 +77,7 @@ module.exports = {
|
|||||||
'Append To Stream Wrong Expected Version': function(test) {
|
'Append To Stream Wrong Expected Version': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
this.conn.appendToStream(this.testStreamName, 10, event)
|
this.conn.appendToStream(this.testStreamName, Long.fromNumber(10), event)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -53,10 +92,10 @@ module.exports = {
|
|||||||
'Append To Stream Deleted': function(test) {
|
'Append To Stream Deleted': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, client.expectedVersion.noStream, true)
|
this.conn.deleteStream(this.testStreamName, NOSTREAM_VERSION, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
|
return self.conn.appendToStream(self.testStreamName, ANY_VERSION, event)
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
@ -73,10 +112,10 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.noStream, metadata)
|
this.conn.setStreamMetadataRaw(this.testStreamName, NOSTREAM_VERSION, metadata)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
|
return self.conn.appendToStream(self.testStreamName, ANY_VERSION, event)
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
|
@ -71,6 +71,32 @@ function eventEqualEventData(name, resolvedEvent, eventData) {
|
|||||||
this.ok(Buffer.compare(ev.metadata, eventData.metadata) === 0, name + ".originalEvent.metadata is not equal to original metadata.");
|
this.ok(Buffer.compare(ev.metadata, eventData.metadata) === 0, name + ".originalEvent.metadata is not equal to original metadata.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testLiveEvent(name, event, evNumber) {
|
||||||
|
this.ok(event.event, name + ".event not defined (or null)");
|
||||||
|
this.ok(event.originalEvent, name + ".originalEvent not defined (or null)");
|
||||||
|
this.ok(event.isResolved === false, name + ".isResolved should be true");
|
||||||
|
this.ok(event.originalPosition instanceof client.Position, name + ".originalPosition is not an instance of Position");
|
||||||
|
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
||||||
|
if (typeof evNumber === 'number') {
|
||||||
|
this.ok(event.originalEventNumber.toNumber() === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
||||||
|
} else {
|
||||||
|
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testReadEvent(name, event, evNumber) {
|
||||||
|
this.ok(event.event, name + ".event not defined (or null)");
|
||||||
|
this.ok(event.originalEvent, name + ".originalEvent not defined (or null)");
|
||||||
|
this.ok(event.isResolved === false, name + ".isResolved should be true");
|
||||||
|
this.ok(event.originalPosition === null, name + ".originalPosition is not null");
|
||||||
|
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
||||||
|
if (typeof evNumber === 'number') {
|
||||||
|
this.ok(event.originalEventNumber.toNumber() === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
||||||
|
} else {
|
||||||
|
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _ = {
|
var _ = {
|
||||||
'setUp': setUp,
|
'setUp': setUp,
|
||||||
'tearDown': tearDown
|
'tearDown': tearDown
|
||||||
@ -84,6 +110,8 @@ function wrap(name, testFunc) {
|
|||||||
test.areEqual = areEqual.bind(test);
|
test.areEqual = areEqual.bind(test);
|
||||||
test.fail = fail.bind(test);
|
test.fail = fail.bind(test);
|
||||||
test.eventEqualEventData = eventEqualEventData.bind(test);
|
test.eventEqualEventData = eventEqualEventData.bind(test);
|
||||||
|
test.testLiveEvent = testLiveEvent.bind(test);
|
||||||
|
test.testReadEvent = testReadEvent.bind(test);
|
||||||
return testFunc.call(this, test);
|
return testFunc.call(this, test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
@ -16,7 +17,7 @@ module.exports = {
|
|||||||
'Test Delete Stream Soft Happy Path': function(test) {
|
'Test Delete Stream Soft Happy Path': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 1, false)
|
this.conn.deleteStream(this.testStreamName, Long.fromNumber(1), false)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
||||||
@ -34,7 +35,7 @@ module.exports = {
|
|||||||
'Test Delete Stream Hard Happy Path': function(test) {
|
'Test Delete Stream Hard Happy Path': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 1, true)
|
this.conn.deleteStream(this.testStreamName, Long.fromNumber(1), true)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
||||||
@ -51,7 +52,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'Test Delete Stream With Wrong Expected Version': function(test) {
|
'Test Delete Stream With Wrong Expected Version': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
this.conn.deleteStream(this.testStreamName, 10)
|
this.conn.deleteStream(this.testStreamName, Long.fromNumber(10))
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -68,7 +69,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.any, {$acl: {$d: "$admins"}})
|
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.any, {$acl: {$d: "$admins"}})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.deleteStream(self.testStreamName, 10);
|
return self.conn.deleteStream(self.testStreamName, Long.fromNumber(10));
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
@ -86,7 +87,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 1, true)
|
this.conn.deleteStream(this.testStreamName, 1, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.deleteStream(self.testStreamName, 1, true);
|
return self.conn.deleteStream(self.testStreamName, Long.fromNumber(1), true);
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
var util = require('util');
|
|
||||||
var uuid = require('uuid');
|
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
const Long = require('long');
|
||||||
|
|
||||||
|
const EMPTY_VERSION = Long.fromNumber(client.expectedVersion.emptyStream);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Set Stream Metadata Raw': function(test) {
|
'Test Set Stream Metadata Raw': function(test) {
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.emptyStream, {$maxCount: 100})
|
this.conn.setStreamMetadataRaw(this.testStreamName, EMPTY_VERSION, {$maxCount: 100})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
|
@ -9,6 +9,20 @@ function createRandomEvent() {
|
|||||||
|
|
||||||
var testStreamName = 'test-' + uuid.v4();
|
var testStreamName = 'test-' + uuid.v4();
|
||||||
|
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayOnlyFirst(count, action) {
|
||||||
|
if (count === 0) return action();
|
||||||
|
return delay(200)
|
||||||
|
.then(function () {
|
||||||
|
action();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Create Persistent Subscription': function(test) {
|
'Test Create Persistent Subscription': function(test) {
|
||||||
var settings = client.PersistentSubscriptionSettings.create();
|
var settings = client.PersistentSubscriptionSettings.create();
|
||||||
@ -22,7 +36,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
//TODO: Update Persistent Subscription
|
//TODO: Update Persistent Subscription
|
||||||
'Test ConnectTo Persistent Subscription': function(test) {
|
'Test ConnectTo Persistent Subscription': function(test) {
|
||||||
test.expect(2);
|
test.expect(4);
|
||||||
|
var receivedEvents = [];
|
||||||
var _doneCount = 0;
|
var _doneCount = 0;
|
||||||
function done(err) {
|
function done(err) {
|
||||||
test.ok(!err, err ? err.stack : '');
|
test.ok(!err, err ? err.stack : '');
|
||||||
@ -31,13 +46,22 @@ module.exports = {
|
|||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
function eventAppeared(s, e) {
|
function eventAppeared(s, e) {
|
||||||
s.stop();
|
return delayOnlyFirst(receivedEvents.length, function () {
|
||||||
|
receivedEvents.push(e);
|
||||||
|
if (receivedEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
done(error);
|
if (error) return done(error);
|
||||||
|
test.ok(receivedEvents[1].originalEventNumber > receivedEvents[0].originalEventNumber, "Received events are out of order.");
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
var subscription = this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped);
|
var self = this;
|
||||||
this.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent()])
|
this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped)
|
||||||
|
.then(function(subscription) {
|
||||||
|
test.ok(subscription, "Subscription is null.");
|
||||||
|
return self.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent(), createRandomEvent()]);
|
||||||
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
var util = require('util');
|
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
|
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
||||||
|
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
this.expectedEvent = {a: uuid.v4(), b: Math.random()};
|
this.expectedEvent = {
|
||||||
|
a: uuid.v4(),
|
||||||
|
b: Math.random()
|
||||||
|
};
|
||||||
this.expectedEventType = 'anEvent';
|
this.expectedEventType = 'anEvent';
|
||||||
this.expectedEventId = uuid.v4();
|
this.expectedEventId = uuid.v4();
|
||||||
var event = client.createJsonEventData(this.expectedEventId, this.expectedEvent, null, this.expectedEventType);
|
var event = client.createJsonEventData(this.expectedEventId, this.expectedEvent, null, this.expectedEventType);
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, event)
|
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, event)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
@ -18,11 +23,11 @@ module.exports = {
|
|||||||
'Read Event Happy Path': function(test) {
|
'Read Event Happy Path': function(test) {
|
||||||
test.expect(8);
|
test.expect(8);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readEvent(this.testStreamName, 0)
|
this.conn.readEvent(this.testStreamName, Long.fromNumber(0))
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, 0);
|
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
||||||
test.ok(result.event !== null, "event is null.");
|
test.ok(result.event !== null, "event is null.");
|
||||||
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
||||||
var event = JSON.parse(result.event.originalEvent.data.toString());
|
var event = JSON.parse(result.event.originalEvent.data.toString());
|
||||||
@ -38,11 +43,11 @@ module.exports = {
|
|||||||
'Read Event From Non-Existing Stream': function(test) {
|
'Read Event From Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readEvent(anotherStream, 0)
|
this.conn.readEvent(anotherStream, Long.fromNumber(0))
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.NoStream);
|
test.areEqual('status', result.status, client.eventReadStatus.NoStream);
|
||||||
test.areEqual('stream', result.stream, anotherStream);
|
test.areEqual('stream', result.stream, anotherStream);
|
||||||
test.areEqual('eventNumber', result.eventNumber, 0);
|
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -55,12 +60,12 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 0, true)
|
this.conn.deleteStream(this.testStreamName, 0, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readEvent(self.testStreamName, 0)
|
return self.conn.readEvent(self.testStreamName, Long.fromNumber(0))
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('status', result.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, 0);
|
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -71,11 +76,11 @@ module.exports = {
|
|||||||
'Read Event With Inexisting Version': function(test) {
|
'Read Event With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readEvent(self.testStreamName, 1)
|
return self.conn.readEvent(self.testStreamName, Long.fromNumber(1))
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.NotFound);
|
test.areEqual('status', result.status, client.eventReadStatus.NotFound);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, 1);
|
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(1));
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -86,10 +91,14 @@ module.exports = {
|
|||||||
'Read Event With No Access': function(test) {
|
'Read Event With No Access': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$r: '$admins'}};
|
var metadata = {
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
$acl: {
|
||||||
.then(function(){
|
$r: '$admins'
|
||||||
return self.conn.readEvent(self.testStreamName, 0);
|
}
|
||||||
|
};
|
||||||
|
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
||||||
|
.then(function() {
|
||||||
|
return self.conn.readEvent(self.testStreamName, Long.fromNumber(0));
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("readEvent succeeded but should have failed.");
|
test.fail("readEvent succeeded but should have failed.");
|
||||||
@ -101,7 +110,36 @@ module.exports = {
|
|||||||
if (isAccessDenied) return test.done();
|
if (isAccessDenied) return test.done();
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
'Read a Large Event': function(test) {
|
||||||
|
test.expect(8);
|
||||||
|
var self = this;
|
||||||
|
const largeData = Buffer.alloc(3 * 1024 * 1024, " ");
|
||||||
|
|
||||||
|
const largeEvent = client.createJsonEventData(uuid.v4(), {
|
||||||
|
a: largeData.toString()
|
||||||
|
}, null, 'largePayloadEvent');
|
||||||
|
|
||||||
|
this.conn.appendToStream(this.testStreamName, ANY_VERSION, largeEvent)
|
||||||
|
.then(function(result) {
|
||||||
|
self.conn.readEvent(self.testStreamName, Long.fromNumber(1))
|
||||||
|
.then(function(result) {
|
||||||
|
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
||||||
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
|
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(1));
|
||||||
|
test.ok(result.event !== null, "event is null.");
|
||||||
|
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
||||||
|
var event = JSON.parse(result.event.originalEvent.data.toString());
|
||||||
|
test.areEqual('event.eventId', result.event.originalEvent.eventId, largeEvent.eventId);
|
||||||
|
test.areEqual('event.eventType', result.event.originalEvent.eventType, 'largePayloadEvent');
|
||||||
|
test.areEqual('decoded event.data', event, JSON.parse(largeEvent.data.toString()));
|
||||||
|
test.done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
require('./common/base_test').init(module.exports);
|
require('./common/base_test').init(module.exports);
|
@ -1,15 +1,17 @@
|
|||||||
var util = require('util');
|
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
const streamSize = 100;
|
const streamSize = 100;
|
||||||
|
|
||||||
|
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
this.eventsData = [];
|
this.eventsData = [];
|
||||||
for(var i = 0; i < streamSize; i++)
|
for(var i = 0; i < streamSize; i++)
|
||||||
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, this.eventsData)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
@ -18,19 +20,19 @@ module.exports = {
|
|||||||
'Read Stream Events Backward Happy Path': function(test) {
|
'Read Stream Events Backward Happy Path': function(test) {
|
||||||
test.expect(7 + (streamSize * 6));
|
test.expect(7 + (streamSize * 6));
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readStreamEventsBackward(this.testStreamName, streamSize-1, streamSize)
|
this.conn.readStreamEventsBackward(this.testStreamName, Long.fromNumber(streamSize-1), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
||||||
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
||||||
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, -1);
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, Long.fromNumber(-1));
|
||||||
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, Long.fromNumber(streamSize-1));
|
||||||
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
for(var i = 0; i < streamSize; i++) {
|
for(var i = 0; i < streamSize; i++) {
|
||||||
var reverseIndex = streamSize - i - 1;
|
var reverseIndex = streamSize - i - 1;
|
||||||
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[reverseIndex]);
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[reverseIndex]);
|
||||||
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, reverseIndex);
|
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, Long.fromNumber(reverseIndex));
|
||||||
}
|
}
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -41,11 +43,11 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Non-Existing Stream': function(test) {
|
'Read Stream Events Backward With Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readStreamEventsBackward(anotherStream, streamSize-1, streamSize)
|
this.conn.readStreamEventsBackward(anotherStream, Long.fromNumber(streamSize-1), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
test.areEqual('slice.stream', slice.stream, anotherStream);
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -56,14 +58,14 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Deleted Stream': function(test) {
|
'Read Stream Events Backward With Deleted Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
this.conn.deleteStream(this.testStreamName, Long.fromNumber(streamSize-1), true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize)
|
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize-1), streamSize)
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -74,11 +76,11 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Inexisting Version': function(test) {
|
'Read Stream Events Backward With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize * 2, streamSize)
|
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize * 2), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize*2));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -90,9 +92,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$r: '$admins'}};
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
||||||
.then(function(){
|
.then(function(){
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize);
|
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize-1), streamSize);
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.fail("readStreamEventsBackward succeeded but should have failed.");
|
test.fail("readStreamEventsBackward succeeded but should have failed.");
|
||||||
|
@ -1,35 +1,37 @@
|
|||||||
var util = require('util');
|
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
const streamSize = 100;
|
const streamSize = 100;
|
||||||
|
|
||||||
|
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
this.eventsData = [];
|
this.eventsData = [];
|
||||||
for(var i = 0; i < streamSize; i++)
|
for(var i = 0; i < streamSize; i++)
|
||||||
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, this.eventsData)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
.catch(cb);
|
.catch(cb);
|
||||||
},
|
},
|
||||||
'Read Stream Events Forward Happy Path': function(test) {
|
'Read Stream Events Forward Happy Path': function(test) {
|
||||||
test.expect(7 + (streamSize * 6));
|
test.expect(7 + (streamSize * 11));
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readStreamEventsForward(this.testStreamName, 0, streamSize)
|
this.conn.readStreamEventsForward(this.testStreamName, Long.fromNumber(0), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
||||||
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
||||||
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, streamSize);
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, Long.fromNumber(streamSize));
|
||||||
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, Long.fromNumber(streamSize-1));
|
||||||
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
for(var i = 0; i < streamSize; i++) {
|
for(var i = 0; i < streamSize; i++) {
|
||||||
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[i]);
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[i]);
|
||||||
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, i);
|
test.testReadEvent('slice.events[' + i + ']', slice.events[i], i);
|
||||||
}
|
}
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -40,11 +42,11 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Non-Existing Stream': function(test) {
|
'Read Stream Events Forward With Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readStreamEventsForward(anotherStream, 0, streamSize)
|
this.conn.readStreamEventsForward(anotherStream, Long.fromNumber(0), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
test.areEqual('slice.stream', slice.stream, anotherStream);
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -55,14 +57,14 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Deleted Stream': function(test) {
|
'Read Stream Events Forward With Deleted Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
this.conn.deleteStream(this.testStreamName, Long.fromNumber(streamSize-1), true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize)
|
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(0), streamSize)
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -73,11 +75,11 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Inexisting Version': function(test) {
|
'Read Stream Events Forward With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, streamSize * 2, streamSize)
|
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(streamSize * 2), streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize*2));
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -89,9 +91,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$r: '$admins'}};
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
||||||
.then(function(){
|
.then(function(){
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize);
|
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(0), streamSize);
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.fail("readStreamEventsForward succeeded but should have failed.");
|
test.fail("readStreamEventsForward succeeded but should have failed.");
|
||||||
|
@ -7,9 +7,23 @@ 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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayOnlyFirst(count, action) {
|
||||||
|
if (count === 0) return action();
|
||||||
|
return delay(200)
|
||||||
|
.then(function () {
|
||||||
|
action();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Subscribe to All From (Start)': function(test) {
|
'Test Subscribe to All From (Start)': function(test) {
|
||||||
test.expect(4);
|
test.expect(6);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -19,19 +33,33 @@ module.exports = {
|
|||||||
test.ok(!err, err ? err.stack : '');
|
test.ok(!err, err ? err.stack : '');
|
||||||
_doneCount++;
|
_doneCount++;
|
||||||
if (_doneCount < 2) return;
|
if (_doneCount < 2) return;
|
||||||
|
|
||||||
|
var catchUpInOrder = true;
|
||||||
|
for(var i = 1; i < catchUpEvents.length; i++)
|
||||||
|
catchUpInOrder = catchUpInOrder && (catchUpEvents[i].originalPosition.compareTo(catchUpEvents[i-1].originalPosition) > 0);
|
||||||
|
test.ok(catchUpInOrder, "Catch-up events are out of order.");
|
||||||
|
|
||||||
|
var liveInOrder = true;
|
||||||
|
for(var j = 1; j < liveEvents.length; j++)
|
||||||
|
liveInOrder = liveInOrder && (liveEvents[j].originalPosition.compareTo(liveEvents[j-1].originalPosition) > 0);
|
||||||
|
test.ok(liveInOrder, "Live events are out of order.");
|
||||||
|
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
function eventAppeared(s, e) {
|
function eventAppeared(s, e) {
|
||||||
if (liveProcessing) {
|
var isLive = liveProcessing;
|
||||||
|
delayOnlyFirst(isLive ? liveEvents.length : catchUpEvents.length, function() {
|
||||||
|
if (isLive) {
|
||||||
liveEvents.push(e);
|
liveEvents.push(e);
|
||||||
s.stop();
|
|
||||||
} else {
|
} else {
|
||||||
catchUpEvents.push(e);
|
catchUpEvents.push(e);
|
||||||
}
|
}
|
||||||
|
if (isLive && liveEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function liveProcessingStarted() {
|
function liveProcessingStarted() {
|
||||||
liveProcessing = true;
|
liveProcessing = true;
|
||||||
var events = [createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
done();
|
done();
|
||||||
@ -39,14 +67,14 @@ module.exports = {
|
|||||||
.catch(done);
|
.catch(done);
|
||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 1, "Expecting 1 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.ok(catchUpEvents.length > 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length);
|
test.ok(catchUpEvents.length > 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
var subscription = this.conn.subscribeToAllFrom(null, false, eventAppeared, liveProcessingStarted, subscriptionDropped, allCredentials);
|
var subscription = this.conn.subscribeToAllFrom(null, false, eventAppeared, liveProcessingStarted, subscriptionDropped, allCredentials);
|
||||||
},
|
},
|
||||||
'Test Subscribe to All From (Position)': function(test) {
|
'Test Subscribe to All From (Position)': function(test) {
|
||||||
test.expect(5);
|
test.expect(7);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -56,19 +84,33 @@ module.exports = {
|
|||||||
test.ok(!err, err ? err.stack : '');
|
test.ok(!err, err ? err.stack : '');
|
||||||
_doneCount++;
|
_doneCount++;
|
||||||
if (_doneCount < 2) return;
|
if (_doneCount < 2) return;
|
||||||
|
|
||||||
|
var catchUpInOrder = true;
|
||||||
|
for(var i = 1; i < catchUpEvents.length; i++)
|
||||||
|
catchUpInOrder = catchUpInOrder && (catchUpEvents[i].originalPosition.compareTo(catchUpEvents[i-1].originalPosition) > 0);
|
||||||
|
test.ok(catchUpInOrder, "Catch-up events are out of order.");
|
||||||
|
|
||||||
|
var liveInOrder = true;
|
||||||
|
for(var j = 1; j < liveEvents.length; j++)
|
||||||
|
liveInOrder = liveInOrder && (liveEvents[j].originalPosition.compareTo(liveEvents[j-1].originalPosition) > 0);
|
||||||
|
test.ok(liveInOrder, "Live events are out of order.");
|
||||||
|
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
function eventAppeared(s, e) {
|
function eventAppeared(s, e) {
|
||||||
if (liveProcessing) {
|
var isLive = liveProcessing;
|
||||||
|
delayOnlyFirst(isLive ? liveEvents.length : catchUpEvents.length, function() {
|
||||||
|
if (isLive) {
|
||||||
liveEvents.push(e);
|
liveEvents.push(e);
|
||||||
s.stop();
|
|
||||||
} else {
|
} else {
|
||||||
catchUpEvents.push(e);
|
catchUpEvents.push(e);
|
||||||
}
|
}
|
||||||
|
if (isLive && liveEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function liveProcessingStarted() {
|
function liveProcessingStarted() {
|
||||||
liveProcessing = true;
|
liveProcessing = true;
|
||||||
var events = [createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
done();
|
done();
|
||||||
@ -76,7 +118,7 @@ module.exports = {
|
|||||||
.catch(done);
|
.catch(done);
|
||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 1, "Expecting 1 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.ok(catchUpEvents.length > 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length);
|
test.ok(catchUpEvents.length > 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
@ -87,7 +129,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
'Test Subscribe to All From (End)': function(test) {
|
'Test Subscribe to All From (End)': function(test) {
|
||||||
test.expect(5);
|
test.expect(6);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -97,19 +139,28 @@ module.exports = {
|
|||||||
test.ok(!err, err ? err.stack : '');
|
test.ok(!err, err ? err.stack : '');
|
||||||
_doneCount++;
|
_doneCount++;
|
||||||
if (_doneCount < 2) return;
|
if (_doneCount < 2) return;
|
||||||
|
|
||||||
|
var liveInOrder = true;
|
||||||
|
for(var j = 1; j < liveEvents.length; j++)
|
||||||
|
liveInOrder = liveInOrder && (liveEvents[j].originalPosition.compareTo(liveEvents[j-1].originalPosition) > 0);
|
||||||
|
test.ok(liveInOrder, "Live events are out of order.");
|
||||||
|
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
function eventAppeared(s, e) {
|
function eventAppeared(s, e) {
|
||||||
if (liveProcessing) {
|
var isLive = liveProcessing;
|
||||||
|
delayOnlyFirst(isLive ? liveEvents.length : catchUpEvents.length, function() {
|
||||||
|
if (isLive) {
|
||||||
liveEvents.push(e);
|
liveEvents.push(e);
|
||||||
s.stop();
|
|
||||||
} else {
|
} else {
|
||||||
catchUpEvents.push(e);
|
catchUpEvents.push(e);
|
||||||
}
|
}
|
||||||
|
if (isLive && liveEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function liveProcessingStarted() {
|
function liveProcessingStarted() {
|
||||||
liveProcessing = true;
|
liveProcessing = true;
|
||||||
var events = [createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
done();
|
done();
|
||||||
@ -117,7 +168,7 @@ module.exports = {
|
|||||||
.catch(done);
|
.catch(done);
|
||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 1, "Expecting 1 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.ok(catchUpEvents.length === 0, "Expecting 0 catchUp event, got " + catchUpEvents.length);
|
test.ok(catchUpEvents.length === 0, "Expecting 0 catchUp event, got " + catchUpEvents.length);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,20 @@ const uuid = require('uuid');
|
|||||||
const client = require('../src/client');
|
const client = require('../src/client');
|
||||||
const allCredentials = new client.UserCredentials("admin", "changeit");
|
const allCredentials = new client.UserCredentials("admin", "changeit");
|
||||||
|
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayOnlyFirst(count, action) {
|
||||||
|
if (count === 0) return action();
|
||||||
|
return delay(200)
|
||||||
|
.then(function () {
|
||||||
|
action();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Subscribe To All Happy Path': function(test) {
|
'Test Subscribe To All Happy Path': function(test) {
|
||||||
const resolveLinkTos = false;
|
const resolveLinkTos = false;
|
||||||
@ -30,8 +44,10 @@ module.exports = {
|
|||||||
|
|
||||||
var receivedEvents = [];
|
var receivedEvents = [];
|
||||||
function eventAppeared(subscription, event) {
|
function eventAppeared(subscription, event) {
|
||||||
|
delayOnlyFirst(receivedEvents.length, function() {
|
||||||
receivedEvents.push(event);
|
receivedEvents.push(event);
|
||||||
if (receivedEvents.length === numberOfPublishedEvents) subscription.close();
|
if (receivedEvents.length === numberOfPublishedEvents) subscription.close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function subscriptionDropped(subscription, reason, error) {
|
function subscriptionDropped(subscription, reason, error) {
|
||||||
if (error) return done(error);
|
if (error) return done(error);
|
||||||
|
@ -1,14 +1,28 @@
|
|||||||
var util = require('util');
|
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
var Long = require('long');
|
||||||
|
|
||||||
function createRandomEvent() {
|
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayOnlyFirst(count, action) {
|
||||||
|
if (count === 0) return action();
|
||||||
|
return delay(200)
|
||||||
|
.then(function () {
|
||||||
|
action();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Subscribe to Stream From Happy Path': function(test) {
|
'Test Subscribe to Stream From Beginning (null)': function(test) {
|
||||||
test.expect(8);
|
test.expect(32);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -22,16 +36,19 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function eventAppeared(s, e) {
|
function eventAppeared(s, e) {
|
||||||
if (liveProcessing) {
|
var isLive = liveProcessing;
|
||||||
|
delayOnlyFirst(isLive ? liveEvents.length : catchUpEvents.length, function() {
|
||||||
|
if (isLive) {
|
||||||
liveEvents.push(e);
|
liveEvents.push(e);
|
||||||
s.stop();
|
|
||||||
} else {
|
} else {
|
||||||
catchUpEvents.push(e);
|
catchUpEvents.push(e);
|
||||||
}
|
}
|
||||||
|
if (isLive && liveEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function liveProcessingStarted() {
|
function liveProcessingStarted() {
|
||||||
liveProcessing = true;
|
liveProcessing = true;
|
||||||
var events = [createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
done();
|
done();
|
||||||
@ -39,12 +56,16 @@ module.exports = {
|
|||||||
.catch(done);
|
.catch(done);
|
||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 1, "Expecting 1 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.ok(catchUpEvents.length >= 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length);
|
test.testLiveEvent('liveEvents[0]', liveEvents[0], 2);
|
||||||
|
test.testLiveEvent('liveEvents[1]', liveEvents[1], 3);
|
||||||
|
test.ok(catchUpEvents.length === 2, "Expecting 2 catchUp event, got " + catchUpEvents.length);
|
||||||
|
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0], 0);
|
||||||
|
test.testReadEvent('catchUpEvents[1]', catchUpEvents[1], 1);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = [createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
|
this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, null, false, eventAppeared, liveProcessingStarted, subscriptionDropped);
|
var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, null, false, eventAppeared, liveProcessingStarted, subscriptionDropped);
|
||||||
@ -55,6 +76,61 @@ module.exports = {
|
|||||||
test.areEqual("subscription.maxPushQueueSize", subscription.maxPushQueueSize, 10000);
|
test.areEqual("subscription.maxPushQueueSize", subscription.maxPushQueueSize, 10000);
|
||||||
})
|
})
|
||||||
.catch(test.done);
|
.catch(test.done);
|
||||||
|
},
|
||||||
|
'Test Subscribe to Stream From 0': function(test) {
|
||||||
|
test.expect(26);
|
||||||
|
var self = this;
|
||||||
|
var liveProcessing = false;
|
||||||
|
var catchUpEvents = [];
|
||||||
|
var liveEvents = [];
|
||||||
|
var _doneCount = 0;
|
||||||
|
|
||||||
|
function done(err) {
|
||||||
|
test.ok(!err, err ? err.stack : '');
|
||||||
|
if (++_doneCount < 2) return;
|
||||||
|
test.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventAppeared(s, e) {
|
||||||
|
var isLive = liveProcessing;
|
||||||
|
delayOnlyFirst(isLive ? liveEvents.length : catchUpEvents.length, function() {
|
||||||
|
if (isLive) {
|
||||||
|
liveEvents.push(e);
|
||||||
|
} else {
|
||||||
|
catchUpEvents.push(e);
|
||||||
|
}
|
||||||
|
if (isLive && liveEvents.length === 2) s.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function liveProcessingStarted() {
|
||||||
|
liveProcessing = true;
|
||||||
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
|
self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, events)
|
||||||
|
.then(function () {
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
}
|
||||||
|
function subscriptionDropped(connection, reason, error) {
|
||||||
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
|
test.testLiveEvent('liveEvents[0]', liveEvents[0], 2);
|
||||||
|
test.testLiveEvent('liveEvents[1]', liveEvents[1], 3);
|
||||||
|
test.ok(catchUpEvents.length === 1, "Expecting 1 catchUp event, got " + catchUpEvents.length);
|
||||||
|
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0], 1);
|
||||||
|
done(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
|
this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
|
||||||
|
.then(function() {
|
||||||
|
var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, Long.fromNumber(0), false, eventAppeared, liveProcessingStarted, subscriptionDropped);
|
||||||
|
|
||||||
|
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
||||||
|
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
||||||
|
test.areEqual("subscription.readBatchSize", subscription.readBatchSize, 500);
|
||||||
|
test.areEqual("subscription.maxPushQueueSize", subscription.maxPushQueueSize, 10000);
|
||||||
|
})
|
||||||
|
.catch(test.done);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
const uuid = require('uuid');
|
const uuid = require('uuid');
|
||||||
const client = require('../src/client');
|
const client = require('../src/client');
|
||||||
|
const Long = require('long');
|
||||||
|
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayOnlyFirst(count, action) {
|
||||||
|
if (count === 0) return action();
|
||||||
|
return delay(200)
|
||||||
|
.then(function () {
|
||||||
|
action();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Subscribe To Stream Happy Path': function(test) {
|
'Test Subscribe To Stream Happy Path': function(test) {
|
||||||
@ -28,8 +43,10 @@ module.exports = {
|
|||||||
|
|
||||||
var receivedEvents = [];
|
var receivedEvents = [];
|
||||||
function eventAppeared(subscription, event) {
|
function eventAppeared(subscription, event) {
|
||||||
|
delayOnlyFirst(receivedEvents.length, function () {
|
||||||
receivedEvents.push(event);
|
receivedEvents.push(event);
|
||||||
if (receivedEvents.length === numberOfPublishedEvents) subscription.close();
|
if (receivedEvents.length === numberOfPublishedEvents) subscription.close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function subscriptionDropped(subscription, reason, error) {
|
function subscriptionDropped(subscription, reason, error) {
|
||||||
if (error) return done(error);
|
if (error) return done(error);
|
||||||
@ -42,7 +59,7 @@ module.exports = {
|
|||||||
.then(function(subscription) {
|
.then(function(subscription) {
|
||||||
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
||||||
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
||||||
test.areEqual("subscription.lastEventNumber", subscription.lastEventNumber, client.expectedVersion.emptyStream);
|
test.areEqual("subscription.lastEventNumber", subscription.lastEventNumber, Long.fromNumber(client.expectedVersion.emptyStream));
|
||||||
|
|
||||||
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.emptyStream, publishedEvents);
|
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.emptyStream, publishedEvents);
|
||||||
})
|
})
|
||||||
|
@ -2,13 +2,17 @@ var uuid = require('uuid');
|
|||||||
var Long = require('long');
|
var Long = require('long');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
|
||||||
|
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
||||||
|
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
||||||
|
var EMPTY_VERSION = Long.fromNumber(client.expectedVersion.emptyStream);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
cb();
|
cb();
|
||||||
},
|
},
|
||||||
'Start A Transaction Happy Path': function(test) {
|
'Start A Transaction Happy Path': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
this.conn.startTransaction(this.testStreamName, client.expectedVersion.noStream)
|
this.conn.startTransaction(this.testStreamName, NOSTREAM_VERSION)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.ok(Long.isLong(trx.transactionId), "trx.transactionId should be a Long.");
|
test.ok(Long.isLong(trx.transactionId), "trx.transactionId should be a Long.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -32,7 +36,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream)
|
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.fail("Start Transaction with deleted stream succeeded.");
|
test.fail("Start Transaction with deleted stream succeeded.");
|
||||||
@ -50,9 +54,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, -1, metadata)
|
this.conn.setStreamMetadataRaw(this.testStreamName, EMPTY_VERSION, metadata)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.fail("Start Transaction with no access succeeded.");
|
test.fail("Start Transaction with no access succeeded.");
|
||||||
@ -67,7 +71,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'Continue A Transaction Happy Path': function(test) {
|
'Continue A Transaction Happy Path': function(test) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream)
|
this.conn.startTransaction(this.testStreamName, EMPTY_VERSION)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent'))
|
||||||
.then(function () {
|
.then(function () {
|
||||||
@ -88,7 +92,7 @@ module.exports = {
|
|||||||
'Write/Commit Transaction Happy Path': function(test) {
|
'Write/Commit Transaction Happy Path': function(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream)
|
this.conn.startTransaction(this.testStreamName, EMPTY_VERSION)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
self.events = [];
|
self.events = [];
|
||||||
for(var i = 0; i < 15; i++) {
|
for(var i = 0; i < 15; i++) {
|
||||||
@ -111,7 +115,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "Missing result.logPosition");
|
test.ok(result.logPosition, "Missing result.logPosition");
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, self.events.length-1);
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(self.events.length-1));
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
.catch(test.done);
|
.catch(test.done);
|
||||||
@ -139,9 +143,9 @@ module.exports = {
|
|||||||
'Write/Commit Transaction With Deleted Stream': function(test) {
|
'Write/Commit Transaction With Deleted Stream': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream, true)
|
this.conn.deleteStream(this.testStreamName, EMPTY_VERSION, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
||||||
@ -163,10 +167,10 @@ module.exports = {
|
|||||||
'Write/Commit Transaction With No Write Access': function(test) {
|
'Write/Commit Transaction With No Write Access': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, client.expectedVersion.any)
|
this.conn.startTransaction(this.testStreamName, ANY_VERSION)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
return self.conn.setStreamMetadataRaw(self.testStreamName, -1, metadata)
|
return self.conn.setStreamMetadataRaw(self.testStreamName, EMPTY_VERSION, metadata)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
Reference in New Issue
Block a user