Skip to content

Bad state: Cannot write to socket, it is closed on query close #44

@sanmadjack

Description

@sanmadjack

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
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions