Skip to content

Commit 5804bf7

Browse files
committed
Update hot swap logic
1 parent 0575002 commit 5804bf7

File tree

2 files changed

+78
-11
lines changed

2 files changed

+78
-11
lines changed

templates/cli/base/params.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
const func = localConfig.getFunction(functionId);
1818

19-
ignore.add('.appwrite');
19+
ignorer.add('.appwrite');
2020

2121
if (func.ignore) {
2222
ignorer.add(func.ignore);

templates/cli/lib/commands/run.js.twig

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
const ignore = require("ignore");
2+
const tar = require("tar");
3+
const fs = require("fs");
14
const childProcess = require('child_process');
25
const chokidar = require('chokidar');
36
const inquirer = require("inquirer");
@@ -7,11 +10,12 @@ const { localConfig, globalConfig } = require("../config");
710
const { paginate } = require('../paginate');
811
const { questionsRunFunctions } = require("../questions");
912
const { actionRunner, success, log, error, commandDescriptions, drawTable } = require("../parser");
10-
const { systemHasCommand, isPortTaken } = require('../utils');
13+
const { systemHasCommand, isPortTaken, getAllFiles } = require('../utils');
1114
const { info } = require('console');
1215

1316
const activeDockerIds = {};
1417

18+
const openRuntimesVersion = 'v3';
1519
const systemTools = {
1620
'node': {
1721
isCompiled: false,
@@ -35,10 +39,11 @@ async function dockerStop(id) {
3539
}
3640

3741
async function dockerPull(func) {
42+
return; // TODO: Remove
3843
log('Pulling Docker image of function runtime ...');
3944

4045
const [ runtimeName, runtimeVersion ] = func.runtime.split('-', 2);
41-
const imageName = `openruntimes/${runtimeName}:v3-${runtimeVersion}`;
46+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
4247

4348
const pullProcess = childProcess.spawn('docker', ['pull', imageName], {
4449
stdio: 'pipe',
@@ -56,7 +61,7 @@ async function dockerBuild(func) {
5661
log('Building function using Docker engine ...');
5762

5863
const [ runtimeName, runtimeVersion ] = func.runtime.split('-', 2);
59-
const imageName = `openruntimes/${runtimeName}:v3-${runtimeVersion}`;
64+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
6065

6166
const functionDir = path.join(process.cwd(), func.path);
6267

@@ -93,14 +98,14 @@ async function dockerStart(func, port) {
9398
success(`Visit http://localhost:${port}/ to execute your function.`);
9499

95100
const [ runtimeName, runtimeVersion ] = func.runtime.split('-', 2);
96-
const imageName = `openruntimes/${runtimeName}:v3-${runtimeVersion}`;
101+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
97102

98103
const tool = systemTools[runtimeName];
99104

100105
const functionDir = path.join(process.cwd(), func.path);
101106

102107
const id = `${new Date().getTime().toString(16)}${Math.round(Math.random() * 1000000000).toString(16)}`;
103-
const params = ['run', '--rm', '--name', id, '-i', '-e', 'OPEN_RUNTIMES_SECRET=', '-p', `${port}:3000`, '-v', `${functionDir}/:/mnt/code:rw`, imageName, 'sh', '-c', ` helpers/start.sh "${tool.startCommand}"`];
108+
const params = ['run', '--rm', '--name', id, '-i', '-e', 'OPEN_RUNTIMES_SECRET=', '-p', `${port}:3000`, '-v', `${functionDir}/.appwrite/logs:/mnt/logs:rw`, '-v', `${functionDir}/:/mnt/code:rw`, imageName, 'sh', '-c', ` helpers/start.sh "${tool.startCommand}"`];
104109

105110
const execProcess = childProcess.spawn('docker', params, {
106111
stdio: 'pipe',
@@ -211,19 +216,29 @@ const runFunction = async ({ port, engine, functionId } = {}) => {
211216

212217
let watcherRunning = false;
213218

219+
childProcess.execSync(`sudo mkdir -p ${path.join(process.cwd(), func.path, '.appwrite/logs')}`, {
220+
pwd: path.join(process.cwd(), func.path)
221+
});
222+
chokidar.watch('.appwrite/logs', {
223+
cwd: path.join(process.cwd(), func.path),
224+
ignoreInitial: true,
225+
}).on('all', async (event, filePath) => {
226+
console.log(fs.readFileSync(path.join(process.cwd(), func.path, filePath)).toString());
227+
});
228+
214229
chokidar.watch('.', {
215230
cwd: path.join(process.cwd(), func.path),
216231
ignoreInitial: true,
217-
ignored: [ ...(func.ignore ?? []), 'code.tar.gz', '.appwrite' ]
218-
}).on('all', async (event, path) => {
232+
ignored: [ ...(func.ignore ?? []), 'code.tar.gz', '.appwrite', '.appwrite/', '.appwrite/*', '.appwrite/**', '.appwrite/*.*', '.appwrite/**/*.*' ]
233+
}).on('all', async (event, filePath) => {
219234
if(watcherRunning) {
220235
info("File change detected but ignored, because live reload is already being ran.");
221236
return;
222237
}
223238

224239
watcherRunning = true;
225240

226-
log('Detected a change in ' + path);
241+
log('Detected a change in ' + filePath);
227242

228243
try {
229244
log('Stopping the function ...');
@@ -232,11 +247,63 @@ const runFunction = async ({ port, engine, functionId } = {}) => {
232247
await dockerStop(id);
233248
}
234249

235-
if(tool.isCompiled || tool.dependencyFiles.includes(path)) {
250+
if(tool.isCompiled || tool.dependencyFiles.includes(filePath)) {
236251
await dockerBuild(func);
237252
await dockerStart(func, port);
238253
} else {
239-
// TODO: Update code.tar.gz with latest changes
254+
// TODO: Some try-catch approach, to rebuild if fails
255+
log('Hot swapping function files ...');
256+
257+
const functionPath = path.join(process.cwd(), func.path);
258+
const hotSwapPath = path.join(functionPath, '.appwrite/hot-swap');
259+
const buildPath = path.join(functionPath, 'code.tar.gz')
260+
261+
// TODO: Using Node code, no sudo
262+
childProcess.execSync(`sudo mkdir -p ${hotSwapPath} && sudo chmod 777 ${buildPath} ${hotSwapPath} && sudo tar -zxf ${buildPath} -C ${hotSwapPath}`, {
263+
pwd: path.join(process.cwd(), func.path)
264+
});
265+
266+
const ignorer = ignore();
267+
ignorer.add('.appwrite');
268+
269+
if (func.ignore) {
270+
ignorer.add(func.ignore);
271+
}
272+
273+
// TODO: Better approach
274+
const filesToCopy = getAllFiles(functionPath).map((file) => path.relative(functionPath, file)).filter((file) => !ignorer.ignores(file));
275+
276+
const copyCommands = [];
277+
for(const f of filesToCopy) {
278+
const filePath = path.join(hotSwapPath, f);
279+
copyCommands.push(`sudo rm -rf ${filePath}`);
280+
281+
const fileDir = path.dirname(filePath);
282+
copyCommands.push(`sudo mkdir -p ${fileDir}`);
283+
284+
const sourcePath = path.join(functionPath, f);
285+
copyCommands.push(`sudo cp ${sourcePath} ${filePath}`);
286+
}
287+
childProcess.execSync(copyCommands.join(" && "), {
288+
pwd: path.join(process.cwd(), func.path)
289+
});
290+
291+
console.log(path.join(process.cwd(), func.path, '.appwrite'));
292+
/*
293+
childProcess.execSync("sudo chmod -R 777 .", {
294+
pwd: path.join(process.cwd(), func.path, '.appwrite')
295+
});
296+
*/
297+
298+
childProcess.execSync(`sudo tar -C ${hotSwapPath} --exclude code.tar.gz -zcf ${buildPath} .`, {
299+
pwd: hotSwapPath
300+
});
301+
302+
// TODO: Using Node code
303+
childProcess.execSync(`sudo rm -rf ${hotSwapPath}`, {
304+
pwd: path.join(process.cwd(), func.path)
305+
});
306+
240307
await dockerStart(func, port);
241308
}
242309
} catch(err) {

0 commit comments

Comments
 (0)