diff --git a/conf/config.default.xml b/conf/config.default.xml index e7a4fcbc7b..991d845c8c 100644 --- a/conf/config.default.xml +++ b/conf/config.default.xml @@ -40,6 +40,7 @@ 0 my_secret 0 + 3000 rq diff --git a/conf/config.rng b/conf/config.rng index 5ef4f61556..d9be38fcbd 100644 --- a/conf/config.rng +++ b/conf/config.rng @@ -415,6 +415,16 @@ + + + + For preflight queries, this speicifies how long KonText client-side waits + for the query. In case it is not finished in the limit, the client will + consider the query a "long one" and warn user accordingly. + + + + diff --git a/lib/action/model/base.py b/lib/action/model/base.py index 0518a55491..31440a7fed 100644 --- a/lib/action/model/base.py +++ b/lib/action/model/base.py @@ -126,6 +126,7 @@ async def add_globals(self, app: Sanic, action_props: ActionProps, result: Dict[ result['issue_reporting_action'] = None result['help_links'] = {} result['_version'] = None + result['preflight_query_timeout_ms'] = settings.get_int('global', 'preflight_query_timeout_ms', 0) return result def init_menu(self, result): diff --git a/lib/action/model/corpus.py b/lib/action/model/corpus.py index 72e444d605..fd3ba9fff3 100644 --- a/lib/action/model/corpus.py +++ b/lib/action/model/corpus.py @@ -19,7 +19,6 @@ import logging -import urllib.parse from dataclasses import asdict from functools import partial from typing import ( diff --git a/public/files/js/app/navigation/index.ts b/public/files/js/app/navigation/index.ts index 19cbb9bf07..4c6d6c9c1c 100644 --- a/public/files/js/app/navigation/index.ts +++ b/public/files/js/app/navigation/index.ts @@ -68,12 +68,13 @@ export function parseUrlArgs(args:string):Array<[string, string]> { * */ interface AjaxRequestProps { - accept:string, - contentType:string, - responseType:XMLHttpRequestResponseType, - method:string, - requestBody:string, - url:string + accept:string; + contentType:string; + responseType:XMLHttpRequestResponseType; + method:string; + requestBody:string; + url:string; + timeout:number; } /** @@ -253,7 +254,8 @@ export class AppNavigation implements Kontext.IURLHandler, Kontext.IAjaxHandler responseType: options.responseType, method, requestBody: body, - url + url, + timeout: options.timeout ? options.timeout : 0 } } @@ -282,7 +284,9 @@ export class AppNavigation implements Kontext.IURLHandler, Kontext.IAjaxHandler responseType: callArgs.responseType, headers: { 'Content-Type': callArgs.contentType - } + }, + timeout: callArgs.timeout + }).pipe( map, T>(v => v.response) ); diff --git a/public/files/js/models/query/first.ts b/public/files/js/models/query/first.ts index 0426c3422e..a66ae457aa 100644 --- a/public/files/js/models/query/first.ts +++ b/public/files/js/models/query/first.ts @@ -22,7 +22,8 @@ import { IFullActionControl } from 'kombo'; import { Observable, of as rxOf } from 'rxjs'; -import { tap, map, concatMap, reduce } from 'rxjs/operators'; +import { AjaxTimeoutError } from 'rxjs/ajax'; +import { tap, map, concatMap, reduce, catchError } from 'rxjs/operators'; import { Dict, tuple, List, pipe, HTTP, Rx } from 'cnc-tskit'; import * as Kontext from '../../types/kontext'; @@ -1119,9 +1120,20 @@ export class FirstQueryFormModel extends QueryFormModel { + if (err instanceof AjaxTimeoutError) { + return rxOf({ + sizeIpm: preflightSubc.threshold_ipm + 1 + }); + } + throw err; + } + ), map( ans => ({ contextData, diff --git a/public/files/js/types/kontext.ts b/public/files/js/types/kontext.ts index 50cfdd6598..2a9db8dfa9 100644 --- a/public/files/js/types/kontext.ts +++ b/public/files/js/types/kontext.ts @@ -356,6 +356,7 @@ export interface AjaxOptions { contentType?:string; responseType?:XMLHttpRequestResponseType; accept?:string; + timeout?:number; } export type AsyncTaskStatus = 'PENDING'|'STARTED'|'SUCCESS'|'FAILURE'; diff --git a/templates/document.html b/templates/document.html index f564e68180..5fd1be8de9 100644 --- a/templates/document.html +++ b/templates/document.html @@ -49,5 +49,6 @@ __conf.TextDirectionRTL = {{ righttoleft|default(false, true)|to_json }}; __conf.InitialFreqLevel = {{ last_freq_level|default(1, true)|to_json }}; __conf.maxDispersionResolution = {{ max_dispersion_resulution|default(0, true)|to_json }}; +__conf.PreflightTimeoutMs = {{ preflight_query_timeout_ms|to_json }}; __conf.manateeIsCustomCNC = {{ manatee_is_custom_cnc|to_json }}; {% endblock %} \ No newline at end of file