Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

World age failure when running GtkReactive demo #21141

Closed
timholy opened this issue Mar 23, 2017 · 7 comments · Fixed by #20820 or #21307
Closed

World age failure when running GtkReactive demo #21141

timholy opened this issue Mar 23, 2017 · 7 comments · Fixed by #20820 or #21307

Comments

@timholy
Copy link
Sponsor Member

timholy commented Mar 23, 2017

When running the examples/drawing.jl demo under

julia> versioninfo()
Julia Version 0.6.0-pre.alpha.229
Commit cc917b5 (2017-03-22 21:53 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, broadwell)

and if GtkReactive needs to be rebuilt, I get the following error when I click on the canvas:

julia> include("drawing.jl")
INFO: Recompiling stale cache file /home/tim/.julia/lib/v0.6/GtkReactive.ji for module GtkReactive.
Gtk.GtkWindowLeaf(name="", parent, width-request=-1, height-request=-1, visible=TRUE, sensitive=TRUE, app-paintable=FALSE, can-focus=FALSE, has-focus=FALSE, is-focus=FALSE, can-default=FALSE, has-default=FALSE, receives-default=FALSE, composite-child=FALSE, style, events=0, no-show-all=FALSE, has-tooltip=FALSE, tooltip-markup=NULL, tooltip-text=NULL, window, opacity=1.000000, double-buffered, halign=GTK_ALIGN_FILL, valign=GTK_ALIGN_FILL, margin-left, margin-right, margin-start=0, margin-end=0, margin-top=0, margin-bottom=0, margin=0, hexpand=FALSE, vexpand=FALSE, hexpand-set=FALSE, vexpand-set=FALSE, expand=FALSE, scale-factor=1, border-width=0, resize-mode, child, type=GTK_WINDOW_TOPLEVEL, title="Drawing", role=NULL, resizable=TRUE, modal=FALSE, window-position=GTK_WIN_POS_NONE, default-width=-1, default-height=-1, destroy-with-parent=FALSE, hide-titlebar-when-maximized=FALSE, icon, icon-name=NULL, screen, type-hint=GDK_WINDOW_TYPE_HINT_NORMAL, skip-taskbar-hint=FALSE, skip-pager-hint=FALSE, urgency-hint=FALSE, accept-focus=TRUE, focus-on-map=TRUE, decorated=TRUE, deletable=TRUE, gravity=GDK_GRAVITY_NORTH_WEST, transient-for, attached-to, has-resize-grip, resize-grip-visible, application, is-active=TRUE, has-toplevel-focus=TRUE, startup-id, mnemonics-visible=FALSE, focus-visible=FALSE, is-maximized=FALSE)

julia> Failed to push!
    GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(0.208377685546875), GtkReactive.UserUnit(0.3292300415039063)), 0x00000001, 4, 0)
to node
    Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}(GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(0.208377685546875), GtkReactive.UserUnit(0.3292300415039063)), 0x00000001, 4, 0), nactions=1)
MethodError: no method matching (::##3#4)(::GtkReactive.MouseButton{GtkReactive.UserUnit})
The applicable method may be too new: running in world age 21622, while current world is 21627.
Closest candidates are:
  #3(::Any) at /home/tim/.julia/v0.6/GtkReactive/examples/drawing.jl:13 (method too new to be called from this world context.)
(::Reactive.##10#11{##3#4,Tuple{Reactive.Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}}})(::Reactive.Signal{Void}, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/operators.jl:39
do_action(::Reactive.Action, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:141
run(::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:218
macro expansion at /home/tim/.julia/v0.6/Reactive/src/core.jl:258 [inlined]
(::Reactive.##7#8)() at ./task.jl:335
Failed to push!
    GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(0.1935784912109375), GtkReactive.UserUnit(0.7561200714111328)), 0x00000001, 7, 256)
to node
    Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}(GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(0.1935784912109375), GtkReactive.UserUnit(0.7561200714111328)), 0x00000001, 7, 256), nactions=1)
MethodError: no method matching (::##7#8)(::GtkReactive.MouseButton{GtkReactive.UserUnit})
The applicable method may be too new: running in world age 21622, while current world is 21627.
Closest candidates are:
  #7(::Any) at /home/tim/.julia/v0.6/GtkReactive/examples/drawing.jl:25 (method too new to be called from this world context.)
(::Reactive.##10#11{##7#8,Tuple{Reactive.Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}}})(::Reactive.Signal{Void}, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/operators.jl:39
do_action(::Reactive.Action, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:141
run(::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:218
macro expansion at /home/tim/.julia/v0.6/Reactive/src/core.jl:258 [inlined]
(::Reactive.##7#8)() at ./task.jl:335

However, it seems to work fine if GtkReactive didn't need to be recompiled.

For you convenience I did a egrep "pure|generated|eval" * in every package that gets loaded for that demo, looking for language constructs that might be suspicious; results are in this gist.

@timholy
Copy link
Sponsor Member Author

timholy commented Mar 23, 2017

There turns out to be a more reliable failure: run the widgets.jl demo instead, and click on the "make window visible" checkbox. It's failed every time I've tried, independent of recompilation.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 4, 2017

for Reactive, I assume it'll want to do something like a more correct version of (like calling apply_latest): (or maybe just starting the event loop later?)

diff --git a/src/operators.jl b/src/operators.jl
index e344b82..2b617e3 100644
--- a/src/operators.jl
+++ b/src/operators.jl
@@ -36,7 +36,7 @@ function connect_map(f, output, inputs...)
         for inp in inputs
             add_action!(inp, output) do output, timestep
                 if prev_timestep != timestep
-                    result = f(map(value, inputs)...)
+                    result = eval(:($f($map($value, $inputs)...)))
                     send_value!(output, result, timestep)
                     prev_timestep = timestep
                 end

Looks like the underlying cause is probably a race-condition between restoring backedges and invalidating them during deserialization.

@timholy
Copy link
Sponsor Member Author

timholy commented Apr 4, 2017

Just to make sure I understand, you're saying it's only an issue because of the asynchronous nature of Reactive? And that by putting it inside an eval we're effectively deferring the operations that have to be performed by f? The part I don't understand is that the map call should run once synchronously to provide an initial value, so I'd think all compilation would be done by the time the user clicks the checkbox.

I'm not finding an apply_latest, I assume this is TBD?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 4, 2017

The part that I changed is inside the action closure callback, so it doesn't run until the checkbox is clicked. The race condition means that it sometimes gets confused about which method it should be running, depending on the order in which recompilation was happening (e.g. the compilecache code is causing required re-inference of some functions which we also use again later, and which alters the cache state by the time we get to loading more code). See #19784

@timholy
Copy link
Sponsor Member Author

timholy commented Apr 6, 2017

Hmm, on 5cacdd6 the following:

using GtkReactive, Gtk.ShortNames
using Base.Test

try
    Reactive.stop()
catch
end

rr() = (Reactive.run_till_now(); yield())

rr()
win = Window() |> (c = canvas(UserUnit))
showall(win)
sleep(0.1)
lastevent = Ref("nothing")
motion  = map(btn->lastevent[] = string("motion to ", btn.position.x, ", ", btn.position.y),
              c.mouse.motion)

still triggers the following errors when I mouse over the window:

julia> include("reduced.jl")
Signal{String}(motion to GtkReactive.UserUnit(-1.0), GtkReactive.UserUnit(-1.0), nactions=0)

julia> Failed to push!
    GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(28.6624755859375), GtkReactive.UserUnit(10.3670654296875)), 0x00000000, 3, 0, nothing)
to node
    Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}(GtkReactive.MouseButton{GtkReactive.UserUnit}(GtkReactive.XY{GtkReactive.UserUnit}(GtkReactive.UserUnit(28.6624755859375), GtkReactive.UserUnit(10.3670654296875)), 0x00000000, 3, 0, nothing), nactions=1)
MethodError: no method matching (::##3#4)(::GtkReactive.MouseButton{GtkReactive.UserUnit})
The applicable method may be too new: running in world age 21654, while current world is 21655.                                                                                              
Closest candidates are:
  #3(::Any) at /home/tim/.julia/v0.6/GtkReactive/test/reduced.jl:16 (method too new to be called from this world context.)
(::Reactive.##10#11{##3#4,Tuple{Reactive.Signal{GtkReactive.MouseButton{GtkReactive.UserUnit}}}})(::Reactive.Signal{String}, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/operators.jl:39
do_action(::Reactive.Action, ::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:141
run(::Int64) at /home/tim/.julia/v0.6/Reactive/src/core.jl:218
macro expansion at /home/tim/.julia/v0.6/Reactive/src/core.jl:258 [inlined]
(::Reactive.##7#8)() at ./task.jl:335
...

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 6, 2017

AFAICT, this is doing exactly what it was asked to do. The only bug here was that it would then segfault afterwards.

@timholy
Copy link
Sponsor Member Author

timholy commented Apr 6, 2017

I misunderstood. You're saying we still need the Reactive change? Is there an apply_latest on the horizon?

vtjnash added a commit that referenced this issue Apr 6, 2017
…ation

we need to restore not only backedges directly to the new methods,
but also to any methods whos backedges have not been inferred
but which might propagate invalidation changes to the new code

fix #21141
vtjnash added a commit that referenced this issue Apr 7, 2017
…ation

we need to restore not only backedges directly to the new methods,
but also to any methods whos backedges have not been inferred
but which might propagate invalidation changes to the new code

fix #21141
vtjnash added a commit that referenced this issue Apr 10, 2017
…ation

we need to restore not only backedges directly to the new methods,
but also to any methods whos backedges have not been inferred
but which might propagate invalidation changes to the new code

fix #21141
vtjnash added a commit that referenced this issue Apr 11, 2017
…ation

we need to restore not only backedges directly to the new methods,
but also to any methods whos backedges have not been inferred
but which might propagate invalidation changes to the new code

fix #21141
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants