user-documentation icon indicating copy to clipboard operation
user-documentation copied to clipboard

Recommendation about concurrent calls to AsyncMysqlConnection queryf doesn't apply

Open lexidor opened this issue 5 years ago • 4 comments

Please complete the information below:

Where is the problem?

We strongly recommend using multiple calls to `queryf()` instead
as it escapes parameters; multiple queries can be
executed simultaneously by combining `queryf()` with `HH\Asio\v()`.

What is the problem?

You can't multiplex queries, so Asio\v() will almost always throw an InvalidArgumentException about the connection being busy.

Question

What is the recommended pattern here? More mysql connections only work if you don't rely on a transaction. If you do, you must execute all queries on one connection. ~Multiple sequential queries using an AsyncQueue incurs many round-trips between your webserver and SQL server.~ Multiple sequential queries using an AsyncQueue is currently the way I do things. However, calling a query method (effectively) sequentially does mean that you pay for "the roundtrip time times the query count" to your database in walltime.


Please don't change anything below this point.


  • Build ID: HHVM=HHVM-4.68.0:HSL=v4.41.0:2020-08-17T20:16:46+0000:7af74eee111304c3c25319df9d95501d92a64697
  • Page requested: /hack/reference/class/AsyncMysqlConnection/multiQuery/
  • Page requested at: Thu, 27 Aug 2020 23:31:48 +0000
  • Controller: APIMethodPageController

lexidor avatar Aug 27 '20 23:08 lexidor

You can't multiplex queries

This is assuming that transactions are used, right?

fredemmott avatar Aug 27 '20 23:08 fredemmott

Also the Asio\v recommendation should be replaced with HSL

fredemmott avatar Aug 27 '20 23:08 fredemmott

In my experience with AsyncMysql, if you do anything concurrently on the same connection, even a couple of unrelated selects, expect an InvalidArgumentException. I've wrapped all connections in an AsyncQueue to prevent this exception.

lexidor avatar Aug 27 '20 23:08 lexidor

$raw_async_mysql = await DB::connectAsync();
try {
  concurrent {
    await $raw_async_mysql->queryf('SELECT %d', 1);
    await $raw_async_mysql->queryf('SELECT %d', 2);
  }
} catch (\Exception $e) {
  echo $e->toString();
}

InvalidArgumentException' with message 'attempt to invoke method on a busy connection in file.hack ... stacktrace

lexidor avatar Aug 27 '20 23:08 lexidor