Cache TaM information on disk
This commit is contained in:
parent
3600e0b2bf
commit
ef6b4b9741
|
@ -1,3 +1,4 @@
|
|||
node_modules
|
||||
dist
|
||||
.cache
|
||||
cache
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
const csv = require("csv-parse");
|
||||
const axios = require("axios");
|
||||
const path = require("path");
|
||||
const fs = require("fs").promises;
|
||||
const { snakeToCamelCase, unzipFile } = require("../../util");
|
||||
|
||||
/**
|
||||
|
@ -17,15 +19,65 @@ const { snakeToCamelCase, unzipFile } = require("../../util");
|
|||
* @property {string} directionId Route identifier inside the line.
|
||||
* @property {string} departureTime Theoretical time at which the
|
||||
* vehicle will depart the stop (HH:MM:SS format).
|
||||
* @property {string} isTheorical (sic) Whether the arrival time is only
|
||||
* a theoretical information.
|
||||
* @property {string} isTheorical (sic) True if this is only the planned
|
||||
* passing time, false if this is real-time information.
|
||||
* @property {string} delaySec Number of seconds before the vehicle arrives
|
||||
* at the station.
|
||||
* at the station (only if isTheorical is false).
|
||||
* @property {string} destArCode Unique network identifier for the final
|
||||
* stop of this trip.
|
||||
* stop of this trip (only if isTheorical is false).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrap a passing-fetching function to use a filesystem-based cache.
|
||||
*
|
||||
* @param {function} func Fetching function to wrap.
|
||||
* @param {string} cachePath Path to the file to use as a cache (will be
|
||||
* overwritten, may be non-existing).
|
||||
* @return {function} Wrapped function.
|
||||
*/
|
||||
const makeCached = (func, cachePath) => {
|
||||
return async function *() {
|
||||
try {
|
||||
const cacheRaw = await fs.readFile(cachePath, {encoding: "utf8"});
|
||||
const cache = JSON.parse(cacheRaw);
|
||||
|
||||
if (Date.now() < cache.timing.nextUpdate) {
|
||||
yield cache.timing;
|
||||
|
||||
for (const passing of cache.passings) {
|
||||
yield passing;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignore missing cache file
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const passings = func();
|
||||
const newCache = {
|
||||
timing: (await passings.next()).value,
|
||||
passings: [],
|
||||
};
|
||||
|
||||
yield newCache.timing;
|
||||
|
||||
for await (const passing of passings) {
|
||||
newCache.passings.push(passing);
|
||||
yield passing;
|
||||
}
|
||||
|
||||
fs.writeFile(cachePath, JSON.stringify(newCache));
|
||||
};
|
||||
};
|
||||
|
||||
const cacheDir = path.join(__dirname, "..", "..", "..", "cache");
|
||||
|
||||
const realtimeEndpoint = "http://data.montpellier3m.fr/node/10732/download";
|
||||
const realtimeCachePath = path.join(cacheDir, "realtime.json");
|
||||
|
||||
/**
|
||||
* Fetch real time passings of vehicles across the network.
|
||||
|
@ -54,9 +106,10 @@ const fetchRealtime = async function *() {
|
|||
}
|
||||
};
|
||||
|
||||
exports.fetchRealtime = fetchRealtime;
|
||||
exports.fetchRealtime = makeCached(fetchRealtime, realtimeCachePath);
|
||||
|
||||
const theoreticalEndpoint = "http://data.montpellier3m.fr/node/10731/download";
|
||||
const theoreticalCachePath = path.join(cacheDir, "theoretical.json");
|
||||
|
||||
/**
|
||||
* Fetch theoretical passings for the current day across the network.
|
||||
|
@ -101,4 +154,4 @@ const fetchTheoretical = async function *() {
|
|||
}
|
||||
};
|
||||
|
||||
exports.fetchTheoretical = fetchTheoretical;
|
||||
exports.fetchTheoretical = makeCached(fetchTheoretical, theoreticalCachePath);
|
||||
|
|
Loading…
Reference in New Issue