Skip to content

Commit 9532b1a

Browse files
committed
refactor: set up remote wasm loading and local caching;
1 parent 15ecc4b commit 9532b1a

File tree

5 files changed

+71
-16
lines changed

5 files changed

+71
-16
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@inspatial/cloud",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"license": "Apache-2.0",
55
"exports": {
66
".": "./mod.ts",

src/orm/db/postgres/in-pg/in-pg.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import { normalizePath } from "./src/convert.ts";
22
import { FileManager } from "./src/fileManager/in-pg-files.ts";
33
import { PGMem } from "./src/pgMem.ts";
44
import { SysCalls } from "./src/syscalls.ts";
5-
import { ExitStatus } from "./src/utils.ts";
5+
import { ExitStatus, getTempDirBase } from "./src/utils.ts";
66
import { WasmLoader } from "./src/wasmLoader.ts";
77
import type { InPgOptions } from "./types.ts";
88

9-
const fileData = Deno.readFileSync(import.meta.dirname + `/src/inpg.data`);
10-
const wasmData = Deno.readFileSync(import.meta.dirname + `/src/inpg.wasm`);
119
export class InPG implements Deno.Conn {
1210
pgMem: PGMem;
1311
wasmLoader;
@@ -38,6 +36,15 @@ export class InPG implements Deno.Conn {
3836
debug?: boolean;
3937
#onStdErr: (message: any) => void;
4038
#onStdOut: (message: any) => void;
39+
#wasmData: Uint8Array = new Uint8Array(0);
40+
#fileData: Uint8Array = new Uint8Array(0);
41+
get wasmData() {
42+
return this.#wasmData;
43+
}
44+
45+
get fileData() {
46+
return this.#fileData;
47+
}
4148

4249
log(type: "out" | "err", chunk: Uint8Array) {
4350
if (!this.debug) {
@@ -89,11 +96,10 @@ export class InPG implements Deno.Conn {
8996
this.#bufferData = new Uint8Array(0);
9097
this.runtimeInitialized = false;
9198
this.pgMem = new PGMem(this);
92-
this.wasmLoader = new WasmLoader(this, wasmData);
99+
this.wasmLoader = new WasmLoader(this);
93100
this.readEmAsmArgsArray = [];
94101
this.fileManager = new FileManager(this, {
95102
debug: options?.debug,
96-
fileData,
97103
});
98104
this.sysCalls = new SysCalls(this);
99105

@@ -112,6 +118,7 @@ export class InPG implements Deno.Conn {
112118

113119
await this.wasmLoader.load();
114120
}
121+
115122
sendQuery(message: Uint8Array) {
116123
this.wasmLoader.callExportFunction("use_wire", 1);
117124
const msg_len = message.length;
@@ -143,6 +150,7 @@ export class InPG implements Deno.Conn {
143150
}
144151

145152
async run() {
153+
await this.loadRemoteFiles();
146154
await this.#setup();
147155
await this.initRuntime();
148156
this.#callMain(this.args);
@@ -178,7 +186,39 @@ export class InPG implements Deno.Conn {
178186
Deno.exit(1);
179187
}
180188
}
189+
async loadRemoteFiles() {
190+
const wasmUrl =
191+
"https://github.com/inspatiallabs/inspatial-cloud/releases/download/0.2.2/inpg.wasm";
192+
const dataUrl =
193+
"https://github.com/inspatiallabs/inspatial-cloud/releases/download/0.2.2/inpg.data";
194+
const tmpDirBase = getTempDirBase();
195+
const tmpDir = `${tmpDirBase}/in-pg`;
196+
197+
Deno.mkdirSync(tmpDir, { recursive: true });
181198

199+
const wasmFile = `${tmpDir}/inpg.0.2.2.wasm`;
200+
const dataFile = `${tmpDir}/inpg.0.2.2.data`;
201+
this.#wasmData = await this.loadRemoteFile(wasmFile, wasmUrl);
202+
this.#fileData = await this.loadRemoteFile(dataFile, dataUrl);
203+
}
204+
async loadRemoteFile(fileName: string, remoteUrl: string) {
205+
try {
206+
Deno.statSync(fileName);
207+
return Deno.readFileSync(fileName);
208+
} catch (e) {
209+
if (e instanceof Deno.errors.NotFound) {
210+
const response = await fetch(remoteUrl);
211+
if (!response.ok) {
212+
throw new Error(`Failed to fetch file: ${response.statusText}`);
213+
}
214+
const data = new Uint8Array(await response.arrayBuffer());
215+
await Deno.writeFile(fileName, data);
216+
return data;
217+
} else {
218+
throw e;
219+
}
220+
}
221+
}
182222
initDB() {
183223
const result = this.wasmLoader.callExportFunction("pgl_initdb");
184224
return result;

src/orm/db/postgres/in-pg/src/fileManager/in-pg-files.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { ERRNO_CODES } from "../constants.ts";
44
import { normalizePath } from "../convert.ts";
55
import type { PGMem } from "../pgMem.ts";
66
import { MemFile, PostgresFile } from "./pg-file.ts";
7-
7+
const dataURL =
8+
"https://github.com/inspatiallabs/inspatial-cloud/releases/download/0.2.2/inpg.data";
89
export class FileManager {
910
openFiles: Map<number, PGFile | PGFileMem>;
1011
openTmpFDs: Map<string, number>;
@@ -23,7 +24,6 @@ export class FileManager {
2324
postgresFiles: Map<string, PostgresFile>;
2425
constructor(inPg: InPG, options: {
2526
debug?: boolean;
26-
fileData: Uint8Array;
2727
}) {
2828
this.lastDebugMessage = "";
2929
this.dirReadOffsets = new Map();
@@ -44,7 +44,7 @@ export class FileManager {
4444
truncate: true,
4545
});
4646
}
47-
this.loadPostgresFiles(options.fileData);
47+
this.loadPostgresFiles();
4848
this.setupStdStreams();
4949
}
5050
clearTmp() {
@@ -412,7 +412,8 @@ export class FileManager {
412412
}
413413
return null;
414414
}
415-
loadPostgresFiles(data: Uint8Array) {
415+
async loadPostgresFiles() {
416+
const data = this.inPg.fileData;
416417
let offset = 0;
417418
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
418419

src/orm/db/postgres/in-pg/src/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { normalizePath } from "./convert.ts";
12
import type { PGMem } from "./pgMem.ts";
23

34
export class ExitStatus {
@@ -57,3 +58,16 @@ export class ExceptionInfo {
5758
return this.mem.HEAPU32[(this.ptr + 16) >> 2];
5859
}
5960
}
61+
62+
export function getTempDirBase() {
63+
let path = Deno.makeTempFileSync();
64+
if (Deno.build.os === "windows") {
65+
const driveLetter = path.match(/^[a-zA-Z]:/)?.[0] || "";
66+
path = `${driveLetter}${normalizePath(path)}`;
67+
}
68+
Deno.removeSync(path);
69+
const parts = path.split("/");
70+
parts.pop();
71+
const tmpdir = parts.join("/");
72+
return tmpdir;
73+
}

src/orm/db/postgres/in-pg/src/wasmLoader.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { uleb128Encode, UTF8ArrayToString } from "./convert.ts";
66

77
import type { PGMem } from "./pgMem.ts";
88
import { setupInvokeImports } from "./setupInvokes.ts";
9-
9+
import { getTempDirBase } from "./utils.ts";
10+
const wasmURL =
11+
"https://github.com/inspatiallabs/inspatial-cloud/releases/download/0.2.2/inpg.wasm";
1012
class LDSO {
1113
loadedLibsByName: Record<string, DSO>;
1214
loadedLibsByHandle: Record<string, DSO>;
@@ -37,12 +39,10 @@ export class WasmLoader {
3739
wasmExports: WebAssembly.Exports;
3840
freeTableIndexes: Array<number>;
3941
inPg: InPG;
40-
wasmData: Uint8Array;
41-
4242
get pgMem(): PGMem {
4343
return this.inPg.pgMem;
4444
}
45-
constructor(inPg: InPG, wasmData: Uint8Array) {
45+
constructor(inPg: InPG) {
4646
this.GOT = {};
4747
this.inPg = inPg;
4848
this.wasmExports = {};
@@ -54,7 +54,6 @@ export class WasmLoader {
5454
initial: this.inPg.tableSize,
5555
element: "anyfunc",
5656
});
57-
this.wasmData = wasmData;
5857

5958
const GOT = this.GOT;
6059
const currentModuleWeakSymbols = this.currentModuleWeakSymbols;
@@ -74,6 +73,7 @@ export class WasmLoader {
7473
},
7574
};
7675
}
76+
7777
async load() {
7878
const GOTHandler = this.GOTHandler;
7979
this.setupImports();
@@ -93,7 +93,7 @@ export class WasmLoader {
9393
) as WebAssembly.ModuleImports,
9494
};
9595

96-
const result = await WebAssembly.instantiate(this.wasmData, info);
96+
const result = await WebAssembly.instantiate(this.inPg.wasmData, info);
9797
this.wasmExports = result.instance.exports;
9898

9999
for (var [sym, exp] of Object.entries(result.instance.exports)) {

0 commit comments

Comments
 (0)