Skip to content

Commit 67448a7

Browse files
authored
Merge pull request #4 from catalyzt-tech/RPGF-90-Migrate-Agora-Cache-To-Worker
RPGF-90 Migrate agora cache to worker
2 parents 99168bf + 7f05eae commit 67448a7

File tree

14 files changed

+114
-13
lines changed

14 files changed

+114
-13
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ Worker dynamically imports and executes TypeScript files from the `src/scripts`
1111
- It should export a `CRON_TIMER` variable that will be used to set the cronjob timer
1212
- CRON_TIMER is the cronjob timer for the module, it can be undefined if the module is not a cronjob
1313
- Visit https://github.com/node-cron/node-cron to learn the format of cronjob
14+
- <a href="https://cloud.google.com/scheduler/docs/configuring/cron-job-schedules">https://cloud.google.com/scheduler/docs/configuring/cron-job-schedules</a>
1415

1516
## Api Route
1617
- Get /api/ will list all the static file that can be served
1718
- Get /api/(any-file-name) will serve the file
1819
- Get /api/(any-folder-name) will list all the file in the folder
1920
- Get /api/(any-folder-name)/(any-file-name) will serve the file
2021
- Get /api/modules will list all the modules that can we run
21-
- Post /api/modules/run/(any-module-name) will run the module
22+
- Post /backoffice/modules/run/(any-module-name) will run the module
2223
- it required post body with a password
2324

2425

@@ -35,4 +36,3 @@ Worker dynamically imports and executes TypeScript files from the `src/scripts`
3536
pnpm run build
3637
node dist/src/index.js
3738
```
38-

data/agora-cache/agora-cache.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

data/retropgf5-live-data/retropgf5-live-data.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/example.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ const MODULE_NAME = "MODULE_NAME"
33
const DATA_DIR = [ 'data', 'any-folder-name']
44

55
// CRON_TIMER is the cron job timer for the module, it can be undefined if the module is not a cron job
6+
// Which evaluates to 'At 0 seconds, 0 minutes every 1st hour'.
7+
// const CRON_TIMER = "0 0 */1 * * *"
68
// visit https://github.com/node-cron/node-cron to get the cron job timer
79
const CRON_TIMER:string | undefined = undefined
810

11+
912
async function Run() {
1013

1114
console.log(`${MODULE_NAME} is starting . . .`);

lib/op-github/save-file-mdx-from-github.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { FilePathAndUrl } from "../list-all-files-github-type";
55
import { chunkArray, convertSpecialChar, headerGithub } from "../../utils/utils";
66
import { Savefile } from "../save-file/save-file";
77

8-
8+
// SaveFileMdxGithub: use to save a file that scrape from github
99
export async function SaveFileMdxGithub(docs: FilePathAndUrl[], requiredPath: string[] = [], baseRefUrl:string) {
1010

1111
try {
@@ -31,7 +31,7 @@ export async function SaveFileMdxGithub(docs: FilePathAndUrl[], requiredPath: st
3131
headers: headers
3232
});
3333

34-
let content:string = "";
34+
let content:string = ""
3535

3636
// decode encrypt content from github
3737
const decodedContent = Buffer.from(response.data.content, 'base64').toString('utf-8');

lib/save-file/save-file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ export async function Savefile(data: any, requiredPath: string[] = [], fileName:
2424
console.log(`File successfully written to ${filePath}`);
2525
} catch (error) {
2626
console.error("An error occurred during the save file process:", error);
27-
throw error; // Re-throw the error for proper handling upstream
27+
throw new Error("An error occurred during the save file process");
2828
}
2929
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async function processScripts() {
6060
const dataDir = module.DATA_DIR.join("").replace("data","");
6161

6262
// get the api path
63-
const apiPath = "/api/modules/run/" + file;
63+
const apiPath = "/backoffice/modules/run/" + file;
6464

6565
// add to the res object
6666
fileNameAndApiPath[file] = apiPath;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface Response {
2+
meta: Meta;
3+
data: any;
4+
}
5+
6+
export interface Meta {
7+
has_next: boolean;
8+
total_returned: number;
9+
next_offset: number;
10+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import axios, { AxiosError, AxiosResponse } from 'axios'
2+
import { Response } from './agora-api-type'
3+
4+
// CallApiAgora: fetch a project base on limit and offset
5+
6+
const API_URL = 'https://vote.optimism.io/api/v1/retrofunding/rounds/5/projects'
7+
8+
async function CallApiAgora(limit: number, offset: number, authorizeKey: string): Promise<Response> {
9+
const url = `${API_URL}?limit=${limit}&offset=${offset}`
10+
try {
11+
const response: AxiosResponse<Response> = await axios.get(url, {
12+
maxBodyLength: Infinity,
13+
headers: {
14+
'Authorization': `Bearer ${authorizeKey}`
15+
}
16+
})
17+
18+
return response.data
19+
} catch (error) {
20+
if (axios.isAxiosError(error)) {
21+
const axiosError = error as AxiosError
22+
if (axiosError.response) {
23+
console.error(`API error: ${axiosError.response.status} - ${axiosError.response.statusText}`)
24+
throw new Error(`API error: ${axiosError.response.status} - ${axiosError.response.statusText}`)
25+
} else {
26+
console.error('Network error:', axiosError.message)
27+
throw new Error(`Network error: ${axiosError.message}`)
28+
}
29+
}
30+
console.error('Unexpected error:', error)
31+
throw error
32+
}
33+
}
34+
35+
// GetAllProjects: fetch all the exist project until the has_next is false
36+
export async function GetAllProjects(authorizeKey: string): Promise<Response[]> {
37+
let conditionBreak = false
38+
let limit = 100
39+
let offset = 0
40+
41+
let datas: Response[] = []
42+
43+
while (!conditionBreak) {
44+
try {
45+
const data = await CallApiAgora(limit, offset, authorizeKey)
46+
if (data){
47+
datas = datas.concat(data)
48+
if (data.meta.has_next) {
49+
offset += 100
50+
} else {
51+
conditionBreak = true
52+
}
53+
}
54+
} catch (error) {
55+
console.error('Error fetching projects:', error)
56+
throw error
57+
}
58+
}
59+
60+
return datas
61+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Savefile } from "../../../lib/save-file/save-file"
2+
import { GetAllProjects } from "./_helper/agora-api"
3+
4+
const DATA_DIR = ["data", "agora-cache"]
5+
const FILENAME = "agora-cache.json"
6+
7+
// Schedule a task to run every 30 minutes
8+
const CRON_TIMER: string | undefined = "*/30 * * * *"
9+
10+
async function Run() {
11+
console.log("Agora cache starting is starting . . .")
12+
try {
13+
14+
const agoraKey = process.env.AGORA_KEY
15+
if (!agoraKey){
16+
throw new Error("Can't find agora key")
17+
}
18+
19+
let projects = await GetAllProjects(agoraKey)
20+
if (!projects || projects.length === 0) {
21+
throw new Error("No projects data found")
22+
}
23+
await Savefile(JSON.stringify(projects), DATA_DIR, FILENAME)
24+
25+
} catch (error) {
26+
console.error("An error occurred during the Agora cache starting process:", error)
27+
} finally {
28+
console.log("Agora cache starting process finished.")
29+
}
30+
}
31+
32+
export { Run, DATA_DIR, CRON_TIMER }

0 commit comments

Comments
 (0)