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