Skip to content

Commit

Permalink
fix(upload-contract): prevent race condition when restarting ag-solo
Browse files Browse the repository at this point in the history
Also, only upload contracts if we haven't already initialized.
  • Loading branch information
michaelfig committed Oct 16, 2019
1 parent dab8b3a commit d478c09
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/ag-solo/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export default async function start(basedir, withSES, argv) {

if (pairs.length > 0) {
// eslint-disable-next-line no-await-in-loop
await uploadContract(basedir, pairs);
await uploadContract(basedir, ['--once', ...pairs]);
}
}
}
34 changes: 22 additions & 12 deletions lib/ag-solo/upload-contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const sendJSON = (ws, obj) => {
};

export default async function upload(basedir, args) {
const { _: namePaths, 'ag-solo': agSolo } = parseArgs(args, {
const { _: namePaths, once, 'ag-solo': agSolo } = parseArgs(args, {
boolean: ['once'],
default: {
target: 'contractHost',
},
Expand All @@ -37,8 +38,6 @@ export default async function upload(basedir, args) {
return 1;
}

console.log(`Uploading contracts...`);

let wsurl = agSolo;
if (!agSolo) {
const cjson = await fs.promises.readFile(
Expand Down Expand Up @@ -77,9 +76,20 @@ export default async function upload(basedir, args) {
console.log('Chain loaded:', await bootC.G.LOADING.P);
// Take a new copy, since the contract targets should exist.
bootC = E.C(bootstrap());
if (once) {
if (await bootC.G.READY.M.isReady().P) {
console.log('Contracts already uploaded');
ws.close();
exit.res(0);
return;
}
}
const uploadsC = bootC.G.uploads;

console.log(`Uploading contracts...`);

const contractAP = [];
const names = [];
const contractsAP = [];
for (const namePath of namePaths) {
const match = namePath.match(/^(([^\W-]+)-[^=]+)=(.+)$/);
if (!match) {
Expand All @@ -98,21 +108,21 @@ export default async function upload(basedir, args) {
);
} else {
// Install the contract, then save it in home.uploads.
contractAP.push(E(targetObj).install(source, moduleFormat));
console.log(`Uploading ${name}`)
contractsAP.push(E(targetObj).install(source, moduleFormat));
names.push(name);
}
}

const contracts = await Promise.all(contractAP);

const uploadsC = bootC.G.uploads;
const uploadAP = [];
for (let i = 0; i < contractAP.length; i += 1) {
uploadAP.push(uploadsC.M.set(names[i], contracts[i]).P);
const contracts = await Promise.all(contractsAP);
for (let i = 0; i < contracts.length; i ++) {
await uploadsC.M.set(names[i], contracts[i]).P;
}

await Promise.all(uploadAP);
console.log('Success! See home.uploads~.list()');
if (once) {
await bootC.G.READY.M.resolve('contracts uploaded').P;
}
ws.close();
exit.res(0);
} catch (e) {
Expand Down
23 changes: 21 additions & 2 deletions lib/ag-solo/vats/vat-http.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,21 @@ function build(E, D) {
});
harden(loaded);
const homeObjects = { LOADING: loaded.p };
let exportedToCapTP = { LOADING: loaded.p };
let isReady = false;
let exportedToCapTP = {
LOADING: loaded.p,
READY: {
resolve(value) { isReady = true; readyForClient.res(value); },
isReady() { return isReady; },
},
};

const readyForClient = {};
readyForClient.p = new Promise((resolve, reject) => {
readyForClient.res = resolve;
readyForClient.rej = reject;
});
harden(readyForClient);

let handler = {};
let canvasState;
Expand Down Expand Up @@ -51,6 +65,11 @@ function build(E, D) {
getReplHandler(E, homeObjects, msg =>
D(commandDevice).sendBroadcast(msg),
),
{
readyForClient() {
return readyForClient.p;
},
},
{
CTP_OPEN(obj) {
console.log(`Starting CapTP`, obj.connectionID);
Expand Down Expand Up @@ -96,7 +115,7 @@ function build(E, D) {
},

setPresences(ps, privateObjects) {
exportedToCapTP = { ...ps, ...privateObjects };
exportedToCapTP = { READY: exportedToCapTP.READY, ...ps, ...privateObjects };
Object.assign(homeObjects, ps, privateObjects);
loaded.res('chain bundle loaded');
if (ps.canvasStatePublisher) {
Expand Down

0 comments on commit d478c09

Please sign in to comment.