diff --git a/src/index.ts b/src/index.ts index 94e7652..4725c19 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,10 @@ import { app } from './server'; -import { updateData, startPeriodicUpdates } from './utils/data_fetcher'; +import { updateData, startPeriodicallyCalling } from './utils/data_fetcher'; updateData(); const default_interval: string = (1000 * 60 * 60 * 24).toString(); const interval: string = process.env["UPDATE_INTERVAL"] || default_interval; -startPeriodicUpdates(parseInt(interval)); +startPeriodicallyCalling(updateData, parseInt(interval)); const PORT = process.env.PORT || 3000; diff --git a/src/utils/__tests__/test_data_fetcher.ts b/src/utils/__tests__/test_data_fetcher.ts new file mode 100644 index 0000000..7b9b2d1 --- /dev/null +++ b/src/utils/__tests__/test_data_fetcher.ts @@ -0,0 +1,19 @@ +import {startPeriodicallyCalling} from "../data_fetcher"; + +describe("Data updating functions", () => { + + it("should update once for each period", () => { + let updateData = jest.fn(); + startPeriodicallyCalling(updateData, 300, new Date()); + setTimeout(() => expect(updateData).toHaveBeenCalledTimes(3), 1000); + }); + + it("should only start updating after the start date", () => { + let updateData = jest.fn(); + const startDate = new Date(); + startDate.setMilliseconds(startDate.getMilliseconds() + 500); + startPeriodicallyCalling(updateData, 200, startDate); + setTimeout(() => expect(updateData).toHaveBeenCalledTimes(0), 400); + setTimeout(() => expect(updateData).toHaveBeenCalledTimes(2), 1000); + }); +}); diff --git a/src/utils/data_fetcher.ts b/src/utils/data_fetcher.ts index a781d31..278d876 100644 --- a/src/utils/data_fetcher.ts +++ b/src/utils/data_fetcher.ts @@ -4,26 +4,35 @@ let mostRecentGeneMap: GeneMap; let mostRecentAnnotations: IAnnotation[]; let mostRecentGroupedAnnotations: GroupedAnnotations>; -export const updateData = () => { +export const getGeneMap = (): GeneMap => { return mostRecentGeneMap; }; + +export const getAnnotations = (): IAnnotation[] => { return mostRecentAnnotations; }; + +export const getGroupedAnnotations = (): GroupedAnnotations> => { return mostRecentGroupedAnnotations; }; + +export const downloadData = (dataUrl: string = "http://current.geneontology.org/annotations/tair.gaf.gz") => { const { execSync } = require("child_process"); - const stdout = execSync("wget http://current.geneontology.org/annotations/tair.gaf.gz ; gunzip tair.gaf.gz"); + const stdout = execSync("wget " + dataUrl + " ; gunzip tair.gaf.gz"); +} +export const updateData = () => { + downloadData(); const { geneMap, annotations, groupedAnnotations } = readData(); mostRecentGeneMap = geneMap; mostRecentAnnotations = annotations; mostRecentGroupedAnnotations = groupedAnnotations; }; -export const startPeriodicUpdates = (interval: number = (1000 * 60 * 60 * 24), startDate: Date = getTomorrowMorning()) => { +export const startPeriodicallyCalling = (fn: (...args: any[]) => void, interval: number = (1000 * 60 * 60 * 24), startDate: Date = getTomorrowMorning()) => { const now = new Date(); - if (sameTimeOfDay(startDate, now)) { - setInterval(updateData, interval); + if (isSameTimeOfDay(startDate, now)) { + setInterval(fn, interval); } else { let difference = startDate.getTime() - now.getTime(); if (difference > 0) { - setTimeout(startPeriodicUpdates, difference, interval, startDate); + setTimeout(startPeriodicallyCalling, difference, fn, interval, startDate); } - setInterval(updateData, interval); // Just begins the updates now if the startDate is in the past + setInterval(fn, interval); // Just begins the updates now if the startDate is in the past } }; @@ -36,12 +45,6 @@ const getTomorrowMorning = (): Date => { return tomorrowMorning; }; -const sameTimeOfDay = (time1, time2) => { +const isSameTimeOfDay = (time1, time2) => { return time1.getHours() === time2.getHours() && time1.getMinutes() === time2.getMinutes(); } - -export const getGeneMap = (): GeneMap => { return mostRecentGeneMap; }; - -export const getAnnotations = (): IAnnotation[] => { return mostRecentAnnotations; }; - -export const getGroupedAnnotations = (): GroupedAnnotations> => { return mostRecentGroupedAnnotations; };