api-local.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import * as fs from 'fs';
  7. import * as path from 'path';
  8. import { JobManager, Job } from './jobs';
  9. import { ConsoleLogger } from 'mol-util/console-logger';
  10. import { resolveJob } from './query';
  11. import { StructureCache } from './structure-wrapper';
  12. import { now } from 'mol-util/now';
  13. import { PerformanceMonitor } from 'mol-util/performance-monitor';
  14. import { QueryName } from './api';
  15. export type LocalInput = {
  16. input: string,
  17. output: string,
  18. query: QueryName,
  19. modelNums?: number[],
  20. params?: any,
  21. binary?: boolean
  22. }[];
  23. export async function runLocal(input: LocalInput) {
  24. if (!input.length) {
  25. ConsoleLogger.error('Local', 'No input');
  26. return;
  27. }
  28. for (const job of input) {
  29. const binary = /\.bcif/.test(job.output);
  30. JobManager.add({
  31. entryId: job.input,
  32. queryName: job.query,
  33. queryParams: job.params || { },
  34. options: {
  35. modelNums: job.modelNums,
  36. outputFilename: job.output,
  37. binary
  38. }
  39. });
  40. }
  41. JobManager.sort();
  42. const started = now();
  43. let job: Job | undefined = JobManager.getNext();
  44. let key = job.key;
  45. let progress = 0;
  46. while (job) {
  47. try {
  48. const encoder = await resolveJob(job);
  49. const writer = wrapFileToWriter(job.outputFilename!);
  50. encoder.writeTo(writer);
  51. writer.end();
  52. ConsoleLogger.logId(job.id, 'Query', 'Written.');
  53. if (JobManager.hasNext()) {
  54. job = JobManager.getNext();
  55. if (key !== job.key) StructureCache.expire(key);
  56. key = job.key;
  57. } else {
  58. break;
  59. }
  60. } catch (e) {
  61. ConsoleLogger.errorId(job.id, e);
  62. }
  63. ConsoleLogger.log('Progress', `[${++progress}/${input.length}] after ${PerformanceMonitor.format(now() - started)}.`);
  64. }
  65. ConsoleLogger.log('Progress', `Done in ${PerformanceMonitor.format(now() - started)}.`);
  66. StructureCache.expireAll();
  67. }
  68. export function wrapFileToWriter(fn: string) {
  69. const w = {
  70. open(this: any) {
  71. if (this.opened) return;
  72. makeDir(path.dirname(fn));
  73. this.file = fs.openSync(fn, 'w');
  74. this.opened = true;
  75. },
  76. writeBinary(this: any, data: Uint8Array) {
  77. this.open();
  78. fs.writeSync(this.file, new Buffer(data.buffer));
  79. return true;
  80. },
  81. writeString(this: any, data: string) {
  82. this.open();
  83. fs.writeSync(this.file, data);
  84. return true;
  85. },
  86. end(this: any) {
  87. if (!this.opened || this.ended) return;
  88. fs.close(this.file, function () { });
  89. this.ended = true;
  90. },
  91. file: 0,
  92. ended: false,
  93. opened: false
  94. };
  95. return w;
  96. }
  97. function makeDir(path: string, root?: string): boolean {
  98. let dirs = path.split(/\/|\\/g),
  99. dir = dirs.shift();
  100. root = (root || '') + dir + '/';
  101. try { fs.mkdirSync(root); }
  102. catch (e) {
  103. if (!fs.statSync(root).isDirectory()) throw new Error(e);
  104. }
  105. return !dirs.length || makeDir(dirs.join('/'), root);
  106. }