Skip to content

Commit

Permalink
Merge pull request #254 from daisy/fetch-caching
Browse files Browse the repository at this point in the history
Fetch caching
  • Loading branch information
marisademeglio authored Nov 8, 2024
2 parents fc94f62 + 2361249 commit 89f8a48
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 64 deletions.
37 changes: 19 additions & 18 deletions src/main/data/middlewares/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,21 +443,21 @@ export function pipelineMiddleware({ getState, dispatch }) {
// dispatch to sync the properties
// in the engine
dispatch(setProperties(settingsTtsProperties))
return pipelineAPI.fetchTtsVoices(
selectTtsConfig(getState())
)(newWebservice)
})
.then((voices: Array<TtsVoice>) => {
// console.log('TTS Voices', voices)
dispatch(setTtsVoices(voices))
return pipelineAPI.fetchTtsEnginesState()(
newWebservice
)
})
.then((states) => {
console.log('tts states', states)
dispatch(setTtsEngineState(states))
// return pipelineAPI.fetchTtsVoices(
// selectTtsConfig(getState())
// )(newWebservice)
})
// .then((voices: Array<TtsVoice>) => {
// // console.log('TTS Voices', voices)
// dispatch(setTtsVoices(voices))
// return pipelineAPI.fetchTtsEnginesState()(
// newWebservice
// )
// })
// .then((states) => {
// //console.log('tts states', states)
// dispatch(setTtsEngineState(states))
// })
.catch((e) => {
error('useWebservice', e, e.parsedText)
if (e instanceof AbortError) {
Expand Down Expand Up @@ -667,9 +667,10 @@ export function pipelineMiddleware({ getState, dispatch }) {
)
//.then(() => pipelineAPI.fetchProperties()(webservice))
.then(() => {
// If any of the properties updated is a TTS engine key
// property, reload voice list
if (
// If voices list is not yet initialised
// or any of the properties updated is a TTS engine key
// property, reload voices list when properties are set
if (getState().pipeline.ttsVoices == null ||
newProperties.find(
(p) =>
p.name.indexOf('.tts.') >= 0 &&
Expand Down Expand Up @@ -749,7 +750,7 @@ export function pipelineMiddleware({ getState, dispatch }) {
)
})
.then((states) => {
console.log('tts states', states)
//console.log('tts states', states)
dispatch(setTtsEngineState(states))
})
}
Expand Down
35 changes: 20 additions & 15 deletions src/renderer/components/SettingsView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,21 +379,26 @@ export function SettingsView() {
</div>
) : selectedSection == SelectedMenuItem.TTSVoices ? (
<div className="tts-voices-config">
<TtsVoicesConfigPane
availableVoices={pipeline.ttsVoices}
userPreferredVoices={
newSettings.ttsConfig.preferredVoices
}
userDefaultVoices={
newSettings.ttsConfig.defaultVoices
}
onChangePreferredVoices={
onTtsVoicesPreferenceChange
}
onChangeDefaultVoices={
onTtsVoicesDefaultsChange
}
/>
{pipeline.ttsVoices ? (
<TtsVoicesConfigPane
availableVoices={pipeline.ttsVoices}
userPreferredVoices={
newSettings.ttsConfig.preferredVoices
}
ttsEnginesStates={pipeline.ttsEnginesStates}
userDefaultVoices={
newSettings.ttsConfig.defaultVoices
}
onChangePreferredVoices={
onTtsVoicesPreferenceChange
}
onChangeDefaultVoices={
onTtsVoicesDefaultsChange
}
/>
) : (
<p>Loading voices...</p>
)}
</div>
) : selectedSection == SelectedMenuItem.TTSEngines ? (
<div className="tts-engines-config">
Expand Down
23 changes: 9 additions & 14 deletions src/renderer/components/TtsVoicesConfig/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import { VoicePreview } from './VoicePreview'
export function TtsVoicesConfigPane({
availableVoices,
userPreferredVoices,
ttsEnginesStates,
userDefaultVoices,
onChangePreferredVoices,
onChangeDefaultVoices,
}) {
const { pipeline } = useWindowStore()

const [preferredVoices, setPreferredVoices] = useState([
...userPreferredVoices,
])
Expand Down Expand Up @@ -87,11 +86,11 @@ export function TtsVoicesConfigPane({
setPreferredVoicesLanguage(e.target.value)
}
let selectDefault = (e, voice) => {
console.log('select default', e, voice)
let tmpVoices = [...defaultVoices]
let oldDefaultIdx = tmpVoices.findIndex(
console.log('default voices', defaultVoices)
let tmpVoices = defaultVoices ? [...defaultVoices] : []
let oldDefaultIdx = tmpVoices?.findIndex(
(vx) => getLang(vx.lang) == getLang(voice.lang)
)
) ?? -1
if (oldDefaultIdx != -1) {
console.log(getLang(voice.lang), ' has default already')
tmpVoices.splice(oldDefaultIdx, 1)
Expand All @@ -101,8 +100,7 @@ export function TtsVoicesConfigPane({
onChangeDefaultVoices(tmpVoices)
}
let clearDefaultVoice = (langCode) => {
console.log('clear default', langCode)
let tmpVoices = [...defaultVoices]
let tmpVoices = defaultVoices ? [...defaultVoices] : []
let oldDefaultIdx = tmpVoices.findIndex(
(vx) => getLang(vx.lang) == langCode
)
Expand Down Expand Up @@ -425,11 +423,8 @@ export function TtsVoicesConfigPane({
v.name}
</td>
<td>
{
pipeline.ttsEnginesStates[
v.engine
].name
}
{ttsEnginesStates[v.engine]?.name ??
v.engine}
</td>
<td>{languageNames.of(v.lang)}</td>
<td>{v.gender}</td>
Expand All @@ -449,7 +444,7 @@ export function TtsVoicesConfigPane({
selectDefault(e, v)
}
defaultChecked={
defaultVoices.find(
defaultVoices?.find(
(vx) =>
vx.id == v.id
) != undefined
Expand Down
61 changes: 46 additions & 15 deletions src/shared/data/apis/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,39 +55,70 @@ interface RequestInit {
export class PipelineAPI {
fetchFunc: (url: string, options?: RequestInit) => Promise<Response>
info: (message?: any, ...optionalParams: any[]) => void
// Cache to avoid multiple fetches on the same url
fetchCache: Map<string, {count:number,request:Promise<any>}> = new Map()

constructor(fetchFunc, info?) {
this.fetchFunc = fetchFunc
this.info = info ?? console.info
}
/**
* Create a fetch function on the pipeline webservice
* for which the resulting pipeline xml is parsed and converted to a js object
* @type T return type of the parser
* @type {T} return type of the parser
* @param webserviceUrlBuilder method to build a url,
* optionnaly using a webservice (like ``(ws) => `${baseurl(ws)}/scripts` ``)
* @param parser method to convert pipeline xml to an object object
* @param options options to be passed to the fetch call
* (like `{method:'POST', body:whateveryoulike}`)
* @returns a customized fetch function from the webservice
* `` (ws:Webservice) => Promise<Awaited<T>> ``
* `` (ws:Webservice) => Promise<T> ``
*/
createPipelineFetchFunction<T>(
webserviceUrlBuilder: (ws: Webservice) => string,
parser: (text: string) => T,
options?: RequestInit
) {
) : (ws?: Webservice) => Promise<T> {
return (ws?: Webservice) => {
this.info(
'fetching ',
webserviceUrlBuilder(ws),
JSON.stringify(options)
)
return this.fetchFunc(webserviceUrlBuilder(ws), {
...options,
signals: options?.signals ?? AbortSignal.timeout(5000),
})
.then((response: Response) => response.text())
.then((text: string) => parser(text))
const url = webserviceUrlBuilder(ws)
const fetcher = (launch = 1) => {
this.info(`createPipelineFetchFunction - Fetching ${launch}`, url, JSON.stringify(options))
this.fetchCache.set(
url,
{ count: launch,
request: this.fetchFunc(url, {
...options,
signals: options?.signals ?? AbortSignal.timeout(5000),
})
.then((response: Response) => {
this.info(`createPipelineFetchFunction - Response ${launch} to request` , url, JSON.stringify(options))
// Try to delete the cache if the fetch is successful
this.fetchCache.delete(url)
return response.text()
})
.then((text: string) => parser(text))
.catch((e) => {
this.info(`createPipelineFetchFunction - Error ${launch}`, url)
this.fetchCache.delete(url)
throw e
})
}
)
return this.fetchCache.get(url).request
}
if (this.fetchCache.has(url)) {
this.info(
'createPipelineFetchFunction - Requesting refetch on URL',
url,
JSON.stringify(options)
)
const lastCache = this.fetchCache.get(url)
// concatenate a new fetch to the existing promise
return lastCache.request.then(() => fetcher(lastCache.count + 1))
} else {
// Launching the first fetch
return fetcher()
}
}
}

Expand Down Expand Up @@ -209,7 +240,7 @@ export class PipelineAPI {
setProperty(prop: EngineProperty) {
return this.createPipelineFetchFunction(
(ws) => `${baseurl(ws)}/admin/properties/${prop.name}`,
(text) => console.log(text),
(text) => null, //this.info('Property', prop.name, 'successfully set to', text),
{
method: 'PUT',
body: propertyToXml(prop),
Expand Down
4 changes: 2 additions & 2 deletions src/shared/data/slices/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const initialState = {
webservice: null,
scripts: [],
datatypes: [],
ttsVoices: [],
ttsVoices: null,
jobs: [],
internalJobCounter: 0,
selectedJobId: '',
Expand Down Expand Up @@ -416,7 +416,7 @@ export const selectors = {
),
selectScripts: (state: RootState) => state.pipeline.scripts,
selectDatatypes: (state: RootState) => state.pipeline.datatypes,
selectTtsVoices: (state: RootState) => state.pipeline.ttsVoices,
selectTtsVoices: (state: RootState) => state.pipeline.ttsVoices ?? [],
selectProperties: (state: RootState) => state.pipeline.properties,
newJob: (pipeline: PipelineState) =>
({
Expand Down

0 comments on commit 89f8a48

Please sign in to comment.