Skip to content

Commit

Permalink
Improved UX for xrefs/xrefsBatch
Browse files Browse the repository at this point in the history
  • Loading branch information
ariutta committed Feb 22, 2018
1 parent 19ecbe9 commit 1b46b68
Show file tree
Hide file tree
Showing 12 changed files with 510 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
demo/
dist/
docs/
lib/
es5/
esnext/
main.js
main.d.ts
Expand Down
187 changes: 180 additions & 7 deletions bin/bridgedb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,109 @@ var _ = require("lodash");
var crypto = require("crypto");
var csv = require("csv-streamify");
var fs = require("fs");
var BridgeDb = require("../lib/BridgeDb").BridgeDb;
var path = require("path");
var BridgeDb = require("../es5/BridgeDb").BridgeDb;
var hl = require("highland");
var ndjson = require("ndjson");
var npmPackage = require("../package.json");
var program = require("commander");
var Rx = require("rx-extra");
require("../lib/topublish/pipeToStdout");
require("../es5/spinoffs/pipeToStdout");
var VError = require("verror");
var ipc = require('node-ipc');

// time to wait for no new calls to xrefs() before we
// batch up all calls in the queue and send to xrefsBatch()
var XREF_REQUEST_DEBOUNCE_TIME = 100; // ms
var IPC_SERVER_PROCESS_NAME = 'bridgeDbProcess';
ipc.config.retry = 1500;
ipc.config.silent = true;
var IPC_SERVER_ON_FILE = path.join(__dirname, '.ipc-listening');

function makeXrefsRequest(organism, dbConventionalName, dbId) {
var primaryBridgeDbProcess = !fs.existsSync(IPC_SERVER_ON_FILE);
var xrefsResponseQueue = new Rx.Subject();

if (primaryBridgeDbProcess) {
fs.writeFileSync(IPC_SERVER_ON_FILE, '');
ipc.config.id = IPC_SERVER_PROCESS_NAME;
ipc.serve(function() {
var bridgeDb = new BridgeDb();
bridgeDb
.xrefs(organism, dbConventionalName, dbId)
.subscribe(xrefsResponseQueue);

var endSignal = new Rx.Subject();
var debounceSignal = Rx.Observable.fromEvent(ipc.server, 'xrefsRequest')
.debounceTime(
XREF_REQUEST_DEBOUNCE_TIME
)
.first();

ipc.server.on('xrefsRequest', function(xrefsRequest, socket) {
bridgeDb
.xrefs(xrefsRequest.organism, xrefsRequest.dbConventionalName, xrefsRequest.dbId)
.subscribe(function(response) {
ipc.server.emit(socket, 'xrefsResponse', response);
endSignal.next();
}, function(err) {
ipc.server.emit(socket, 'err', err);
endSignal.error(err);
}, function() {
ipc.server.emit(socket, 'end');
endSignal.complete();
});
});

endSignal
.skipUntil(debounceSignal)
//debounceSignal
.first()
.subscribe(function(data) {
}, function(err) {
throw err;
}, function() {
ipc.server.stop();
fs.unlinkSync(IPC_SERVER_ON_FILE);
console.warn('bridgeDb CLI server stopped...');
//process.exit(0);
});

debounceSignal.subscribe();
/*
ipc.server.on('destroy', function() {
});
//*/
});
ipc.server.start();
} else {
ipc.config.id = IPC_SERVER_PROCESS_NAME + new Date().toISOString();
ipc.connectTo(IPC_SERVER_PROCESS_NAME, function() {
ipc.of[IPC_SERVER_PROCESS_NAME].on(
'connect',
function(){
ipc.of[IPC_SERVER_PROCESS_NAME].emit('xrefsRequest', {
organism: organism,
dbConventionalName: dbConventionalName,
dbId: dbId
});

ipc.of[IPC_SERVER_PROCESS_NAME].on('xrefsResponse', function(xrefsResponse, socket) {
xrefsResponseQueue.next(xrefsResponse);
});
ipc.of[IPC_SERVER_PROCESS_NAME].on('err', function(err, socket) {
xrefsResponseQueue.err(err);
});
ipc.of[IPC_SERVER_PROCESS_NAME].on('end', function() {
xrefsResponseQueue.complete();
ipc.disconnect(IPC_SERVER_PROCESS_NAME);
});
});
});
}

return xrefsResponseQueue;
}

program
.version(npmPackage.version)
Expand Down Expand Up @@ -113,17 +208,58 @@ program
});

// npm run compile:es5 && ./bin/bridgedb xrefs 'Homo sapiens' 'Entrez Gene' '1234'
//
// cat test/dbNamesAndIds.csv | while read ln; do xrefDb=`echo $ln | sed s/,.*//g`; xrefId=`echo $ln | sed 's/^.*,//g'`; echo "$xrefDb" "$xrefId"; ./bin/bridgedb xrefs "Homo sapiens" "$xrefDb" "$xrefId"; done

// cat test/dbNamesAndIds.csv | while read ln; do xrefDb=`echo $ln | sed s/,.*//g`; xrefId=`echo $ln | sed 's/^.*,//g'`; echo "$xrefDb" "$xrefId"; ./bin/bridgedb xrefs "Homo sapiens" "$xrefDb" "$xrefId" | jq ". | .dbId | {\"$xrefId\": .}" | tee $xrefId.tsv & done
program
.command("xrefs <organism> <dbConventionalName> <dbId>")
.action(function(organism, dbConventionalName, dbId) {
var bridgeDb = new BridgeDb();

var serialize = ndjson.serialize();
bridgeDb
.xrefs(organism, dbConventionalName, dbId)
makeXrefsRequest(organism, dbConventionalName, dbId)
.throughNodeStream(serialize)
/*
.map(function(x) {
return JSON.stringify(x);
})
//*/
//.do(console.warn)
.pipeToStdout();
});
// npm run compile:es5 && ./bin/bridgedb dataSource 'Entrez Gene'
// npm run compile:es5 && ./bin/bridgedb dataSource 'Entrez Gene'
/*
cat ../gpml2pvjson-js/test/expected/WP481_94171.json | jq '.entitiesById[] | select(has("dbConventionalName") and .kaavioType=="SingleFreeNode") | .dbConventionalName+"\t"+.dbId'
*/
program
.command("datasource <input> [as]")
.option(
"--format [string]",
'Column format to return when identifying a data source name format: term or iri. Default: "term"'
)
.action(function(input, as, options) {
var format = !!options['format'] ? options['format'] : 'term';
var serialize = ndjson.serialize();
var bridgeDb = new BridgeDb();
if (!!as) {
bridgeDb
.convertDataSourceNameTo(as, input)
.throughNodeStream(serialize)
.pipeToStdout();
} else {
if (format === 'term') {
bridgeDb
.dataSourceNameToColumnTerm(input)
.throughNodeStream(serialize)
.pipeToStdout();
} else {
bridgeDb
.dataSourceNameToColumnIri(input)
.throughNodeStream(serialize)
.pipeToStdout();
}
}
});

/*
Compile, if needed:
Expand Down Expand Up @@ -246,8 +382,45 @@ program
});
});
})
.throughNodeStream(serialize)
.map(function(result) {
return '\t' + result.id + '\n\t\t' + result.xrefs.map(function(xref) {
return [xref.dataSource, xref.dbId].join('\t');
}).join('\n\t\t') + '\n'
})
//.throughNodeStream(serialize)
.pipeToStdout();

// .mergeMap(function(dataSource) {
// if (!dataSource || !dataSource.id) {
// return Rx.Observable.throw(
// new Error(`Cannot process "${dbConventionalName}:${dbId}"`)
// );
// }
// var id = dataSource.id + dbId;
// return bridgeDb
// .xrefs(organism, dbConventionalName, dbId)
// /*
// .map(function(xref) {
// return [xref.dataSource, xref.dbId].join('\t');
// })
// .toArray()
// .map(function(xrefStrings) {
// return xrefStrings.join('\n');
// });
// //*/
// //*
// .toArray()
// .map(function(xrefs) {
// return {
// id: id,
// //dbConventionalName: dbConventionalName,
// //dbId: dbId,
// //organism: organism,
// xrefs: xrefs
// };
// });
// //*/
// });
});

program.parse(process.argv);
35 changes: 34 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 15 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
"name": "bridgedb",
"version": "6.0.0-18",
"description": "JS client for BridgeDb.org ID mapping framework webservices",
"main": "lib/index.js",
"main:esnext": "esnext/index.js",
"typings": "lib/index.d.ts",
"main": "es5/index.js",
"module": "esnext/index.js",
"jsnext:main": "esnext/index.js",
"typings": "es5/index.d.ts",
"bin": "./bin/bridgedb",
"files": [
"lib/",
"es5/",
"src/",
"dist/",
"esnext/",
Expand All @@ -22,12 +23,12 @@
"typings/organism.d.ts"
],
"scripts": {
"assets": "mkdir -p lib/components && mkdir -p esnext/components && cp ./node_modules/react-select/dist/react-select.css ./lib/components/react-select.css && cp ./node_modules/react-select/dist/react-select.css ./src/components/react-select.css && cp ./node_modules/react-select/dist/react-select.css ./esnext/components/react-select.css && echo ok || echo not ok",
"assets": "mkdir -p es5/components && mkdir -p esnext/components && cp ./node_modules/react-select/dist/react-select.css ./es5/components/react-select.css && cp ./node_modules/react-select/dist/react-select.css ./src/components/react-select.css && cp ./node_modules/react-select/dist/react-select.css ./esnext/components/react-select.css && echo ok || echo not ok",
"prepare": "npm run build && npm run test",
"build": "npm run compile && mkdir -p dist && rm -rf dist/* && browserify ./lib/index.js -o ./dist/index.js -d -t cssify -t deglobalify",
"build": "npm run compile && mkdir -p dist && rm -rf dist/* && browserify ./es5/index.js -o ./dist/index.js -d -t cssify -t deglobalify",
"build-demo": "npm run compile:es5:ui && npm run compile:es5:ui:test && browserify ./test/e2e/ui-components-local.test.js -o ./demo/ui-combo.bundle.js -d -t deglobalify",
"compile": "npm-run-all -p compile:*",
"compile:es5": "mkdir -p lib && rm -rf lib/* && npm run assets && tsc --project tsconfig.json && echo ok || echo not ok",
"compile:es5": "mkdir -p es5 && rm -rf es5/* && npm run assets && tsc --project tsconfig.json && echo ok || echo not ok",
"compile:esnext": "mkdir -p esnext && rm -rf esnext/* && npm run assets && tsc --project tsconfig.esnext.json && echo ok || echo not ok",
"compile-demo:es5:ui": "tsc src/components/react-demo.tsx --jsx react --sourceMap --lib dom,es5,scripthost --module commonjs --outDir components/ && echo ok || echo not ok",
"compile-demo:es5:ui:test": "tsc --project tsconfig.demo.json && echo ok || echo not ok",
Expand All @@ -36,7 +37,9 @@
"start:mockserver": "./node_modules/mockserver/bin/mockserver.js -p 4522 -m './test/input-data'",
"start:ui": "webpack-dev-server --config webpack.config.js --progress --colors --watch",
"test": "npm-run-all test:*",
"test:cli": "echo '1234\n1235\n' | ./bin/bridgedb xrefsBatch --organism 'Homo sapiens' --dbConventionalName 'Entrez Gene'",
"test:cli": "npm-run-all test:cli:*",
"test:cli:xrefsBatchSingleDatasource": "echo '1234\n1235\n' | ./bin/bridgedb xrefsBatch --organism 'Homo sapiens' --dbConventionalName 'Entrez Gene'",
"test:cli:xrefsBatchMultipleDatasources": "echo '1234\n1235\n' | ./bin/bridgedb xrefsBatch --organism 'Homo sapiens' --dbConventionalName 'Entrez Gene'",
"test:ui": "echo 'TODO: Add tests for UI!'",
"watch": "npm-run-all -p start:mockserver watch:*",
"watch:client": "npm-watch",
Expand Down Expand Up @@ -89,6 +92,7 @@
"levenshtein": "^1.0.5",
"lodash": "^4.11.1",
"ndjson": "^1.5.0",
"node-ipc": "^9.1.1",
"react": "^15.4.2",
"react-addons-css-transition-group": "^15.4.1",
"react-addons-shallow-compare": "^15.4.1",
Expand All @@ -100,8 +104,8 @@
"redux-form": "^6.1.1",
"redux-localstorage": "^0.4.1",
"rx-extra": "^2.1.0-beta",
"source-map-support": "^0.5.0",
"rxjs": "^5.4.2",
"source-map-support": "^0.5.0",
"typestyle": "^0.22.3",
"urijs": "^1.18.1",
"verror": "^1.9.0",
Expand Down Expand Up @@ -161,9 +165,9 @@
"./docs",
"./test",
"./bower_components",
"./lib",
"./es5",
"./esnext",
"./demo",
"./gulp",
"./dist"
]
}
Expand Down
Loading

0 comments on commit 1b46b68

Please sign in to comment.