release-connection.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. module.exports = {
  2. friendlyName: 'Release connection',
  3. description: 'Release an active MySQL database connection back to the pool.',
  4. inputs: {
  5. connection: {
  6. friendlyName: 'Connection',
  7. description: 'An active database connection.',
  8. extendedDescription: 'The provided database connection instance must still be active. Only database connection instances created by the `getConnection()` machine in this driver are supported.',
  9. example: '===',
  10. required: true
  11. },
  12. meta: {
  13. friendlyName: 'Meta (custom)',
  14. description: 'Additional stuff to pass to the driver.',
  15. extendedDescription: 'This is reserved for custom driver-specific extensions. Please refer to the documentation for the driver you are using for more specific information.',
  16. example: '==='
  17. }
  18. },
  19. exits: {
  20. success: {
  21. description: 'The connection was released and is no longer active.',
  22. extendedDescription: 'The provided connection may no longer be used for any subsequent queries.',
  23. outputVariableName: 'report',
  24. outputDescription: 'The `meta` property is reserved for custom driver-specific extensions.',
  25. outputExample: '==='
  26. // outputExample: {
  27. // meta: '==='
  28. // }
  29. },
  30. badConnection: {
  31. friendlyName: 'Bad connection',
  32. description: 'The provided connection is not valid or no longer active. Are you sure it was obtained by calling this driver\'s `getConnection()` method?',
  33. extendedDescription: 'Usually, this means the connection to the database was lost due to a logic error or timing issue in userland code. In production, this can mean that the database became overwhelemed or was shut off while some business logic was in progress.',
  34. outputVariableName: 'report',
  35. outputDescription: 'The `meta` property is reserved for custom driver-specific extensions.',
  36. outputExample: '==='
  37. // outputExample: {
  38. // meta: '==='
  39. // }
  40. }
  41. },
  42. fn: function releaseConnection(inputs, exits) {
  43. var validateConnection = require('./private/validate-connection');
  44. // Validate provided connection.
  45. if (!validateConnection({ connection: inputs.connection }).execSync()) {
  46. return exits.badConnection({
  47. meta: inputs.meta
  48. });
  49. }
  50. // Release connection.
  51. try {
  52. // Note that if this driver is adapted to support managers which spawn
  53. // ad-hoc connections or manage multiple pools/replicas using PoolCluster,
  54. // then relevant settings would need to be included in the manager instance
  55. // so that connections can be appropriately released/destroyed here.
  56. //
  57. // For now, since we only support a single pool, we simply release the
  58. // connection back to the pool.
  59. inputs.connection.release();
  60. // If we made it here, releasing the connection gracefully must have worked.
  61. return exits.success();
  62. } catch (_releaseErr) {
  63. // If the connection cannot be released back to the pool gracefully,
  64. // try to force it to disconnect.
  65. try {
  66. inputs.connection.destroy();
  67. // If even THAT fails, exit via `error`.
  68. } catch (_destroyErr) {
  69. return exits.error(new Error('Could not release MySQL connection gracefully, and attempting to forcibly destroy the connection threw an error. Details:\n=== === ===\n' + _destroyErr.stack + '\n\nAnd error details from the original graceful attempt:\n=== === ===\n' + _releaseErr.stack));
  70. }
  71. // Otherwise if we're here, while we could not release the MySQL connection
  72. // gracefully, we were able to forcibly destroy it.
  73. return exits.success({
  74. meta: inputs.meta
  75. });
  76. }
  77. }
  78. };