Changeset - 67347c027b2a
[Not reviewed]
default
0 1 0
Drew Perttula - 8 years ago 2017-06-10 10:19:35
drewp@bigasterisk.com
hopefully harmmless steps towards making the handler tree right
Ignore-this: 1e7acf9e64ac8cc5250a3da3876af130
1 file changed with 37 insertions and 5 deletions:
0 comments (0 inline, 0 general)
light9/web/graph.coffee
Show inline comments
 
@@ -36,57 +36,87 @@ class AutoDependencies
 
    if not label?
 
      throw new Error("missing label")
 

	
 
    h = new Handler(func, label)
 
    tailChildren = @handlerStack[@handlerStack.length - 1].innerHandlers
 
    matchingLabel = _.filter(tailChildren, ((c) -> c.label == label)).length
 
    # ohno, something depends on some handlers getting run twice :(
 
    if matchingLabel < 2
 
      tailChildren.push(h)
 
    console.time("handler #{label}")
 
    @_rerunHandler(h, null)
 
    console.timeEnd("handler #{label}")
 
    @_logHandlerTree()
 
    
 
  _rerunHandler: (handler, patch) ->
 
    handler.patterns = []
 
    @handlerStack.push(handler)
 
    try
 
      handler.func(patch)
 
    catch e
 
      log('error running handler: ', e)
 
      # assuming here it didn't get to do all its queries, we could
 
      # add a *,*,*,* handler to call for sure the next time?
 
    finally
 
      #log('done. got: ', handler.patterns)
 
      @handlerStack.pop()
 
    # handler might have no watches, in which case we could forget about it
 

	
 
  _logHandlerTree: ->
 
    log('handler tree:')
 
    prn = (h, depth) ->
 
      indent = ''
 
      for i in [0...depth]
 
        indent += '  '
 
      log(indent + h.label)
 
      log("#{indent} \"#{h.label}\" #{h.patterns.length} pats")
 
      for c in h.innerHandlers
 
        prn(c, depth + 1)
 
    prn(@handlers, 0)
 

	
 
  _allPatchSubjs: (patch) ->
 

	
 
    allPatchSubjs = []
 
    for stmt in patch.addQuads
 
      allPatchSubjs.push(stmt.subject)
 
    for stmt in patch.delQuads
 
      allPatchSubjs.push(stmt.subject)
 
    allPatchSubjs = _.uniq(allPatchSubjs)
 
    if _.contains(allPatchSubjs, null) or allPatchSubjs.length == 0
 
      allPatchSubjs = null
 
    log('allPatchSubjs', allPatchSubjs)
 
    
 
  _handlerIsAffected: (child, allPatchSubjs) ->
 
    if allPatchSubjs == null
 
      return true
 
    if not child.patterns.length
 
      return false
 
      
 
    for stmt in child.patterns
 
      if _.contains(allPatchSubjs, stmt[0])
 
        return true
 

	
 
    return false
 
            
 
  graphChanged: (patch) ->
 
    # SyncedGraph is telling us this patch just got applied to the graph.
 

	
 
    allPatchSubjs = @_allPatchSubjs(patch)
 
    
 
    rerunInners = (cur) =>
 
      toRun = cur.innerHandlers.slice()
 
      for child in toRun
 

	
 
        match = @_handlerIsAffected(child, allPatchSubjs)
 
        log('match', child.label, match)
 
        #child.innerHandlers = [] # let all children get called again
 
        
 
        @_rerunHandler(child, patch)
 
        rerunInners(child)
 
    rerunInners(@handlers)
 

	
 
  askedFor: (s, p, o, g) ->
 
    # SyncedGraph is telling us someone did a query that depended on
 
    # quads in the given pattern.
 
    current = @handlerStack[@handlerStack.length - 1]
 
    if current? and current != @handlers
 
      current.patterns.push([s, p, o, g])
 
      #log('push', s,p,o,g)
 

	
 
@@ -146,35 +176,37 @@ class window.SyncedGraph
 
    parser.parse trig, (error, quad, prefixes) =>
 
                  if (quad)
 
                    patch.addQuads.push(quad)
 
                  else
 
                    @_applyPatch(patch)
 
                    @_addPrefixes(prefixes)
 
                    cb() if cb
 
                    
 
  quads: () -> # for debugging
 
    [q.subject, q.predicate, q.object, q.graph] for q in @graph.find()
 

	
 
  applyAndSendPatch: (patch) ->
 
    console.time('applyAndSendPatch')
 
    if !Array.isArray(patch.addQuads) || !Array.isArray(patch.delQuads)
 
      throw new Error("corrupt patch: #{patch}")
 
      throw new Error("corrupt patch: #{JSON.stringify(patch)}")
 

	
 
    for qs in [patch.addQuads, patch.delQuads]
 
      for q in qs
 
        if not q.graph?
 
          throw new Error("corrupt patch: #{q}")
 
          throw new Error("corrupt patch: #{JSON.stringify(q)}")
 

	
 
    @_applyPatch(patch)
 
    @_client.sendPatch(patch) if @_client
 

	
 
    console.timeEnd('applyAndSendPatch')
 
    
 
  _applyPatch: (patch) ->
 
    # In most cases you want applyAndSendPatch.
 
    # 
 
    # This is the only method that writes to @graph!
 
    @cachedFloatValues.clear()
 
    for quad in patch.delQuads
 
      @graph.removeTriple(quad)
 
    for quad in patch.addQuads
 
      @graph.addTriple(quad)
 
    #log('applied patch locally', patchSizeSummary(patch))
 
    @_autoDeps.graphChanged(patch)
 

	
0 comments (0 inline, 0 general)