Repository: bokeh/bokeh

Issue:
tools cause hard crash on Safari after import/export PR 
@mattpap OSX / Safari is currently crash easily. AS an example:
- run `unemployment.py`
- pan around
- leave plot area
- pan more

That's pretty reliable way to crash and cause a page reload. Seems to be confined to Safari. A git bisection traced it to the import/export PR:

UPDATE: seems to be related to hover tool being on, see below

```
[bryan:~/work/bokeh]$ git bisect good                                                                                                          (1ef6d22)
d2ce1971e4b984c7d30728b2378f7c959a3efd06 is the first bad commit
commit d2ce1971e4b984c7d30728b2378f7c959a3efd06
Author: Mateusz Paprocki <mattpap@gmail.com>
Date:   Tue Oct 11 19:35:45 2016 +0200

    Use ES6 import/export instead of require() and module.exports (#5321)

    * tsjs

    * underscore

    * jquery

    * import 'name'

    * import * as Mod from "mod"

    * import {name_1, ..., name_n} from "mod"

    * underscore patching

    * mousewheel

    * Remove duplicated Title

    * export {...}

    * Fix imports/exports in models/tiles

    * Adjust imports/exports

    * Split models/index.coffee and use exports

    * import {Model}

    * Use exports in core modules

    * Use exports in models/widgets

    * Use exports in api/

    * More exports from main.coffee

    * Integrate scripts:tsjs in to scripts:compile

    * Use default exports for templates

    * Use exports in main.coffee

    * Use exports in api.coffee

    * Export require in prelude, not in main

    * Don't show tsjs errors unless --tsjs option is used

    * Use exports in core/util/proj4

    * Set up scripts' build dependencies properly

    * Use window.Date() to avoid clash with exported Date

    * Use compiled *.js files for testing

    * Use proper this in pop_pending() in client.coffee

    * Use HasProps instead of HasProps.constructor

    * Fix imports in tests

    * Don't use file extensions in imports in tests

    * Use build/js/tree in proxy require magic

    * Add a polyfill for String.prototype.startsWith()

    * Fix imports of Model in custom model examples

    * Fix broken import in models/canvas/cartesian_frame

    * Add typings for all external libraries

    * Allow to skip selected scripts:tsjs errors

    * Add typings for kiwi

    * Update gulp-typescript to version 3.x

    * Don't compile *.ts files, just copy under tree_ts/

    This allows to compile all *.ts files (handwritten and generated)
    in one compiler run, allowing for proper module resolution, etc.

    * Rewrite api/palettes in TypeScript and fix exports

    * Increase size limit for bokeh-api bundle

    * Switch to direct model/view exports

    * Remove debugging code from gulp/tasks/scripts.coffee

    * Fix broken imports in webgl/{base,line} and tools/toolbar_base

    * Move compile.js build code to compiler:build

    * No need anymore for run-time Eco template compilation

    * Add support for TypeScript to compile.js

    * Use import/export in examples and documentation

    * Allow to use file extensions in custom module paths

    Now you can issue e.g. `import "./custom.less"`.

    * Add support for TypeScript to custom module compiler

    * Fix tests after adding TypeScript to compilation pipeline

    * Access default member by using ['default'] syntax

:040000 040000 8541bccdb203e2062faba1401e5304f106a4e1b2 84a96944fe50f4d3633be352beeccfed4609f3c0 M  bokeh
:040000 040000 ef8f45e4c0988ea4b44a58a2aa39e9f62442cb82 defe848efd3bb6f7fad9677a1ed56ce89188da65 M  bokehjs
:040000 040000 36f13b0ac4bbe15496b3873ee6f02fbe52f6a64f cad0a8cdad9d62c50cc77caf6594747b030cab5c M  examples
:040000 040000 f2d4047399d5c29cd837b9fe56544087f7a4a06c b364c8da71fba56e565fc47bc44c20b19eb0021d M  sphinx
```



Discussion:
Here is the Safari crash dump: 

https://gist.github.com/bryevdv/f227e4713122c32b2cf4ab5413af1cc1

Confirmed happening on another mac besides mine

currently http://bokeh.pydata.org/en/dev/docs/gallery/unemployment.html exhibits the problem easily

OK this seems to be related to the hover tool. If I turn the hover tool off immediately, there is no crash. Can pan, etc no problem. Turning hover tool back on and hovering over the plot causes a crash almost immediately. Ping @birdsarah can you confirm?

Agreed. Only on Safari. Turning off the hover no problem. Turning off the other tools and just hovering around a lot causes an error.

I don't have access to OSX, so can't help much.

I repushed original `5320_import_export` branch, so that this can be further bisected.

@mattpap thanks that's helpful I will try to do another bisection today. 

I can demonstrate the problem in https://github.com/bokeh/bokeh/commit/27a71e7f0e56e799134ac00a545d83471eb7d55f but have not been able to build or run other commits earlier than that 

I'm not having much luck with direct debugging of the hover tool on master either, If we can't figure this out I am afraid we are looking at the prospect of reverting everything up to this point. This makes Bokeh completely unusable on Safari. 

> I'm not having much luck with direct debugging of the hover tool

I'm almost certain that this issue has nothing to do with hover tool, just it makes the actual issue surface.

> we are looking at the prospect of reverting everything up to this point

This is not an option.

@bryevdv, how can I get my hands on Safari/OSX? Is VM an option?

If I can't figure this out this afternoon I will figure out how to get one sent to you. 

In case this nice you any ideas. 

It "works" with this diff (but accumulates an infinitely log tooltip div over time):

```
diff --git a/bokehjs/package.json b/bokehjs/package.json
index 764060c..66659f4 100644
--- a/bokehjs/src/coffee/models/annotations/tooltip.coffee
+++ b/bokehjs/src/coffee/models/annotations/tooltip.coffee
@@ -112,7 +112,7 @@ export class Tooltip extends Annotation
   }

   clear: () ->
-    @data = []
+    #@data = []

   add: (vx, vy, content) ->
     data = @data
```

But fails (crashes) with this diff

```
iff --git a/bokehjs/package.json b/bokehjs/package.json
index 764060c..0805c3b 100644
--- a/bokehjs/src/coffee/models/annotations/tooltip.coffee
+++ b/bokehjs/src/coffee/models/annotations/tooltip.coffee
@@ -22,6 +22,7 @@ export class TooltipView extends AnnotationView
     @_draw_tips()

   _draw_tips: () ->
+    return
     data = @model.data
     @$el.empty()
     @$el.hide()
```

That seems to indicate some problem in the event/callback handling. Tho why it only fails when `@data` is set to an empty list (an not when other content is updates) is a mystery

@mattpap this diff seems to "fix" the issue for real (no crashes, tooltip looks correct):

```
index 764060c..ef7f2ca 100644
--- a/bokehjs/src/coffee/models/annotations/tooltip.coffee
+++ b/bokehjs/src/coffee/models/annotations/tooltip.coffee
@@ -112,7 +112,11 @@ export class Tooltip extends Annotation
   }

   clear: () ->
-    @data = []
+    @data.splice(0, @data.length)
+
+    # TODO (bev) not sure why this is now necessary
+    @trigger('change:data')
+

   add: (vx, vy, content) ->
     data = @data
```

I think this narrows down things to something about the prop change detection and event triggering

FYI there is also an update to hammerjs available tho updating did not fix, we should probably bump for good measure. 

> `# TODO (bev) not sure why this is now necessary`

Because `@data.splice(0, @data.length)` is an in-place operation, so backbone can't detect such change and trigger appropriate events. Note also that just triggering `change:data` is insufficient to comply with with backbone's `set()` semantics.

@mattpap that's actually what I assumed (testing that was the point of the change), that was an old comment copied over from the other function

> I think this narrows down things to something about the prop change detection and event triggering

The thing is that the PR in consideration didn't change any of that. If we just proceed with this "fix", the problem will like reappear sooner than later. @bryevdv, can you step debug the original code starting at `@data = []`, so that we can see exactly which instruction blows up?

@mattpap agreed I am not suggesting this is a real fix, just some information to help figure things out. I'll check that after lunch. I am also getting some VMs to see if the problem is reproducible on a VM. 

This is making me despondent. I went through all of this:

https://blog.help.com/2015/12/08/debugging-safari-crashes/

and got no useful information. 

Possibly new info 

https://bugs.webkit.org/show_bug.cgi?id=164306

@mattpap the last comment in the webkit bug issue for this linked above seems to implicate the tail call optimization. Is there something that might have changed regarding compilation?

@mattpap more new info:

https://bugs.webkit.org/show_bug.cgi?id=164306#c4

Webkit devs have repro'd and identified the bug. Basically it boils down to having a tail call in a setter, and the suggestion for a workaround is to avoid that for now. 


Resolving patch:
diff --git a/bokeh/models/widgets/inputs.py b/bokeh/models/widgets/inputs.py
--- a/bokeh/models/widgets/inputs.py
+++ b/bokeh/models/widgets/inputs.py
@@ -43,7 +43,7 @@ class TextInput(InputWidget):
     A callback to run in the browser whenever the user unfocuses the TextInput
     widget by hitting Enter or clicking outside of the text box area.
     """)
-    
+
     placeholder = String(default="", help="""
     Placeholder for empty input field
     """)


Test patch: