Skip to content
Browse files

AgentManager reschedules timer when TTL < 10 sec.

The AgentManager sets an interval for agent reaping
every 10 seconds. If agent timeouts are < 10 seconds,
then the timeout may be delayed as much as 10 seconds
before the reap check happens.

Reschedule the AgentManager's reap timer when an Agent
requests a TTL under 10 seconds.

Add a functional test for timeout behavior.
  • Loading branch information...
1 parent d378681 commit 807b0fa0dcc38dee9a8456c61b90980650ac529a @reid reid committed Aug 27, 2012
Showing with 72 additions and 0 deletions.
  1. +49 −0 lib/hub/agent.js
  2. +23 −0 test/functional.js
View
49 lib/hub/agent.js
@@ -151,6 +151,7 @@ Agent.prototype.setTTLUntilComplete = function (ttl) {
this.debug("setTTLUntilComplete:", ttl);
this.defaults.ttl = this.ttl;
this.ttl = ttl;
+ this.manager.setTTLUntilComplete(ttl);
};
/**
@@ -275,6 +276,7 @@ Agent.prototype.nextURL = function () {
url += "agent/" + this.id;
this.emit("complete");
this.restoreDefaults();
+ this.manager.restoreDefaults();
}
this.currentUrl = url;
@@ -426,6 +428,8 @@ function AgentManager(hub, ttl) {
this.ttl = ttl || AgentManager.REAP_TTL;
+ this.defaults = {};
+
if (REAP) {
this._startReap();
}
@@ -450,10 +454,55 @@ AgentManager.REAP_TTL = (10 * 1000); //Default reap timeout
*/
//TODO this needs to be destroyed at some point, just not sure where (`agentManager.destroy()` maybe)
AgentManager.prototype._startReap = function () {
+ if (this._reap) {
+ this.debug("About to reschedule reap to ttl =",
+ this.ttl + ", clearing old interval", this._reap);
+ clearInterval(this._reap);
+ }
this._reap = setInterval(this.reap.bind(this), this.ttl);
};
/**
+ * Set a new TTL.
+ * The old TTL will be restored when the complete event fires.
+ *
+ * @method setTTLUntilComplete
+ * @param {Number} ttl TTL in milliseconds.
+ */
+AgentManager.prototype.setTTLUntilComplete = function (ttl) {
+ if ("ttl" in this.defaults) {
+ this.debug("ignorning setTTLUntilComplete because default TTL already set");
+ return;
+ }
+
+ this.debug("setTTLUntilComplete:", ttl);
+ this.defaults.ttl = this.ttl;
+ this.ttl = ttl;
+
+ if (this.ttl < this.defaults.ttl) {
+ this._startReap();
+ }
+};
+
+/**
+ * Restore default settings.
+ *
+ * @method restoreDefaults
+ * @private
+ */
+AgentManager.prototype.restoreDefaults = function () {
+ var self = this;
+ Object.keys(self.defaults).forEach(function (name) {
+ if (name in self) {
+ self.debug("restoreDefaults restored", name, "to", self.defaults[name]);
+ self[name] = self.defaults[name];
+ delete self.defaults[name];
+ }
+ });
+ this._startReap();
+};
+
+/**
* TODO
*
* @method reap
View
23 test/functional.js
@@ -330,6 +330,22 @@ function clientFailureContext(createBatchConfiguration) {
});
}
+function clientTimeoutContext(createBatchConfiguration) {
+ return captureContext({
+ topic: createBatchTopic(createBatchConfiguration),
+ "did not throw": didNotThrow,
+ "the browser returned to the capture page": function (topic) {
+ assert.strictEqual(topic.finalPathname, topic.expectedPathname);
+ },
+ "the agentComplete event fired once": function (topic) {
+ assert.strictEqual(topic.agentCompleteFires, 1);
+ },
+ "the agentError event fired once": function (topic) {
+ assert.strictEqual(topic.agentErrorFires, 1);
+ }
+ });
+}
+
function visitorContext(createBatchConfiguration) {
return captureContext({
topic: createBatchTopic(createBatchConfiguration),
@@ -565,6 +581,13 @@ vows.describe("Yeti Functional")
})
}))
.addBatch(hub.functionalContext({
+ "visits Yeti with test that will timeout": clientTimeoutContext({
+ basedir: basedir,
+ tests: fixtures(["long-async.html", "basic.html"]),
+ timeout: 1 // long-async.html takes 10s to run, we expect it to be skipped
+ })
+ }))
+ .addBatch(hub.functionalContext({
"visits Yeti then aborts during the batch": clientFailureContext(withTests("long-async.html"))
}))
.addBatch(hub.functionalContext({

0 comments on commit 807b0fa

Please sign in to comment.
Something went wrong with that request. Please try again.