Best way to timeout and return partial results?

I’m writing a number of queries that will return quickly most of the time. However in certain cases, because of the structure of the graph (high degree nodes, etc) they will time out.

When a query times out, I’m interested in returning partial results. Even if the full results could not be found, partial results may still be useful for a user. As an example I’ll give a simplified query:

CREATE QUERY searchNeighbors(Vertex seed, String searchTerm, Int skip=0, Int lim=10) FOR GRAPH test SYNTAX v2 { 
  SetAccum<Vertex> @@hits;
  OrAccum @visited = false;
  SumAccum<int> @@loop=0;
  MinAccum<Int> @depth;
     
  // mark seed visited
  Frontier (ANY) = {seed};
  Frontier = SELECT v
          FROM Frontier:v
          ACCUM v.@visited += true;
  
  // breadth-first search
  WHILE (@@hits.size() < skip + lim) DO
    @@loop += 1;

    Frontier =  SELECT v
                FROM Frontier:u-((_|_>):e)-ANY:v
                WHERE v.@visited == false
                ACCUM v.@visited += true, v.@depth += @@loop
                POST-ACCUM
                  CASE WHEN v.name == searchTerm THEN @@hits += v END;
  END;
  

  results (ANY) = @@hits;
  // get results in BFS order
  results = SELECT u FROM results:u ORDER BY u.@depth ASC, getvid(u) DESC LIMIT lim OFFSET skip;
  print results;
}

What I would like to do is break out of the WHILE loop if the query goes on too long, and take whatever is in @@hits and proceed to the next stage of the query.

What’s the best way to do this in GSQL?

You can increase your query limit (timeout) if you would like? @dsolow Which product are you using Enterprise Edition, Developer Edition, Cloud Edition?

I’m using enterprise edition.

I’m not really interested in increasing the timeout. If I hit the timeout it’s already too late – the query results will be lost.

Have you tried adding WHILE LIMIT semantics (Few Examples)

# These three WHILE statements behave the same.  Each terminates when 
# (v.size == 0) or after 5 iterations of the loop.
WHILE v.size() !=0 LIMIT 5 DO 
    # Some statements		
END;
  
INT iter = 0;
WHILE (v.size() !=0) AND (iter < 5) DO
	# Some statements
    iter = iter + 1;		
END;
 
INT iter = 0;
WHILE v.size() !=0 DO
    IF iter == 5 THEN  BREAK;  END;
    # Some statements	
	iter = iter + 1;	
END;

@dsolow

Yeah I’m using these now. What I’d like to be able to do is make the following guarantees:

  1. The query will run for no longer than a certain time
  2. If this time is reached, partial results (whatever has been found so far) are returned

Have you used the DATETIME the IF THEN BREAK?

https://docs.tigergraph.com/dev/gsql-ref/querying/operators-functions-and-expressions#datetime-functions

You could grab IF now() is 16 seconds past original time then BREAK

3 Likes

Thanks for all the <3 everyone!!

1 Like