Add progress information during exploration
This commit is contained in:
		
							parent
							
								
									aec7db0183
								
							
						
					
					
						commit
						bd2300303b
					
				| 
						 | 
					@ -10,9 +10,10 @@ const GRAPH_LINK = '    "%s" -> "%s"';
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @async
 | 
					 * @async
 | 
				
			||||||
 * @param string videoId Source video identifier.
 | 
					 * @param string videoId Source video identifier.
 | 
				
			||||||
 | 
					 * @param function onUpdate Callback run every time a new video is explored.
 | 
				
			||||||
 * @return Array.<Object, Object> Nodes and set of neighbors of each node.
 | 
					 * @return Array.<Object, Object> Nodes and set of neighbors of each node.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const exploreVideos = async videoId =>
 | 
					export const exploreVideos = async (videoId, onUpdate) =>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Store metadata about each visited video
 | 
					    // Store metadata about each visited video
 | 
				
			||||||
    const videosNodes = Object.create(null);
 | 
					    const videosNodes = Object.create(null);
 | 
				
			||||||
| 
						 | 
					@ -46,6 +47,8 @@ export const exploreVideos = async videoId =>
 | 
				
			||||||
                queue.push(nextId);
 | 
					                queue.push(nextId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        onUpdate(Object.keys(videosNodes).length, queue.length);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return [videosNodes, nextVideos];
 | 
					    return [videosNodes, nextVideos];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import { toSVG } from '../lib/graphviz.mjs';
 | 
				
			||||||
const router = express.Router();
 | 
					const router = express.Router();
 | 
				
			||||||
export default router;
 | 
					export default router;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const statusDone = Symbol('DONE');
 | 
				
			||||||
const statusPending = Symbol('PENDING');
 | 
					const statusPending = Symbol('PENDING');
 | 
				
			||||||
const statusError = Symbol('ERROR');
 | 
					const statusError = Symbol('ERROR');
 | 
				
			||||||
const cache = Object.create(null);
 | 
					const cache = Object.create(null);
 | 
				
			||||||
| 
						 | 
					@ -45,37 +46,47 @@ router.get('/:videoId', async (req, res) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (videoId in cache)
 | 
					    if (videoId in cache)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (cache[videoId] === statusPending)
 | 
					        if (cache[videoId][0] === statusPending)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            res.header('Refresh', '5');
 | 
					            res.header('Refresh', '5');
 | 
				
			||||||
            res.send('Exploration in progress… Please wait.');
 | 
					            res.send(`Exploration in progress, please wait.<br>
 | 
				
			||||||
 | 
					${cache[videoId][1]}…`);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (cache[videoId] === statusError)
 | 
					        else if (cache[videoId][0] === statusError)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            res.status(500).send('Error');
 | 
					            res.status(500).send('Error');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            res.send(cache[videoId]);
 | 
					            res.send(cache[videoId][1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        cache[videoId] = statusPending;
 | 
					        cache[videoId] = [statusPending, 'Starting exploration'];
 | 
				
			||||||
        res.header('Refresh', '1');
 | 
					        res.header('Refresh', '1');
 | 
				
			||||||
        res.send('Exploration in progress… Please wait.');
 | 
					        res.send('Exploration in progress, please wait.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            const graph = await exploreVideos(req.params.videoId);
 | 
					            const graph = await exploreVideos(req.params.videoId, (done, rem) =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                cache[videoId] = [
 | 
				
			||||||
 | 
					                    statusPending,
 | 
				
			||||||
 | 
					                    `${done} videos explored, ${rem} pending`
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cache[videoId] = [statusPending, 'Converting graph to SVG'];
 | 
				
			||||||
            const graphviz = toGraphviz(...graph);
 | 
					            const graphviz = toGraphviz(...graph);
 | 
				
			||||||
            const svg = await toSVG(graphviz);
 | 
					            const svg = await toSVG(graphviz);
 | 
				
			||||||
            cache[videoId] = svg;
 | 
					
 | 
				
			||||||
 | 
					            cache[videoId] = [statusDone, svg];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (err)
 | 
					        catch (err)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            console.error(err);
 | 
					            console.error(err);
 | 
				
			||||||
            cache[videoId] = statusError;
 | 
					            cache[videoId] = [statusError];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue