@@ -124,37 +124,41 @@ function callbackify(func) {
124
124
// if last argument is not a function, simply invoke the function as usual
125
125
// and a promise will be returned
126
126
if ( typeof arguments [ arguments . length - 1 ] !== 'function' ) {
127
- return func . apply ( this , arguments ) . catch ( function stackCapture ( err ) {
128
- throw errors . transformErr ( err , stackCapture ) ;
129
- } ) ;
127
+ return func . apply ( this , arguments ) ;
130
128
}
131
129
132
130
// otherwise, resolve or reject the promise and invoke the callback
133
131
const args = Array . prototype . slice . call ( arguments , 0 , arguments . length - 1 ) ;
134
132
const cb = arguments [ arguments . length - 1 ] ;
135
133
func . apply ( this , args ) . then ( function ( result ) {
136
134
cb ( null , result ) ;
137
- } , function stackCapture ( err ) {
138
- cb ( errors . transformErr ( err , stackCapture ) ) ;
139
- } ) ;
135
+ } , cb ) ;
140
136
} ;
141
137
if ( func . name ) {
142
138
Object . defineProperty ( wrapper , 'name' , { value : func . name } ) ;
143
139
}
144
140
return wrapper ;
145
141
}
146
142
147
- // The serialize function is used to wrap methods to ensure that the connection
148
- // is not used concurrently by multiple threads
149
- function serialize ( func ) {
150
- return async function ( ) {
143
+ // the wrapFn() function is used to wrap a single method to ensure that calls
144
+ // are serialized and that concurrent calls are prevented where that is needed;
145
+ // this method also ensures that error information is captured correctly
146
+ function wrapFn ( func , serialize , preventConcurrentErrorCode ) {
147
+ const wrapper = async function wrapper ( ) {
151
148
152
149
let connImpl ;
153
150
151
+ // if concurrent operations are to be prevented, check for that now
152
+ if ( preventConcurrentErrorCode ) {
153
+ if ( this . _isActive )
154
+ errors . throwErr ( preventConcurrentErrorCode ) ;
155
+ this . _isActive = true ;
156
+ }
157
+
154
158
// determine the connection implementation associated with the object, if
155
159
// one currently exists and acquire the "lock"; this simply checks to see
156
160
// if another operation is in progress, and if so, waits for it to complete
157
- if ( this . _impl ) {
161
+ if ( serialize && this . _impl ) {
158
162
connImpl = this . _impl . _getConnImpl ( ) ;
159
163
await connImpl . _acquireLock ( ) ;
160
164
}
@@ -164,46 +168,43 @@ function serialize(func) {
164
168
// if a connection implementation is currently associated with this object
165
169
try {
166
170
return await func . apply ( this , arguments ) ;
171
+ } catch ( err ) {
172
+ throw errors . transformErr ( err , wrapper ) ;
167
173
} finally {
168
174
if ( connImpl )
169
175
connImpl . _releaseLock ( ) ;
176
+ if ( preventConcurrentErrorCode ) {
177
+ this . _isActive = false ;
178
+ }
170
179
}
171
- } ;
172
- }
173
180
174
- function preventConcurrent ( func , errorCode ) {
175
- return async function ( ) {
176
- if ( this . _isActive )
177
- errors . throwErr ( errorCode ) ;
178
- this . _isActive = true ;
179
- try {
180
- return await func . apply ( this , arguments ) ;
181
- } finally {
182
- this . _isActive = false ;
183
- }
184
181
} ;
182
+ if ( func . name ) {
183
+ Object . defineProperty ( wrapper , 'name' , { value : func . name } ) ;
184
+ }
185
+ return wrapper ;
185
186
}
186
187
187
188
// The wrapFns() function is used to wrap the named methods on the prototype
188
- // in multiple ways (serialize, preventConcurrent and callbackify) ; the
189
+ // so that a number of common tasks can be done in a single place ; the
189
190
// arguments following the formal arguments contain the names of methods to
190
191
// wrap on the prototype; if the first extra argument is an error code, it is
191
192
// used to wrap to prevent concurrent access
192
193
function wrapFns ( proto ) {
193
194
let nameIndex = 1 ;
195
+ let serialize = true ;
194
196
let preventConcurrentErrorCode ;
195
197
if ( typeof arguments [ 1 ] === 'number' ) {
196
- nameIndex = 2 ;
198
+ nameIndex ++ ;
197
199
preventConcurrentErrorCode = arguments [ 1 ] ;
200
+ } else if ( typeof arguments [ 1 ] === 'boolean' ) {
201
+ nameIndex ++ ;
202
+ serialize = arguments [ 1 ] ;
198
203
}
199
204
for ( let i = nameIndex ; i < arguments . length ; i ++ ) {
200
205
const name = arguments [ i ] ;
201
206
const f = proto [ name ] ;
202
- if ( preventConcurrentErrorCode ) {
203
- proto [ name ] = callbackify ( preventConcurrent ( serialize ( f ) ,
204
- preventConcurrentErrorCode ) ) ;
205
- } else
206
- proto [ name ] = callbackify ( serialize ( f ) ) ;
207
+ proto [ name ] = callbackify ( wrapFn ( f , serialize , preventConcurrentErrorCode ) ) ;
207
208
}
208
209
}
209
210
@@ -436,8 +437,7 @@ module.exports = {
436
437
isXid,
437
438
normalizeXid,
438
439
makeDate,
439
- preventConcurrent,
440
- serialize,
441
440
verifySodaDoc,
441
+ wrapFn,
442
442
wrapFns
443
443
} ;
0 commit comments