-
Notifications
You must be signed in to change notification settings - Fork 1.1k
WIP: 836 - pool.close()
should iterate open connections and close them
#950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Added logic for extra parameter in pool.js to forcibly close connection pool with DPI_MODE_POOL_CLOSE_FORCE after a timer has passed. Signed-off-by: Danilo Henrique Garcia da Silva <danilo_hgds@hotmail.com>
I thought of changing closeMode to forceClose and use it as a boolean, pass it over to the .cpp layer and then before the work is queued, the actual DPI enum value is resolved based on the variable.
I think it would overcomplicate things if we were to check isPoolClosing on the connection.close calls as well. Checking for connection == 0 in the pool.close call seems to be enough imo.
I went with the option of blocking only new getConnection calls from being executed and returned an NJS-064 to the user. Are there any other scenarios where we should block work?
I don't see a reason not to. I will change it. |
@danilohgds Maybe rename We had some attributes that used to start with "is", such as |
Signed-off-by: Danilo Henrique Garcia da Silva danilo_hgds@hotmail.com
Signed-off-by: Danilo Henrique Garcia da Silva danilo_hgds@hotmail.com
@dmcghan I changed them over to only closing. Initially I went with the poolClosing name as many variables are referenced that way, example poolMin, poolMax, and they get referenced the same way in cpp, so I followed that pattern. |
Test to validate new connections are not obtainable after force close. Signed-off-by: Danilo Henrique Garcia da Silva danilo_hgds@hotmail.com
pool.close()
should iterate open connections and close thempool.close()
should iterate open connections and close them
Validates NJS-064
Make closing available, only mark closing as true when calling ODPI with force.
Added forceClose bool to njsBaton object
Added logic to read forceClose from baton object and pass over to Async_Close Async_Close now uses different DPI constants based on mode
remove unnecessary comments.
Added tests to cover most generic cases.
@cjbj @anthony-tuininga the changes on the c++ layer are also included. I tested some cases which I came up with and the changes seem good. |
simplify force close and add logic to ensure 2 args are always passed.
@anthony-tuininga |
include As<Object>().
@anthony-tuininga I copied it over from your example, I ended up not seeing the Object part was missing. |
Right. Formatting issue. I forgot to tell it that it was code. Sorry about that! |
lib/pool.js
Outdated
const upperLimitTimeout = 2147483647; | ||
|
||
nodbUtil.assert(typeof drainTime === 'number', 'NJS-006', 2); | ||
nodbUtil.assert(drainTime >= 1 && drainTime <= upperLimitTimeout, 'NJS-005', 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this allow drainTime of 0, meaning force the connection pool to close?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I meant to have that as 0, good catch.
@danilohgds Looks good. Shall we take it over and test it and do doc etc? |
@cjbj please do. |
allow drain time to be 0 in assert clause.
@danilohgds Excellent. Anthony is already doing ODPI-C changes to make sure the forced pool close doesn't cause problems. |
@cjbj Awesome! shall I move to the next feature then ✌️ ? I was looking around the enhancement labels, do u have any in mind? |
@danilohgds Scanning my long "to do" list, most changes are C++ related. What level of work are you up for? If you want small 'paper cut' things:
Or what about adding some async/await examples? I already have a variant of webapp.js that is awaiting @dmcghan's review, but other examples would be good. |
@danilohgds a bigger example showing GraphQL or a REST service might be good. Specially if it has comments about how to use it in Angular! |
lib/pool.js
Outdated
nodbUtil.assert(typeof getConnectionCb === 'function', 'NJS-006', | ||
arguments.length); | ||
nodbUtil.assert(typeof getConnectionCb === 'function', 'NJS-006', arguments.length); | ||
nodbUtil.assert(self.closing === false, 'NJS-064', self.poolAlias); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about returning this in the callback?
- nodbUtil.assert(self.closing === false, 'NJS-064', self.poolAlias);
-
+ if (self.closing === true) {
+ getConnectionCb(new Error(nodbUtil.getErrorMessage('NJS-064', self.poolAlias)));
+ return;
+ }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question is then, should there be a second message printed when the pool has finally closed? The self.closing attribute would need to have 3 states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have a closing and hasClosed property? due to the nature of the closing being a boolean I would like to have a new property in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danilohgds I know @anthony-tuininga is keen to add a check on connectionsOut at connection release which may change the flags a bit; I'll let him add his proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion was to store "_closeCb" (callback function) on the pool instead of "closing" (boolean). That would allow, as Chris mentioned, the ability to check connectionsOut at connection release. If the connectionsOut after release is zero, the close callback can be invoked immediately (but first that attribute would be reset to undefined so that when the timeout expires it won't call it a second time). This would permit well-behaved applications with reasonably short connection lifetimes to shut down quickly without waiting for the drain time to expire.
My other suggestion was to change the API to use an options object instead of a simple integer. The options object could contain one or both of these two keys:
- force: forces the pool to be closed even if connections are out (default false)
- drainTime: specifies the maximum amount of time the pool will wait for connections to be released back to the pool (default 0 seconds)
This provides the current behaviour (immediate close with a failure if any connections are out) and also provides a means to control both options. Currently if any value is specified for drainTime then it is assumed that forcing the close at the end of the drainTime value is desirable, and if no value is specified, then forcing is not desired. Its a bit awkward, but workable. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anthony-tuininga I think I understand your suggestion now. So essentially, the driver would be able to intervene and invoke the call back when the connectionsOut reaches 0 and save time. Although, I think that the close callback can be called only after the self._close is called.. because that is when the pool shuts down.
As for the second suggestion, this would essentially mean that I can set up a drain time delay for both force and default option correct? I'm trying to see situations in which setting a drain time without the force would be used, since it might eventually fail if there still connections, maybe a routine that catches such error and schedules the closing again after X time? Might be beneficial I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with the first suggestion (it completes #836 (comment)) but I'm not worried if it gets deferred.
I don't see a strong reason to have a drainTime for a non-force close. Having what is effectively 'named' parameters does add flexibility for future OCI session pool enhancements, but I'm not sure it's worth it. I'd be happy to go with the implemented 'less typing' API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed some of the code around for proper error messaging like you suggested, also cleaned up some variables and comments.
I will see how to make the ._close function stored and callable later during the connection releases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danilohgds excellent. Ping us if you want us to take over.
Some of the asserts are printing the wrong parameter numbers. How about moving them all to the top like this (based on how
I have't extensively tested it yet. |
remove unnecessary logs. remove unused variable in njspool
@danilohgds if you're bored, one other general node-oracledb enhancement request would be to update the typescript files. |
} | ||
|
||
if (arguments.length === 1) { | ||
self.closing = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about moving the setting of the closing
property to closeWrapper()
? It's a straight assignment of the value of mode
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe not. It should probably be set before making an async call
@@ -398,6 +439,14 @@ function extend(pool, poolAttrs, poolAlias, oracledb) { | |||
value: closePromisified, | |||
enumerable: true, | |||
writable: true | |||
}, | |||
closing: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this new property should be added to _logStats()
too:
console.log('...closing:', self.closing);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, that information might be helpful in some cases.
As for the closing, I thought of changing it over to an enum:
*not closing
*close pending
*close issued
Not only it does give a better sense of what is going on under the hood, but also allows execute callbacks to cut in and call close first should there be no connectionsOut in use.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fair.
@danilohgds A proposed update landed on https://github.com/oracle/node-oracledb/tree/danilohgds-PR-836 Take a look. |
@danilohgds I pushed this in 4999982. Take a look and see what cleanup you want. A few tweaks from myself, @anthony-tuininga and @octokyle crept in :) Can you review the I changed the NJS message text so the pool alias isn't printed: not all pools have aliases. If you think the messages and logic should be updated to handle both cases (with & without aliases), send in the PR! |
@cjbj Looks fine to me. I think showing pool alias is redudant since you have to get the pool by the alias in case you have more than one. |
@danilohgds We really appreciate you putting time into this and making it happen. If you're in the office hours session tomorrow we can catch up. |
@cjbj I will be there ☺. |
Since this is now in master, I'll close the PR. Thanks @danilohgds. |
Added NJS-064 to util.js file
Added logic for an extra parameter in pool.js to forcibly close connection pool with DPI_MODE_POOL_CLOSE_FORCE after a timer has passed.
Signed-off-by: Danilo Henrique Garcia da Silva danilo_hgds@hotmail.com