Dmitry Bubnenkov
Dmitry Bubnenkov

Reputation: 9859

TimeoutException: Future not completed

I am getting error and can't understand what can be wrong. Error:

This query is already running
TimeoutException: Future not completed

code:

 Future<void> addResultToCache(sqlQuery) async {
  try {
      if(pendingFutures.containsKey(sqlQuery.hashCode)) {
        print('This query is already running');
        await pendingFutures[sqlQuery.hashCode];
        print("This Line is already do not prints"); 
      }
      else {
        pendingFutures.addAll({sqlQuery.hashCode: connection.query(sqlQuery, timeoutInSeconds: 3600)});
        var queryResult = await pendingFutures[sqlQuery.hashCode]; // run pending Future 
        await pendingFutures.remove(sqlQuery.hashCode); // remove pending future from list
        var queryObj = RequestCacheStruct(sqlQuery.hashCode, DateTime.now(), queryResult! );
        requestsCacheList.add(queryObj);
        
        print('Query was added to сache');
      }
   }
      on TimeoutException catch(e) {
        print('TimeoutException: ${e.message}' );
        }
}

The bug is rise not every time, but usually after n runs (after 2-3 minutes of working). It seems that something wrong with:

await pendingFutures[sqlQuery.hashCode];

Could you give any ideas what can be wrong with my code?

Does Futures have default timeouts and it's my case?

Upvotes: 3

Views: 10524

Answers (2)

lrn
lrn

Reputation: 71653

I don't think there is anything wrong with the particular line you ask about. Your code seems reasonable, although overly complicated.

You seem to assume that the hashCode of an sqlQuery is unique. It's not. It's quite possible to have two different queries with the same hashCode, in which case your pendingFutures may cause you to discard the second one to be queried. That's likely not your problem here, but it's something to be wary of.

You do genuinely seem to get two requests with the same hashCode (either really the same request or a hash-code conflict), and at least one request which completes with a TimeoutException. The await pendingFutures[sqlQuery.hashCode]; waits for the repeated request's future. Then some future completes, possibly that one, possibly another one, with a TimeoutException. That causes either that await or the one in var queryResult = await pendingFutures[sqlQuery.hashCode]; to throw the TimeoutException, which is caught and printed by your catch clause.

Since your request's timeout is set to one hour, it's reasonable that it happens only after that long. Or earlier, if something else in the system also has a timeout which triggers, but that depends on which other code you're running. Futures in general do not have timeouts unless you ask for one.

Upvotes: 1

Antoniossss
Antoniossss

Reputation: 32517

Your future throws TimeoutException and your catch clause of try-catch block is kicking in.

As for why is it happen, it might be dozens of things. Since it works for you cople of times and then stops I would say that your SQL server times out queries because for example of lack of working threads. Maybe you are running more queries at once that DB is configured to handle, maybe you are not releasing connections which causes connection pool drainage. Those are just blind guesses.

Upvotes: 0

Related Questions