diff --git a/Libraries/Interaction/InteractionManager.js b/Libraries/Interaction/InteractionManager.js index 93c384d23..098dfcee9 100644 --- a/Libraries/Interaction/InteractionManager.js +++ b/Libraries/Interaction/InteractionManager.js @@ -19,6 +19,13 @@ var invariant = require('invariant'); var keyMirror = require('keyMirror'); var setImmediate = require('setImmediate'); +type Handle = number; + +/** + * Maximum time a handle can be open before warning in DEV. + */ +var DEV_TIMEOUT = 2000; + var _emitter = new EventEmitter(); var _interactionSet = new Set(); var _addInteractionSet = new Set(); @@ -83,17 +90,25 @@ var InteractionManager = { /** * Notify manager that an interaction has started. */ - createInteractionHandle(): number { + createInteractionHandle(): Handle { scheduleUpdate(); var handle = ++_inc; _addInteractionSet.add(handle); + if (__DEV__) { + // Capture the stack trace of what created the handle. + var error = new Error( + 'InteractionManager: interaction handle not cleared within ' + + DEV_TIMEOUT + ' ms.' + ); + setDevTimeoutHandle(handle, error, DEV_TIMEOUT); + } return handle; }, /** * Notify manager that an interaction has completed. */ - clearInteractionHandle(handle: number) { + clearInteractionHandle(handle: Handle) { invariant( !!handle, 'Must provide a handle to clear.' @@ -151,4 +166,19 @@ function processUpdate() { _deleteInteractionSet.clear(); } +/** + * Wait until `timeout` has passed and warn if the handle has not been cleared. + */ +function setDevTimeoutHandle( + handle: Handle, + error: Error, + timeout: number +): void { + setTimeout(() => { + if (_interactionSet.has(handle)) { + console.warn(error.message + '\n' + error.stack); + } + }, timeout); +} + module.exports = InteractionManager;