Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Issue #14, persist test with fixes

* Fix read from cache
* Update lru info on hit in cache
* Fix cache cleanup
* Better test cleanup
  • Loading branch information...
commit dc88df3b9af5575bd97b2cc8ca7ab5970c7b0808 1 parent ee382f1
@parente parente authored
Showing with 87 additions and 22 deletions.
  1. +47 −19 JSonic.js
  2. +3 −3 tests/index.html
  3. +37 −0 tests/persist.js
View
66 JSonic.js
@@ -576,7 +576,15 @@ dojo.declare('uow.audio.LRUCache', null, {
}
},
+ get: function(key) {
+ var node = this._index[key];
+ if(node) {
+ return node.value;
+ }
+ },
+
push: function(key, value) {
+ console.log('pushing', key);
// see if the key is already in the cache
var curr = this._index[key];
if(curr) {
@@ -660,8 +668,18 @@ dojo.declare('uow.audio.JSonicCache', dijit._Widget, {
throw new Error('no known media supported');
}
},
+
+ uninitialize: function() {
+ // persist cache before cleanup
+ this._serialize();
+ this._destroyed = true;
+ },
_serialize: function() {
+ if(this._destroyed) {
+ // don't persist if instance is destroyed
+ return;
+ }
localStorage['jsonic.cache'] = dojo.toJson(this._speechCache.toArray());
},
@@ -679,7 +697,7 @@ dojo.declare('uow.audio.JSonicCache', dijit._Widget, {
}
},
- resetCache: function(args) {
+ resetCache: function() {
if(localStorage) {
// clear out the cache
delete localStorage['jsonic.cache'];
@@ -687,9 +705,6 @@ dojo.declare('uow.audio.JSonicCache', dijit._Widget, {
localStorage['jsonic.version'] = uow.audio._jsonicVersion;
}
this._speechCache = new uow.audio.LRUCache({maxSize : this.maxSize});
- // if(args) {
- // delete this._speechCache[args.key];
- // }
},
getEngines: function() {
@@ -766,31 +781,38 @@ dojo.declare('uow.audio.JSonicCache', dijit._Widget, {
getSpeech: function(args, props) {
// get the client cache key
- var key = this._getSpeechCacheKey(args.text, props);
+ var key = this._getSpeechCacheKey(args.text, props),
+ resultDef, audioNode, fileName, speechParams, request;
args.key = key;
- var resultDef, audioNode;
+
+ // @todo: because we don't update lru upon each result, it's not
+ // truly lru; to meet strict definition, need to update stats
+ // when audio is actually used, not just when it's returned from
+ // the server; trying the simple way first, probably good enough
resultDef = this._speechRenderings[key];
if(resultDef) {
// return deferred result for synth already in progress on server
return resultDef;
}
- var response = this._speechCache[key];
- if(response) {
- // build a new audio node for a known speech file url
- audioNode = this._onSpeechSynthed(null, args, response);
+ fileName = this._speechCache.get(key);
+ if(fileName) {
+ console.log('known key', key);
+ // known key
+ this._speechCache.push(key, fileName);
+ audioNode = this._buildNode(fileName);
resultDef = new dojo.Deferred();
resultDef.callback(audioNode);
return resultDef;
}
// synth on server
- var speechParams = {
+ speechParams = {
format : this._ext,
utterances : {text : args.text},
properties: props
};
resultDef = new dojo.Deferred();
- var request = {
+ request = {
url : this.jsonicURI+'synth',
handleAs: 'json',
postData : dojo.toJson(speechParams),
@@ -821,15 +843,21 @@ dojo.declare('uow.audio.JSonicCache', dijit._Widget, {
_onSpeechSynthed: function(resultDef, args, response) {
delete this._speechRenderings[args.key];
- var node = {}; //dojo.create('audio');
- node.autobuffer = true;
- node.preload = 'auto';
- node.src = this.jsonicURI+'files/'+response.result.text+this._ext;
+ var fileName = response.result.text;
+ var node = this._buildNode(fileName);
if(args.cache) {
// cache the speech file url and properties
- this._speechCache.push(args.key, response);
+ this._speechCache.push(args.key, fileName);
}
- if(resultDef) {resultDef.callback(node);}
+ resultDef.callback(node);
+ return node;
+ },
+
+ _buildNode: function(fileName) {
+ var node = {}; //dojo.create('audio');
+ node.autobuffer = true;
+ node.preload = 'auto';
+ node.src = this.jsonicURI+'files/'+fileName+this._ext;
return node;
}
});
@@ -1144,7 +1172,7 @@ dojo.declare('uow.audio.JSonicChannel', dijit._Widget, {
if(this._kind === 'say') {
// if speech, dump the entire local cache assuming we need a
// resynth of everything
- this.cache.resetCache(this._args);
+ this.cache.resetCache();
}
// clear everything before the callback
var cargs = this._args;
View
6 tests/index.html
@@ -38,16 +38,16 @@
}
};
QUnit.moduleDone = function(name) {
- if(uow.audio.initJSonic) {
+ if(uow.audio._jsonicInstance) {
// cleanup JSonic singleton before next module runs
- var js = uow.audio.initJSonic();
- js.destroyRecursive();
+ uow.audio._jsonicInstance.destroyRecursive();
}
};
dojo.require('uow.audio.JSonic');
dojo.require('uow.audio.tests.lru');
dojo.require('uow.audio.tests.creation');
+ dojo.require('uow.audio.tests.persist');
dojo.require('uow.audio.tests.simple');
dojo.require('uow.audio.tests.interrupt');
dojo.require('uow.audio.tests.sequential');
View
37 tests/persist.js
@@ -0,0 +1,37 @@
+/*global TO UT1 UT2 localStorage dojo ok equal getModOpts module test stop start uow*/
+dojo.provide('uow.audio.tests.persist');
+
+(function() {
+ module('persist', {
+ setup: function() {
+ this.js = uow.audio.initJSonic({defaultCaching : true});
+ },
+ teardown: function() {
+ if(this.js) {
+ this.js.destroyRecursive();
+ }
+ delete localStorage['jsonic.cache'];
+ }
+ });
+ test('persist cache', 4, function () {
+ stop(TO);
+ var self = this;
+ this.js.say({text : UT1}).callAfter(function() {
+ self.js.say({text : UT1}).callAfter(function() {
+ // destroy instance to force persistence of cache
+ self.js.destroy();
+ // verify cache created and its length
+ var arr = dojo.fromJson(localStorage['jsonic.cache']);
+ equal(arr.length, 2);
+ equal(arr[0][0].slice(0, UT2.length), UT2);
+ equal(arr[1][0].slice(0, UT1.length), UT1);
+ // build a new instance to read the cache
+ self.js = uow.audio.initJSonic({defaultCaching : true});
+ // whitebox: look at cache contents
+ equal(self.js._cache._speechCache.size, 2);
+ start();
+ });
+ });
+ this.js.say({text : UT2});
+ });
+}());
Please sign in to comment.
Something went wrong with that request. Please try again.