Cache TaM information on disk
This commit is contained in:
parent
3600e0b2bf
commit
ef6b4b9741
|
@ -1,3 +1,4 @@
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
.cache
|
.cache
|
||||||
|
cache
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
const csv = require("csv-parse");
|
const csv = require("csv-parse");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs").promises;
|
||||||
const { snakeToCamelCase, unzipFile } = require("../../util");
|
const { snakeToCamelCase, unzipFile } = require("../../util");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,15 +19,65 @@ const { snakeToCamelCase, unzipFile } = require("../../util");
|
||||||
* @property {string} directionId Route identifier inside the line.
|
* @property {string} directionId Route identifier inside the line.
|
||||||
* @property {string} departureTime Theoretical time at which the
|
* @property {string} departureTime Theoretical time at which the
|
||||||
* vehicle will depart the stop (HH:MM:SS format).
|
* vehicle will depart the stop (HH:MM:SS format).
|
||||||
* @property {string} isTheorical (sic) Whether the arrival time is only
|
* @property {string} isTheorical (sic) True if this is only the planned
|
||||||
* a theoretical information.
|
* passing time, false if this is real-time information.
|
||||||
* @property {string} delaySec Number of seconds before the vehicle arrives
|
* @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
|
* @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 realtimeEndpoint = "http://data.montpellier3m.fr/node/10732/download";
|
||||||
|
const realtimeCachePath = path.join(cacheDir, "realtime.json");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch real time passings of vehicles across the network.
|
* 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 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.
|
* 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