Mercurial > hg > ugly-duckling
comparison src/app/services/feature-extraction/FeatureExtractionWorker.ts @ 449:dc7237d84f8d
When a remote extractor fails, still populate menu with ones that were valid.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Wed, 28 Jun 2017 10:40:36 +0100 |
parents | 676c4d6d35f7 |
children | c39df81c4dae |
comparison
equal
deleted
inserted
replaced
448:d2cf357c946b | 449:dc7237d84f8d |
---|---|
43 }); | 43 }); |
44 }; | 44 }; |
45 | 45 |
46 return tasks.reduce((runningResponses, nextResponse) => { | 46 return tasks.reduce((runningResponses, nextResponse) => { |
47 return runningResponses.then(response => { | 47 return runningResponses.then(response => { |
48 return reducer(response, nextResponse()); | 48 try { |
49 return reducer(response, nextResponse()); | |
50 } catch (e) { | |
51 throw new QueuedTaskFailure(runningResponses); | |
52 } | |
49 }); | 53 }); |
50 }, Promise.resolve([])); | 54 }, Promise.resolve([])); |
55 } | |
56 | |
57 class QueuedTaskFailure<T> extends Error { | |
58 public previousResponses: Promise<T[]>; | |
59 | |
60 constructor(previousResponses: Promise<T[]>, message?: string) { | |
61 super(message || 'Queued task failed.'); | |
62 this.previousResponses = previousResponses; | |
63 } | |
64 } | |
65 | |
66 function flattenListResponses(responses: ListResponse[]): ListResponse { | |
67 return { | |
68 available: responses.reduce( | |
69 (flat, res) => flat.concat(res.available), | |
70 [] | |
71 ) | |
72 }; | |
51 } | 73 } |
52 | 74 |
53 class AggregateStreamingService implements StreamingService { | 75 class AggregateStreamingService implements StreamingService { |
54 private services: Map<LibraryKey, Factory<PiperStreamingService>>; | 76 private services: Map<LibraryKey, Factory<PiperStreamingService>>; |
55 | 77 |
69 | 91 |
70 list(request: ListRequest): Promise<ListResponse> { | 92 list(request: ListRequest): Promise<ListResponse> { |
71 const listThunks: (() => Promise<ListResponse>)[] = [ | 93 const listThunks: (() => Promise<ListResponse>)[] = [ |
72 ...this.services.values() | 94 ...this.services.values() |
73 ].map(createClient => () => createClient().list({})); | 95 ].map(createClient => () => createClient().list({})); |
74 | 96 return waterfall(listThunks) |
75 return waterfall(listThunks).then(responses => ({ | 97 .then(flattenListResponses); |
76 available: responses.reduce((flat, res) => flat.concat(res.available), []) | |
77 })); | |
78 } | 98 } |
79 | 99 |
80 process(request: SimpleRequest): Observable<StreamingResponse> { | 100 process(request: SimpleRequest): Observable<StreamingResponse> { |
81 return this.dispatch('process', request); | 101 return this.dispatch('process', request); |
82 } | 102 } |
160 .then(response => { | 180 .then(response => { |
161 this.workerScope.postMessage({ | 181 this.workerScope.postMessage({ |
162 method: 'import', | 182 method: 'import', |
163 result: response | 183 result: response |
164 }); | 184 }); |
185 }) | |
186 .catch((e) => { | |
187 console.warn(`${e.message}. Try using results so far`); | |
188 e.previousResponses.then(responses => { | |
189 this.workerScope.postMessage({ | |
190 method: 'import', | |
191 result: flattenListResponses(responses) | |
192 }); | |
193 }); | |
165 }); | 194 }); |
166 } | 195 } |
167 }; | 196 }; |
168 } | 197 } |
169 | 198 |
170 private downloadRemoteLibrary(key: LibraryKey, | 199 private downloadRemoteLibrary(key: LibraryKey, |
171 uri: LibraryUri): Promise<Factory<Service>> { | 200 uri: LibraryUri): Promise<Factory<Service>> { |
172 return new Promise((res, rej) => { | 201 return new Promise((res, rej) => { |
173 this.requireJs([uri], (plugin) => { | 202 this.requireJs([uri], (createModule) => { |
174 res(() => { | 203 res(() => { |
175 // TODO a factory with more logic probably belongs in piper-js | 204 // TODO a factory with more logic probably belongs in piper-js |
176 const lib: any | EmscriptenModule = plugin.createLibrary(); | 205 const lib: any | EmscriptenModule = createModule(); |
177 const isEmscriptenModule = typeof lib.cwrap === 'function'; | 206 const isEmscriptenModule = typeof lib.cwrap === 'function'; |
178 return isEmscriptenModule ? new PiperVampService(lib) : lib; // TODO | 207 return isEmscriptenModule ? new PiperVampService(lib) : lib; // TODO |
179 }); | 208 }); |
180 }, (err) => { | 209 }, (err) => { |
181 rej(`Failed to load ${key} remote module.`); | 210 rej(`Failed to load ${key} remote module.`); |