Created
July 12, 2017 12:31
-
-
Save bennadel/998aa3f30e50e88b5311f49dad3e0831 to your computer and use it in GitHub Desktop.
Calling Timeout.unref() With setTimeout() Does Not Appear To Be A Best Practice In Node.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Require the application modules. | |
| var api = require( "./api" ); | |
| // ----------------------------------------------------------------------------------- // | |
| // ----------------------------------------------------------------------------------- // | |
| var TEN_SECONDS = ( 10 * 1000 ); | |
| function runWithTimeout( command, timeout = TEN_SECONDS ) { | |
| // Since we can't cancel a command once it has been executed, we have to | |
| // conditionally turn a command into either a resolved or a rejected promise. In | |
| // this case, we'll use a timer to generate a rejected promise prior to command | |
| // completion if the command takes too long to return. | |
| var promise = new Promise( | |
| function( resolve, reject ) { | |
| // Setup our rejection timer to preemptively kill hanging commands. | |
| var timer = setTimeout( | |
| function rejectHangingCommand() { | |
| reject( new Error( "Command took too long (and was timed-out)." ) ); | |
| }, | |
| timeout | |
| ); | |
| // ************************************************************** // | |
| // ************************************************************** // | |
| // CAUTION: This is the line that seemingly makes no sense (to me). | |
| // I cannot figure out what purpose it actually serves. | |
| timer.unref(); | |
| // ************************************************************** // | |
| // ************************************************************** // | |
| // Catch any synchronous execution errors. | |
| try { | |
| var commandPromise = Promise.resolve( command() ); | |
| } catch ( error ) { | |
| var commandPromise = Promise.reject( error ); | |
| } | |
| // Once the command returns, we need to use the result to fulfill the | |
| // contextual Promise. However, the command may return before OR after the | |
| // timeout has already rejected the contextual Promise. As such, the | |
| // following operations may actually be No-Op instructions. | |
| commandPromise.then( | |
| function handleResolve( result ) { | |
| clearTimeout( timer ); | |
| resolve( result ); | |
| }, | |
| function handleReject( error ) { | |
| clearTimeout( timer ); | |
| reject( error ); | |
| } | |
| ); | |
| } | |
| ); | |
| return( promise ); | |
| } | |
| // ----------------------------------------------------------------------------------- // | |
| // ----------------------------------------------------------------------------------- // | |
| // Run the command with a 1-Second timeout. Since our command will take 5-Seconds to | |
| // execute, we know that the command-runner's timer will terminate the request early. | |
| var promise = runWithTimeout( | |
| function command() { | |
| return( api.echoAfterTimeout( "[data payload]", 5000 ) ); | |
| }, | |
| 1000 | |
| ); | |
| promise.then( | |
| function handleResolve( result ) { | |
| console.log( "Success:", result ); | |
| }, | |
| function handleReject( error ) { | |
| console.log( "Error:", error ); | |
| } | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| console.log( "App started." ); | |
| var timer = setTimeout( | |
| function timeoutCallback() { | |
| console.log( "Timer callback." ); | |
| }, | |
| 1000 | |
| ); | |
| // At this point, the timer is the only action that would hold the node-process open. By | |
| // unref-ing it, the process will exit prior to the timeout callback execution and we | |
| // should never see the second console.log() statement. | |
| timer.unref(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I guess you've already figured that out, nevertheless, I think you can think of a scenario like this.