-
Notifications
You must be signed in to change notification settings - Fork 40
Open
Description
I am getting this exception when I close the pool very soon after closing a query:
Uncaught Error: Bad state: Cannot write to socket, it is closed
Stack Trace:
#0 BufferedSocket.writeBufferPart (package:sqljocky/src/buffered_socket.dart:114:7)
#1 BufferedSocket.writeBuffer (package:sqljocky/src/buffered_socket.dart:108:27)
#2 _Connection._sendBufferPart (package:sqljocky/src/connection.dart:261:31)
#3 _Connection._sendBuffer (package:sqljocky/src/connection.dart:249:29)
#4 _Connection.processHandler (package:sqljocky/src/connection.dart:289:16)
#5 ConnectionPool._closeQuery.<anonymous closure> (package:sqljocky/src/connection_pool.dart:220:29)
#6 _rootRunUnary (dart:async/zone.dart:730)
#7 _RootZone.runUnary (dart:async/zone.dart:864)
#8 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#9 _Future._propagateToListeners (dart:async/future_impl.dart:571)
#10 _Future._completeWithValue (dart:async/future_impl.dart:331)
#11 _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:393)
#12 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#13 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)
Unhandled exception:
Bad state: Cannot write to socket, it is closed
#0 _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:713)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#3 _asyncRunCallback (dart:async/schedule_microtask.dart:36)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)
the issue seems to be that the query close fires of a Future internally, so the close() function returns before the close is actually finished:
void _closeQuery(Query q, bool retain) {
_log.finest("Closing query: ${q.sql}");
for (var cnx in _pool) {
var preparedQuery = cnx.removePreparedQueryFromCache(q.sql);
if (preparedQuery != null) {
_waitUntilReady(cnx).then((_) {
_log.finest("Connection ready - closing query: ${q.sql}");
var handler = new _CloseStatementHandler(preparedQuery.statementHandlerId);
cnx.autoRelease = !retain;
cnx.processHandler(handler, noResponse: true);
});
}
}
}
The pool close happens immediately, it closes the socket right away. This means the query close (which is delayed till after the pool close due to the Future) fails, unable to send whatever information it needs to through the socket. I think the query close either needs to be changed to return a Future that doesn't complete until the query is actually closed, or the query close needs to be changed to be able to deal with the closed socket.
Code to replicate the issue:
Future _putMethod(RestRequest request) {
return new Future.sync(() {
mysql.ConnectionPool pool = getConnectionPool();
return pool.prepare("SELECT * FROM files").then((mysql.Query query) {
return query.execute().then((result) {
// Do something?
}).then((_) {
this._log.info("Closing");
query.close();
});
}).then((_) {
pool.close();
});
});
}
Metadata
Metadata
Assignees
Labels
No labels