Skip to content

Commit 9d03115

Browse files
committed
Push pooling logic into connection providers
1 parent 579b614 commit 9d03115

File tree

78 files changed

+1234
-885
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1234
-885
lines changed

gulpfile.babel.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const ts = require('gulp-typescript')
3838
const JasmineReporter = require('jasmine-spec-reporter').SpecReporter
3939
const karma = require('karma')
4040
const log = require('fancy-log')
41+
const JasmineExec = require('jasmine')
4142

4243
/**
4344
* Useful to investigate resource leaks in tests. Enable to see active sockets and file handles after the 'test' task.
@@ -112,6 +113,18 @@ gulp.task(
112113
})
113114
)
114115

116+
gulp.task('test-nodejs-unit', () => {
117+
return runJasmineTests('#unit*')
118+
})
119+
120+
gulp.task('test-nodejs-stub', () => {
121+
return runJasmineTests('#stub*')
122+
})
123+
124+
gulp.task('test-nodejs-integration', () => {
125+
return runJasmineTests('#integration*')
126+
})
127+
115128
gulp.task('run-browser-test-chrome', function (cb) {
116129
runKarma('chrome', cb)
117130
})
@@ -248,3 +261,24 @@ function runKarma (browser, cb) {
248261
}
249262
).start()
250263
}
264+
265+
function runJasmineTests (filterString) {
266+
return new Promise((resolve, reject) => {
267+
const jasmine = new JasmineExec()
268+
jasmine.loadConfigFile('./spec/support/jasmine.json')
269+
jasmine.loadHelpers()
270+
jasmine.loadSpecs()
271+
jasmine.configureDefaultReporter({
272+
print: () => {}
273+
})
274+
jasmine.addReporter(newJasmineConsoleReporter())
275+
jasmine.onComplete(passed => {
276+
if (passed) {
277+
resolve()
278+
} else {
279+
reject(new Error('tests failed'))
280+
}
281+
})
282+
jasmine.execute(null, filterString)
283+
})
284+
}

package-lock.json

Lines changed: 3 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/support/jasmine.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"spec_dir": "test",
3+
"spec_files": ["**/*.test.js", "!**/browser/*.js"],
4+
"helpers": ["../node_modules/@babel/register/lib/node.js"],
5+
"stopSpecOnExpectationFailure": false,
6+
"random": true
7+
}

src/driver.js

Lines changed: 15 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import Session from './session'
2121
import Pool from './internal/pool'
22-
import Connection from './internal/connection'
22+
import ChannelConnection from './internal/connection-channel'
2323
import { newError, SERVICE_UNAVAILABLE } from './error'
2424
import DirectConnectionProvider from './internal/connection-provider-direct'
2525
import Bookmark from './internal/bookmark'
@@ -76,19 +76,9 @@ class Driver {
7676
this._id = idGenerator++
7777
this._address = address
7878
this._userAgent = userAgent
79-
this._openConnections = {}
8079
this._authToken = authToken
8180
this._config = config
8281
this._log = Logger.create(config)
83-
this._pool = new Pool({
84-
create: this._createConnection.bind(this),
85-
destroy: this._destroyConnection.bind(this),
86-
validate: this._validateConnection.bind(this),
87-
installIdleObserver: this._installIdleObserverOnConnection.bind(this),
88-
removeIdleObserver: this._removeIdleObserverOnConnection.bind(this),
89-
config: PoolConfig.fromDriverConfig(config),
90-
log: this._log
91-
})
9282

9383
/**
9484
* Reference to the connection provider. Initialized lazily by {@link _getOrCreateConnectionProvider}.
@@ -120,66 +110,6 @@ class Driver {
120110
return connectivityVerifier.verify({ database })
121111
}
122112

123-
/**
124-
* Create a new connection and initialize it.
125-
* @return {Promise<Connection>} promise resolved with a new connection or rejected when failed to connect.
126-
* @access private
127-
*/
128-
_createConnection (address, release) {
129-
const connection = Connection.create(
130-
address,
131-
this._config,
132-
this._createConnectionErrorHandler(),
133-
this._log
134-
)
135-
connection._release = () => release(address, connection)
136-
this._openConnections[connection.id] = connection
137-
138-
return connection.connect(this._userAgent, this._authToken).catch(error => {
139-
if (this.onError) {
140-
// notify Driver.onError callback about connection initialization errors
141-
this.onError(error)
142-
}
143-
// let's destroy this connection
144-
this._destroyConnection(connection)
145-
// propagate the error because connection failed to connect / initialize
146-
throw error
147-
})
148-
}
149-
150-
/**
151-
* Check that a connection is usable
152-
* @return {boolean} true if the connection is open
153-
* @access private
154-
**/
155-
_validateConnection (conn) {
156-
if (!conn.isOpen()) {
157-
return false
158-
}
159-
160-
const maxConnectionLifetime = this._config.maxConnectionLifetime
161-
const lifetime = Date.now() - conn.creationTimestamp
162-
return lifetime <= maxConnectionLifetime
163-
}
164-
165-
_installIdleObserverOnConnection (conn, observer) {
166-
conn._queueObserver(observer)
167-
}
168-
169-
_removeIdleObserverOnConnection (conn) {
170-
conn._updateCurrentObserver()
171-
}
172-
173-
/**
174-
* Dispose of a connection.
175-
* @return {Connection} the connection to dispose.
176-
* @access private
177-
*/
178-
_destroyConnection (conn) {
179-
delete this._openConnections[conn.id]
180-
conn.close()
181-
}
182-
183113
/**
184114
* Acquire a session to communicate with the database. The session will
185115
* borrow connections from the underlying connection pool as required and
@@ -225,38 +155,27 @@ class Driver {
225155
}
226156

227157
// Extension point
228-
_createConnectionProvider (address, connectionPool, driverOnErrorCallback) {
229-
return new DirectConnectionProvider(
230-
address,
231-
connectionPool,
232-
driverOnErrorCallback
233-
)
234-
}
235-
236-
// Extension point
237-
_createConnectionErrorHandler () {
238-
return new ConnectionErrorHandler(SERVICE_UNAVAILABLE)
158+
_createConnectionProvider (address, userAgent, authToken) {
159+
return new DirectConnectionProvider({
160+
id: this._id,
161+
config: this._config,
162+
log: this._log,
163+
address: address,
164+
userAgent: userAgent,
165+
authToken: authToken
166+
})
239167
}
240168

241169
_getOrCreateConnectionProvider () {
242170
if (!this._connectionProvider) {
243-
const driverOnErrorCallback = this._driverOnErrorCallback.bind(this)
244171
this._connectionProvider = this._createConnectionProvider(
245172
this._address,
246-
this._pool,
247-
driverOnErrorCallback
173+
this._userAgent,
174+
this._authToken
248175
)
249176
}
250-
return this._connectionProvider
251-
}
252177

253-
_driverOnErrorCallback (error) {
254-
const userDefinedOnErrorCallback = this.onError
255-
if (userDefinedOnErrorCallback && error.code === SERVICE_UNAVAILABLE) {
256-
userDefinedOnErrorCallback(error)
257-
} else {
258-
// we don't need to tell the driver about this error
259-
}
178+
return this._connectionProvider
260179
}
261180

262181
/**
@@ -266,18 +185,8 @@ class Driver {
266185
*/
267186
close () {
268187
this._log.info(`Driver ${this._id} closing`)
269-
270-
try {
271-
// purge all idle connections in the connection pool
272-
this._pool.purgeAll()
273-
} finally {
274-
// then close all connections driver has ever created
275-
// it is needed to close connections that are active right now and are acquired from the pool
276-
for (let connectionId in this._openConnections) {
277-
if (this._openConnections.hasOwnProperty(connectionId)) {
278-
this._openConnections[connectionId].close()
279-
}
280-
}
188+
if (this._connectionProvider) {
189+
this._connectionProvider.close()
281190
}
282191
}
283192
}

0 commit comments

Comments
 (0)