Browse Source

Cache TaM information on disk

main
Mattéo Delabre 2 years ago
parent
commit
ef6b4b9741
Signed by: matteo GPG Key ID: AE3FBD02DC583ABB
  1. 1
      .gitignore
  2. 65
      src/tam/sources/tam.js

1
.gitignore

@ -1,3 +1,4 @@
node_modules
dist
.cache
cache

65
src/tam/sources/tam.js

@ -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…
Cancel
Save