Skip to content
Snippets Groups Projects
Commit c636caab authored by David Sehnal's avatar David Sehnal
Browse files

ModelServer error handling

parent 923b91bf
No related branches found
No related tags found
No related merge requests found
......@@ -31,43 +31,59 @@ export async function resolveJob(job: Job, writer: Writer) {
const wrappedStructure = await getStructure(job);
perf.start('query');
// TODO: encode errors that happen past this point as CIF rather than just 404
const structure = job.queryDefinition.structureTransform
? await job.queryDefinition.structureTransform(job.normalizedParams, wrappedStructure.structure)
: wrappedStructure.structure;
const query = job.queryDefinition.query(job.normalizedParams, structure);
const result = StructureSelection.unionStructure(StructureQuery.run(query, structure, Config.maxQueryTimeInMs));
perf.end('query');
ConsoleLogger.logId(job.id, 'Query', 'Query finished.');
let startedWriting = false;
try {
const encoder = CifWriter.createEncoder({ binary: job.responseFormat.isBinary, encoderName: `ModelServer ${Version}` });
perf.start('query');
const structure = job.queryDefinition.structureTransform
? await job.queryDefinition.structureTransform(job.normalizedParams, wrappedStructure.structure)
: wrappedStructure.structure;
const query = job.queryDefinition.query(job.normalizedParams, structure);
const result = await StructureSelection.unionStructure(StructureQuery.run(query, structure, Config.maxQueryTimeInMs));
perf.end('query');
ConsoleLogger.logId(job.id, 'Query', 'Query finished.');
perf.start('encode');
encoder.startDataBlock(structure.units[0].model.label.toUpperCase());
encoder.writeCategory(_model_server_result, [job]);
encoder.writeCategory(_model_server_params, [job]);
// encoder.setFilter(mmCIF_Export_Filters.onlyPositions);
encode_mmCIF_categories(encoder, result);
// encoder.setFilter();
perf.end('encode');
ConsoleLogger.logId(job.id, 'Query', 'Encoded.');
const stats: Stats = {
structure: wrappedStructure,
queryTimeMs: perf.time('query'),
encodeTimeMs: perf.time('encode')
};
encoder.writeCategory(_model_server_stats, [stats]);
encoder.encode();
startedWriting = true;
encoder.writeTo(writer);
ConsoleLogger.logId(job.id, 'Query', 'Written.');
} catch (e) {
ConsoleLogger.errorId(job.id, e);
if (!startedWriting) {
doError(job, writer, e);
} else {
ConsoleLogger.errorId(job.id, 'Error was not relayed to the user because it happened during "write".');
}
}
}
function doError(job: Job, writer: Writer, e: any) {
const encoder = CifWriter.createEncoder({ binary: job.responseFormat.isBinary, encoderName: `ModelServer ${Version}` });
perf.start('encode');
encoder.startDataBlock(structure.units[0].model.label.toUpperCase());
encoder.writeCategory(_model_server_result, [job]);
encoder.writeCategory(_model_server_params, [job]);
// encoder.setFilter(mmCIF_Export_Filters.onlyPositions);
encode_mmCIF_categories(encoder, result);
// encoder.setFilter();
perf.end('encode');
ConsoleLogger.logId(job.id, 'Query', 'Encoded.');
const stats: Stats = {
structure: wrappedStructure,
queryTimeMs: perf.time('query'),
encodeTimeMs: perf.time('encode')
};
encoder.writeCategory(_model_server_stats, [stats]);
encoder.writeCategory(_model_server_error, ['' + e]);
encoder.encode();
encoder.writeTo(writer);
ConsoleLogger.logId(job.id, 'Query', 'Written.');
}
const maxTime = Config.maxQueryTimeInMs;
......@@ -88,7 +104,7 @@ function int32<T>(name: string, value: (data: T) => number): CifField<number, T>
return CifField.int(name, (i, d) => value(d));
}
const _model_server_result_fields: CifField<number, Job>[] = [
const _model_server_result_fields: CifField<any, Job>[] = [
string<Job>('job_id', ctx => '' + ctx.id),
string<Job>('datetime_utc', ctx => ctx.datetime_utc),
string<Job>('server_version', ctx => Version),
......@@ -102,6 +118,10 @@ const _model_server_params_fields: CifField<number, string[]>[] = [
string<string[]>('value', (ctx, i) => ctx[i][1])
];
const _model_server_error_fields: CifField<number, string>[] = [
string<string>('message', (ctx, i) => ctx)
];
const _model_server_stats_fields: CifField<number, Stats>[] = [
int32<Stats>('io_time_ms', ctx => ctx.structure.info.readTime | 0),
int32<Stats>('parse_time_ms', ctx => ctx.structure.info.parseTime | 0),
......@@ -110,12 +130,16 @@ const _model_server_stats_fields: CifField<number, Stats>[] = [
int32<Stats>('encode_time_ms', ctx => ctx.encodeTimeMs | 0)
];
const _model_server_result: CifWriter.Category<Job> = {
name: 'model_server_result',
instance: (job) => ({ data: job, fields: _model_server_result_fields, rowCount: 1 })
};
const _model_server_error: CifWriter.Category<string> = {
name: 'model_server_error',
instance: (message) => ({ data: message, fields: _model_server_error_fields, rowCount: 1 })
};
const _model_server_params: CifWriter.Category<Job> = {
name: 'model_server_params',
instance(job) {
......
......@@ -13,6 +13,7 @@ import * as util from 'util'
import * as fs from 'fs'
import * as zlib from 'zlib'
import { Job } from './jobs';
import { ConsoleLogger } from 'mol-util/console-logger';
require('util.promisify').shim();
......@@ -87,7 +88,14 @@ async function readStructure(key: string, sourceId: string, entryId: string) {
if (!fs.existsSync(filename)) throw new Error(`Could not map '${key}' to an existing file.`);
perf.start('read');
const data = await readFile(filename);
let data;
try {
data = await readFile(filename);
} catch (e) {
ConsoleLogger.error(key, '' + e);
throw new Error(`Could not read the file for '${key}' from disk.`);
}
perf.end('read');
perf.start('parse');
const frame = (await parseCif(data)).blocks[0];
......
......@@ -69,12 +69,12 @@ async function processNextJob() {
try {
writer.writeHeader(job.responseFormat.isBinary);
await resolveJob(job, writer);
writer.end();
} catch (e) {
ConsoleLogger.errorId(job.id, '' + e);
// TODO: add some error?
writer.doError(404);
} finally {
writer.end();
setImmediate(processNextJob);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment