Permalink
Browse files

improved fs.watch() failure handling for missing files

  • Loading branch information...
1 parent 71a73d4 commit 2724cf20c4ed222c8593362d9f967b0a1c5e90f3 @malgorithms committed Oct 11, 2012
Showing with 75 additions and 41 deletions.
  1. +37 −20 lib/engine.js
  2. +2 −2 package.json
  3. +2 −2 src/consts.coffee
  4. +34 −17 src/engine.coffee
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,7 +1,7 @@
{
"name": "toffee",
- "description": "An Express 3.x and 2.x templating language based on CoffeeScript with slicker tokens and syntax. Built with love at OkCupid.",
- "version": "0.0.46",
+ "description": "A NodeJs, Express 3.x, Express 2.x, and browser-side templating language based on CoffeeScript with slicker tokens and syntax. Built with love at OkCupid.",
+ "version": "0.0.47",
"directories": {
"lib": "./lib"
},
View
@@ -1,8 +1,8 @@
exports.states =
- TOFFEE: 1
+ TOFFEE: 1
COFFEE: 2
exports.TAB_SPACES = 2
exports.tweakables =
- MISSING_FILE_RECHECK: 1000 #ms
+ MISSING_FILE_RECHECK: 1000 # ms before checking if a file has been introduced/changed if fs.watch() fails
View
@@ -67,7 +67,8 @@ class engine
realpath = path.normalize filename
pwd = path.dirname realpath
- v = @viewCache[realpath] or @_loadCacheAndMonitor realpath, options
+ v = (@_viewCacheGet realpath) or (@_loadCacheAndMonitor realpath, options)
+
if v
options.__toffee.parent = realpath
options.partial = options.partial or (fname, lvars) => @_fn_partial fname, lvars, realpath, options
@@ -81,6 +82,16 @@ class engine
@_log "#{realpath} run in #{Date.now() - start_time}ms"
return [err, res]
+ _viewCacheGet: (filename) ->
+ if not @viewCache[filename]?
+ return null
+ else if not @fsErrorCache[filename]?
+ return @viewCache[filename]
+ else if (Date.now() - @fsErrorCache[filename]) < tweakables.MISSING_FILE_RECHECK
+ return @viewCache[filename]
+ else
+ return null
+
_inlineInclude: (filename, local_vars, parent_realpath, parent_options) =>
options = local_vars or {}
options.__toffee = options.__toffee or {}
@@ -113,21 +124,28 @@ class engine
return txt
_loadCacheAndMonitor: (filename, options) ->
+ previous_fs_err = @fsErrorCache[filename]?
try
txt = fs.readFileSync filename, 'utf8'
+ if @fsErrorCache[filename]? then delete @fsErrorCache[filename]
catch e
txt = "Error: Could not read #{filename}"
if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}"
- @fsErrorCache[filename] = Date.now()
- view_options =
- fileName: filename
- verbose: @verbose
- prettyPrintErrors: @prettyPrintErrors
- minimize: @minimize
- v = new view txt, view_options
- @viewCache[filename] = v
- @_monitorForChanges filename, options
- v
+ @fsErrorCache[filename] = Date.now()
+
+ # if we hit an fs error and it already happened, just return that
+ if (@fsErrorCache[filename] and previous_fs_err and @viewCache[filename])
+ return @viewCache[filename]
+ else
+ view_options =
+ fileName: filename
+ verbose: @verbose
+ prettyPrintErrors: @prettyPrintErrors
+ minimize: @minimize
+ v = new view txt, view_options
+ @viewCache[filename] = v
+ @_monitorForChanges filename, options
+ return v
_reloadFileInBkg: (filename, options) ->
fs.readFile filename, 'utf8', (err, txt) =>
@@ -154,12 +172,10 @@ class engine
we must continuously unwatch/rewatch because some editors/systems invoke a "rename"
event and we'll end up following the wrong, old 'file' as a new one
is dropped in its place.
+
+ Files that are missing are ignored here because they get picked up by new calls to _loadCacheAndMonitor
###
- if @fsErrorCache[filename]? and ((Date.now() - @fsErrorCache[filename]) > tweakables.MISSING_FILE_RECHECK)
- delete @fsErrorCache[filename]
- @_reloadFileInBkg filename, options
- @_monitorForChanges filename, options
- else
+ if not @fsErrorCache[filename]? # if there's an fsError, this will get rechecked on-demand occasionally
fsw = null
try
@_log "#{filename} starting fs.watch()"
@@ -169,6 +185,7 @@ class engine
@_monitorForChanges filename, options
@_reloadFileInBkg filename, options
catch e
- setTimeout (=> @_monitorForChanges filename, options), tweakables.MISSING_FILE_RECHECK
+ @_log "fs.watch() failed for #{filename}; settings fsErrorCache = true"
+ @fsErrorCache[filename] = Date.now()
exports.engine = engine

0 comments on commit 2724cf2

Please sign in to comment.