Skip to content

Commit

Permalink
Working on connection management stuff.
Browse files Browse the repository at this point in the history
Got rid of pool.close() and introduced pool.closeConnectionsNow and pool.closeConnectionsWhenNotInUse
  • Loading branch information
jamesots committed May 15, 2014
1 parent 71e4f17 commit 94218b1
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

v0.12.0
-------
* Breaking change: ConnectionPool.close() has been renamed to ConnectionPool.closeConnectionsNow.
It is a dangerous method to call as it closes all connections even if they are in the middle
of an operation. ConnectionPool.closeConnectionsWhenNotInUse has been added, which is much
safer.

v0.11.0
-------
* Added support for packets larger than 16 MB. ConnectionPool's constructor has a new parameter,
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Things to do

* Compression
* COM_SEND_LONG_DATA
* CLIENT_MULTI_STATEMENTS and CLIENT_MULTI_RESULTS for stored procedures
* More connection pool management (close after timeout, change pool size...)
* Better handling of various data types, especially BLOBs, which behave differently when using straight queries and prepared queries.
* Implement the rest of mysql's commands
* Handle character sets properly? Currently defaults to UTF8 for the connection character set. Is it
Expand Down
16 changes: 15 additions & 1 deletion lib/src/connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class _Connection {
final Buffer _compressedHeaderBuffer;
Buffer _dataBuffer;
bool _readyForHeader = true;
bool _closeRequested = false;

int _packetNumber = 0;

Expand Down Expand Up @@ -56,6 +57,15 @@ class _Connection {
if (_socket != null) {
_socket.close();
}
_pool._removeConnection(this);
}

void closeWhenFinished() {
if (_inUse) {
_closeRequested = true;
} else {
close();
}
}

bool get inUse => _inUse;
Expand Down Expand Up @@ -216,11 +226,15 @@ class _Connection {
if (autoRelease && !inTransaction) {
log.finest("Response finished for #$number, setting handler to null and waiting to release and reuse");
new Future.delayed(new Duration(seconds: 0), () {
if (_closeRequested) {
close();
return;
}
if (_inUse) {
log.finest("Releasing and reusing connection #$number");
_inUse = false;
_handler = null;
_pool._newReuseConnection(this);
_pool._reuseConnectionForQueuedOperations(this);
}
});
} else {
Expand Down
33 changes: 25 additions & 8 deletions lib/src/connection_pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,16 @@ class ConnectionPool extends Object with _ConnectionHelpers implements Queriable
_pool.remove(cnx);
}

/**
/**
* Attempts to continue using a connection. If the connection isn't managed
* by this pool, or if the connection is already in use, nothing happens.
*
* If there are operations which have been queued in this pool, starts
* to execute that operation.
*
* Otherwise, nothing happens.
*
* //TODO rename to something like processQueuedOperations??
*/
_newReuseConnection(_Connection cnx) {
_reuseConnectionForQueuedOperations(_Connection cnx) {
if (!_pool.contains(cnx)) {
_log.warning("reuseConnection called for unmanaged connection");
return;
Expand Down Expand Up @@ -138,19 +136,38 @@ class ConnectionPool extends Object with _ConnectionHelpers implements Queriable
// });
// }

/**
* Closes all open connections.
*
/**
* Closes all open connections immediately. It doesn't wait for operations to complete.
*
* WARNING: this will probably break things.
*/
void close() {
void closeConnectionsNow() {
for (_Connection cnx in _pool) {
if (cnx != null) {
cnx.close();
}
}
}

/**
* Closes all connections as soon as they are no longer in use.
*
* Retained connections will only be closed once they have been released.
* Connection which are in use by a transaction will only be closed
* once the transaction has completed.
*
* Any operations which are initiated after calling this method will be
* executed on new connections, even if the current operations haven't
* yet finished when the operation is queued.
*/
void closeConnectionsWhenNotInUse() {
for (_Connection cnx in _pool) {
if (cnx != null) {
cnx.closeWhenFinished();
}
}
}

Future<Results> query(String sql) {
_log.info("Running query: ${sql}");

Expand Down
2 changes: 1 addition & 1 deletion lib/src/retained_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class _RetainedConnectionImpl extends _RetainedConnectionBase implements Retaine

_cnx.inTransaction = false;
_cnx.release();
_pool._newReuseConnection(_cnx);
_pool._reuseConnectionForQueuedOperations(_cnx);
}

void _checkReleased() {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/transaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class _TransactionImpl extends _RetainedConnectionBase implements Transaction {
.then((results) {
_cnx.inTransaction = false;
_cnx.release();
_pool._newReuseConnection(_cnx);
_pool._reuseConnectionForQueuedOperations(_cnx);
return results;
});
}
Expand All @@ -46,7 +46,7 @@ class _TransactionImpl extends _RetainedConnectionBase implements Transaction {
.then((results) {
_cnx.inTransaction = false;
_cnx.release();
_pool._newReuseConnection(_cnx);
_pool._reuseConnectionForQueuedOperations(_cnx);
return results;
});
}
Expand Down

0 comments on commit 94218b1

Please sign in to comment.