On Wed, 20 Mar 2024 at 08:09, Henrik Grubbström (Lysator) @ Pike (-) importmöte för mailinglistan <6...@lyskom.lysator.liu.se> wrote: > > > Hey, folks. > > Hi Mike. > > > We have a MySql database we need to connect to on this project, and > > having trouble getting asynchronous requests to work. > > > > If we use `dbconn->typed_query`, we get the expected response. > > > > With promise_query, seeing: `SQL status: still running...` > > > > Chris Angelico promises (pun intended) to pry further into it, and I > > hope you don't mind more spam from me in the meantime. > > > [...] > > The first thing to check is: Have you started the default backend (ie > returned -1 or a Concurrent.Future from main()? >
Yes, the backend is running. I did some further tests and have found that the PostgreSQL bindings work fine either synchronously or asynchronously, and MySQL works synchronously, but not async. Here's my test code, using async functions: Concurrent.Future main() {return test();} __async__ void run_test(string uri, string query) { werror("****** %s *******\n", uri); Sql.Sql dbconn = Sql.Sql(uri); werror("Query result: %O\n", dbconn->typed_query(query)); mixed q = dbconn->promise_query(query); werror("Promise: %O\n", q); mixed result = await(q); werror("Result: %O\n", result); werror("Rows: %O\n", result->get()); } __async__ void test() { await(run_test("pgsql://USER:PASSWORD@127.0.0.1/DATABASE", "select 1")); await(run_test("mysql://USER:PASSWORD@127.0.0.1/", "select 1 from dual")); } Equivalent using explicit promises: int main() {test(); return -1;} Concurrent.Future run_test(string uri, string query) { werror("****** %s *******\n", uri); Sql.Sql dbconn = Sql.Sql(uri); werror("Query result: %O\n", dbconn->typed_query(query)); mixed q = dbconn->promise_query(query); werror("Promise: %O\n", q); return q->then() {[mixed result] = __ARGS__; werror("Result: %O\n", result); werror("Rows: %O\n", result->get()); }; } void test() { run_test("pgsql://USER:PASSWORD@127.0.0.1/DATABASE", "select 1")->then() { run_test("mysql://USER:PASSWORD@127.0.0.1/", "select 1 from dual")->then() {exit(0);}; }; } Running with -DSP_DEBUG shows something rather curious: Query result: ({ /* 1 element */ ([ /* 1 element */ "1": 1 ]) }) Create future mysql(/*127.0.0.1 via TCP/IP*/) "select 1 from dual" 0 Create future result mysql(/*127.0.0.1 via TCP/IP*/) "select 1 from dual" 0 Callback got ({ /* 1 element */ ({ /* 1 element */ 1 }) }) Callback got 0 Future succeeded "select 1 from dual" Promise: __builtin.Sql.Promise(no future,FutureResult from query: "select 1 from dual", bindings: 0 recordcount: 1 SQL status: still running...) The final line of output here comes from printing out the promise before awaiting it, but the query has already actually been run at this point (the "Callback got" lines show the incoming data). This isn't the case with the PostgreSQL bindings. It's possible something in the MySQL bindings is operating synchronously. Side note: Pike actually doesn't build against the latest MySQL due to the removal of some ancient deprecated functions, so I have been using the MariaDB client which is what ships with Debian anyway. They're meant to be equivalent so I doubt this is the cause of the issue. ChrisA