Skip to content

Commit 35ce9de

Browse files
committed
Merge branch 'master' into production
2 parents 803b64a + 5732126 commit 35ce9de

File tree

16 files changed

+17330
-334
lines changed

16 files changed

+17330
-334
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
# Leave this set to 0 on the GitHub repo so the unit and
88
# integration tests do not need to have wheels (until we
99
# find a convenient way to use wheels on GitHub)
10-
TAG=0.20
10+
TAG=0.21
1111
USE_WHEELS=1
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Add issue to project
2+
on:
3+
issues:
4+
types: [opened]
5+
pull_request:
6+
types: [opened]
7+
jobs:
8+
add-to-project:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Add issue to project
12+
uses: actions/add-to-project@v0.5.0
13+
with:
14+
github_token: ${{ secrets.PENNAI_TOKEN }}
15+
project_url: https://github.com/orgs/EpistasisLab/projects/9

docker_logs.txt

Lines changed: 16710 additions & 0 deletions
Large diffs are not rendered by default.

lab/db.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ db.bind("batches");
5454
db.bind("users");
5555
db.bind("datasets");
5656
db.bind("settings");
57+
db.bind("chats");
58+
db.bind("chatlogs");
59+
db.bind("executions");
5760

5861
// Promisify all methods
5962
Object.keys(mongoskin).forEach((key) => {

lab/lab.js

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const assert = require("assert");
5454
const openaiRouter = require('./routes/openai');
5555
const chatapiRouter = require('./routes/chatapi');
5656
const execapiRouter = require('./routes/execapi');
57+
const { deleteFilesFromGridstore } = require('./labutils');
5758

5859
/***************
5960
* Enums
@@ -601,6 +602,7 @@ app.get("/api/v1/:collection/:id", (req, res, next) => {
601602

602603
// Update existing entry
603604
app.put("/api/v1/:collection/:id", jsonParser, (req, res, next) => {
605+
604606
delete req.body._id; // Delete ID (will not update otherwise)
605607
req.collection.updateByIdAsync(req.params.id, {
606608
$set: req.body
@@ -626,6 +628,99 @@ app.put("/api/v1/:collection/:id", jsonParser, (req, res, next) => {
626628
});
627629
});
628630

631+
app.delete('/api/v1/datasets/:id', async (req, res, next) => {
632+
const result = {};
633+
let files = [];
634+
let query = '';
635+
try {
636+
const dataset_id = db.toObjectID(req.params.id);
637+
let dataset = await db.datasets.findByIdAsync(dataset_id);
638+
639+
if (dataset == null) {
640+
return res.status(404).send({ message: 'dataset ' + req.params.id + ' not found'});
641+
}
642+
643+
// if (dataset.ai && (dataset.ai.status == recommenderStatus.RUNNING || dataset.ai.status == recommenderStatus.INITIALIZING)) {
644+
if (dataset.ai && ['on', 'requested'].some(status => dataset.ai.status === status)) {
645+
console.log('cannot delete dataset, AI is enabled');
646+
return res.status(409).send({message: 'cannot delete dataset, AI is enabled'});
647+
}
648+
649+
const dataset_file_id = db.toObjectID(dataset.files[0]._id);
650+
files.push(...dataset.files);
651+
652+
// experiments
653+
query = { $or: [
654+
{"_dataset_id": {"$eq": dataset_id}},
655+
{"_dataset_file_id": {"$eq": dataset_file_id}},
656+
]}
657+
658+
let experiments = await db.experiments.find(query).toArrayAsync();
659+
console.log(experiments);
660+
let runningExp = experiments.find(exp => ['running', 'pending', 'suggested'].some(status => exp._status === status));
661+
662+
if (runningExp) {
663+
console.log('cannot delete dataset, experiments running');
664+
return res.status(409).send({message: 'cannot delete dataset, experiments running'});
665+
}
666+
667+
let experimentIds = []; // maybe I don't need this one.
668+
experiments.forEach(exp => {
669+
experimentIds.push(exp._id);
670+
files.push(...exp.files);
671+
})
672+
673+
// chats
674+
query = { $or: [
675+
{"_dataset_id": {"$eq": dataset_id}},
676+
{"_experiment_id": {"$in": experimentIds}}
677+
]}
678+
let chats = await db.chats.find(query).toArrayAsync();
679+
let chatIds = [];
680+
let chatlogIds = [];
681+
chats.forEach(chat => {
682+
chatIds.push(chat._id);
683+
chatlogIds.push(...chat.chatlogs);
684+
})
685+
686+
// executions
687+
query = { $or: [
688+
{"_dataset_id": {"$eq": dataset_id}},
689+
{"_dataset_file_id": {"$eq": dataset_file_id}},
690+
{"_experiment_id": {"$in": experimentIds}}
691+
]}
692+
let executions = await db.executions.find(query).toArrayAsync();
693+
executions.forEach(exec => {
694+
files.push(...exec.files);
695+
})
696+
697+
// *** DELETE ***
698+
result.datasetCount = await db.datasets.removeByIdAsync(dataset_id);
699+
if (experiments.length > 0) {
700+
result.experimentCount = await db.experiments.removeAsync({'_id': { '$in': experimentIds }});
701+
console.log('experiment count');
702+
}
703+
if (chatIds.length > 0) {
704+
result.chatlogCount = (await db.chatlogs.removeAsync({'_id': { '$in': chatlogIds }}));
705+
console.log('chatlogs deleted');
706+
result.chatCount = (await db.chats.removeAsync({'_id': { '$in': chatIds }}));
707+
console.log('chats deleted');
708+
}
709+
result.fileCount = await deleteFilesFromGridstore(files);
710+
711+
// temp values
712+
// result.datasets = dataset;
713+
// result.experiments = experiments;
714+
// result.chats = chats;
715+
// result.executions = executions;
716+
// result.files = files;
717+
718+
res.send(result);
719+
} catch (err) {
720+
next(err);
721+
}
722+
});
723+
629724
// Delete existing entry
630725
app.delete("/api/v1/:collection/:id", (req, res, next) => {
631726
req.collection.removeByIdAsync(req.params.id)
@@ -643,7 +738,6 @@ app.delete("/api/v1/:collection/:id", (req, res, next) => {
643738
});
644739

645740

646-
647741
// Experiment page
648742
app.get("/api/v1/experiments/:id", (req, res, next) => {
649743
db.experiments.findByIdAsync(req.params.id)

lab/labutils.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const db = require("./db").db;
2+
3+
async function deleteFilesFromGridstore(files) {
4+
try {
5+
let filesP = [];
6+
let filesDeleted = 0;
7+
8+
for (let i = 0; i < files.length; i++) {
9+
let gfs = new db.GridStore(db, files[i]._id, 'w', {
10+
promiseLibrary: Promise
11+
});
12+
filesP.push(gfs.unlinkAsync().then(() => {
13+
filesDeleted++;
14+
}));
15+
}
16+
17+
await Promise.all(filesP);
18+
return filesDeleted;
19+
} catch (err) {
20+
console.log(err);
21+
throw err;
22+
}
23+
}
24+
25+
module.exports = {
26+
deleteFilesFromGridstore
27+
}

lab/routes/execapi.js

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -120,103 +120,6 @@ router.post('/executions', async (req, res, next) => {
120120
});
121121

122122

123-
router.post('/executions_old', async (req, res, next) => {
124-
if (req.body.src_code == null) {
125-
return res.status(400).json({ message: 'No src_code provided' });
126-
}
127-
128-
// This should not be needed in the code run. The client should take the
129-
// execution_id returned by this enpoint and write it to the next chatlog.
130-
// // this will be the chatlog_id of the chatlog that is requesting this run.
131-
// // the next chatlog will be the one with the results of this run. The client
132-
// // will need to save the execution_id returned by this endpoint in the next
133-
// // chatlog.
134-
// if (req.body.chatlog_id != null) {
135-
// return res.status(400).json({ message: 'no chatlog_id provided' });
136-
// }
137-
138-
// create a new execution
139-
let execution = new Execution({
140-
src_code: req.body.src_code,
141-
status: 'submitted',
142-
result: null,
143-
files: []
144-
});
145-
146-
if (req.body.dataset_file_id != null) {
147-
execution._dataset_file_id = req.body.dataset_file_id;
148-
} else if (req.body.dataset_id != null) {
149-
execution._dataset_id = req.body.dataset_id;
150-
let dataset = await getDatasetById(req.body.dataset_id);
151-
if (dataset != null) {
152-
execution._dataset_file_id = dataset.files[0]._id;
153-
}
154-
}
155-
156-
if (req.body.experiment_id != null) {
157-
execution._experiment_id = req.body.experiment_id;
158-
}
159-
160-
try {
161-
const newExecution = await execution.save();
162-
execution._id = newExecution._id;
163-
} catch (err) {
164-
return res.status(500).json({ message: err.message });
165-
}
166-
167-
// make folder if not available yet:
168-
// let tmppath = path.join(process.env.CODE_RUN_PATH, request.execution_id.toString());
169-
let tmppath = path.join(process.env.CODE_RUN_PATH, execution._id.toString());
170-
// make tmp folder if it is not available
171-
if (!fs.existsSync(tmppath)) fs.mkdirSync(tmppath, { recursive: true });
172-
173-
// find machines that could handle the project
174-
// this may need revision, submitting experiments checks the machine capacity
175-
// but the capacity is tied to each algorithm. Not sure how to handle this yet.
176-
let machines;
177-
try {
178-
machines = await Machine.find({}, { address: 1 });
179-
if (machines.length == 0) {
180-
return res.status(400).json({ message: 'No machines available' });
181-
}
182-
// call the machine api
183-
let result = await fetch(machines[0].address + '/code/run', {
184-
method: 'POST',
185-
headers: {
186-
'Content-Type': 'application/json'
187-
},
188-
body: JSON.stringify(execution)
189-
});
190-
result = await result.json();
191-
192-
// update the execution status
193-
execution.status = result.exec_results.status;
194-
execution.result = result.exec_results.result;
195-
196-
// add any generated files in tmppath to the execution.files array
197-
const files = await uploadExecFiles(execution._id, tmppath);
198-
execution.files = files;
199-
200-
const updatedExecution = await execution.save();
201-
202-
// delete the tmp folder
203-
fs.rmdir(tmppath, { recursive: true }, (err) => {
204-
if (err) {
205-
console.error(err);
206-
} else {
207-
console.log(tmppath + ' folder deleted');
208-
}
209-
});
210-
211-
res.send(execution);
212-
}
213-
catch (err) {
214-
console.error(err);
215-
return res.status(500).json({ message: err.message });
216-
}
217-
});
218-
219-
220123
router.post('/executions/install', async (req, res, next) => {
221124

222125
if (req.body.command != 'install' && req.body.command != 'freeze') {

lab/webapp/package-lock.json

Lines changed: 7 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)