Skip to content
Permalink
Browse files Browse the repository at this point in the history
server: fix Subscription.modify assert
  • Loading branch information
erossignon committed Aug 13, 2022
1 parent 684a796 commit 3fd46ec
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 6 deletions.
15 changes: 9 additions & 6 deletions packages/node-opcua-server/source/server_subscription.ts
Expand Up @@ -629,7 +629,7 @@ export class Subscription extends EventEmitter {
this.messageSent = false;

this.timerId = null;
this._start_timer();
this._start_timer({ firstTime: true });

debugLog(chalk.green(`creating subscription ${this.id}`));

Expand Down Expand Up @@ -686,7 +686,7 @@ export class Subscription extends EventEmitter {
// todo
}
this._stop_timer();
this._start_timer();
this._start_timer({ firstTime: false });
}

/**
Expand Down Expand Up @@ -732,7 +732,7 @@ export class Subscription extends EventEmitter {
public increaseLifeTimeCounter(): void {
this._life_time_counter += 1;
if (this._life_time_counter >= this.lifeTimeCount) {
this.emit("lifeTimeExpired");
this.emit("lifeTimeExpired");
}
this.emit("lifeTimeCounterChanged", this._life_time_counter);
}
Expand Down Expand Up @@ -1458,7 +1458,7 @@ export class Subscription extends EventEmitter {
}
}

private _start_timer() {
private _start_timer({ firstTime }: { firstTime: boolean }) {
debugLog(
chalk.bgWhite.blue("Subscription#_start_timer subscriptionId="),
this.id,
Expand All @@ -1478,8 +1478,11 @@ export class Subscription extends EventEmitter {
// make sure that a keep-alive Message will be send at the end of the first publishing cycle
// if there are no Notifications ready.
this._keep_alive_counter = 0; // this.maxKeepAliveCount;
assert(this.messageSent === false);
assert(this.state === SubscriptionState.CREATING);

if (firstTime) {
assert(this.messageSent === false);
assert(this.state === SubscriptionState.CREATING);
}

assert(this.publishingInterval >= Subscription.minimumPublishingInterval);
this.timerId = setInterval(this._tick.bind(this), this.publishingInterval);
Expand Down
65 changes: 65 additions & 0 deletions packages/node-opcua-server/test/test_subscription.js
Expand Up @@ -1062,6 +1062,71 @@ describe("Subscriptions", function () {
subscription.dispose();
});

it("T17 - should be possible to modify subscription publishing interval", function(){
// pretend the client has sent many pending PublishRequests
fake_publish_engine.pendingPublishRequestCount = 1000;

/**
* When a Subscription is created, the first Message is sent at the end of the first publishing cycle to
* inform the Client that the Subscription is operational. A Notification Message is sent if there are
* Notifications ready to be reported. If there are none, a keep-alive Message is sent instead that
* contains a sequence number of 1, indicating that the first Notification Message has not yet been
* sent. This is the only time a keep-alive Message is sent without waiting for the maximum keep-alive
* count to be reached, as specified in (f) above.
*
*/
const subscription = new Subscription({
publishingInterval: 1000,
maxKeepAliveCount: 20,
//
publishEngine: fake_publish_engine,
globalCounter: { totalMonitoredItemCount: 0 },
serverCapabilities: { maxMonitoredItems: 10000, maxMonitoredItemsPerSubscription: 1000 }
});
const monitoredItem = add_mock_monitored_item(subscription);

// pretend that we already have notification messages
// a notification finally arrived !
monitoredItem.simulateMonitoredItemAddingNotification();

const notification_event_spy = sinon.spy();
const keepalive_event_spy = sinon.spy();
const expire_event_spy = sinon.spy();

subscription.on("notification", notification_event_spy);
subscription.on("keepalive", keepalive_event_spy);
subscription.on("expired", expire_event_spy);

test.clock.tick(200);
keepalive_event_spy.callCount.should.equal(0);
notification_event_spy.callCount.should.eql(0);

test.clock.tick(1000);
keepalive_event_spy.callCount.should.equal(0);
notification_event_spy.callCount.should.eql(1);

test.clock.tick(1000);
keepalive_event_spy.callCount.should.equal(0);
notification_event_spy.callCount.should.eql(1);

monitoredItem.simulateMonitoredItemAddingNotification();
// now change the publishin Intervale
subscription.modify({ requestedPublishingInterval: 2000});

test.clock.tick(1000);
keepalive_event_spy.callCount.should.equal(0);
notification_event_spy.callCount.should.eql(1);

test.clock.tick(1010);
keepalive_event_spy.callCount.should.equal(0);
notification_event_spy.callCount.should.eql(2);

subscription.terminate();
subscription.dispose();

});


xit("closing a Subscription causes its MonitoredItems to be deleted. ", function () {
/** */
});
Expand Down

0 comments on commit 3fd46ec

Please sign in to comment.