尝试关闭池和查询时出现套接字错误

时间:2014-07-13 19:47:21

标签: dart dart-async sqljocky

我在关闭查询后很快关闭池时遇到此异常:

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)

问题似乎是查询在内部关闭了一个Future,所以close()函数在关闭实际结束之前返回:

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);
      });
    }
  }
}

游泳池关闭立即发生,它会立即关闭套接字。这意味着查询关闭(由于Future而延迟到池关闭之后)失败,无法通过套接字发送它需要的任何信息。我已经在https://github.com/jamesots/sqljocky/issues/44打开了sqljocky的门票,但我没有收到任何回复,如果需要一段时间才能获得回复,我需要一个解决方法。

此代码允许我在100%的时间内复制问题:

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();
    });
  });
}

1 个答案:

答案 0 :(得分:0)

这不仅仅是一个问题,而是一个答案,但我无法以可用的方式将此代码放入评论中。

您应该确保返回从每个异步调用返回的Future。 我不知道我添加评论// added return的行是否是异步调用。

如果发生任何变化,请试着提供反馈。

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? // also ensure that a Future of an async invocation is returned
      }).then((_) {
        this._log.info("Closing");
        return query.close(); // added return
      });
    }).then((_) {
      return pool.close(); // added return
    });
  });
}