feat: add an API to time out query executions

Currently, if a predicate is hard to match on the Rust side, a sizable
query against a very large file can take forever, and ends up hanging.
This commit adds an API function `ts_query_cursor_set_timeout_micros` to
limit how long query execution is allowed to take, thereby negating the
chance of a hang to occur.
This commit is contained in:
Amaan Qureshi 2024-08-29 17:21:52 -04:00
parent a748488596
commit 3f424c0121
11 changed files with 132 additions and 8 deletions

View file

@ -5146,3 +5146,28 @@ fn test_query_on_empty_source_code() {
&[(0, vec![("program", "")])],
);
}
#[test]
fn test_query_execution_with_timeout() {
let language = get_language("javascript");
let mut parser = Parser::new();
parser.set_language(&language).unwrap();
let source_code = "function foo() { while (true) { } }\n".repeat(1000);
let tree = parser.parse(&source_code, None).unwrap();
let query = Query::new(&language, "(function_declaration) @function").unwrap();
let mut cursor = QueryCursor::new();
cursor.set_timeout_micros(1000);
let matches = cursor
.matches(&query, tree.root_node(), source_code.as_bytes())
.count();
assert!(matches < 1000);
cursor.set_timeout_micros(0);
let matches = cursor
.matches(&query, tree.root_node(), source_code.as_bytes())
.count();
assert_eq!(matches, 1000);
}