-
Notifications
You must be signed in to change notification settings - Fork 29
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
make it work with reactive-banana again #25
base: master
Are you sure you want to change the base?
Conversation
7031380
to
f478659
Compare
The Can you make sure that the test cases I think you did spot an issue with the condition for pushing weaks to the Can you point me to the code that gets you a |
Hi @luite! Thanks for the explaination and yes on the the testcases! Found the reason for the killed thread and it totaly makes sense: The action which I call from my I added a On the semantics at the tobstoning:
Entering step 4 we have all those weak pointers left in the (old) Btw i still think that the explicit marking of all pointers in the new After the GC is complelty done, it will returned. The application code might sill have a valid reference to the weak pointer object it self, but can't actually do anything with it anymore. but as long it has a reference, the backing object in the js world will continue to live. So to put it back in the context of the definition i understand it like this (I added things in bold to make my point how I understand the semantics): Scan the Weak Pointer List again. Please correct me if I'am wrong with that. |
You removed marking all Unreachable weak refs don't need to be tombstoned, since they are dead anyway, but it doesn't really hurt to still do so. The key to replicating GHC's semantics is to keep the values of weak references alive if their key is reachable, regardless of whether the weak reference. The bold text doesn't appear in the paper (or at least the version I have), and it doesn't make sense given the semantics specified in the paper. Reachability of the weak object can't be in the condition for moving the weak object to the finalization pending list: If the weak object would just be discarded if it's unreachable, then its finalizer would never be run. This contradicts the earlier assertion that all finalizers are run exactly once during the execution of the program (this is true by approximation in GHCJS, and i suspect in GHC as well: early terminaton of the RTS may prevent some finalizers to be run. Perhaps GHCJS should do a bit more in this area and let the |
the |
f478659
to
cef0064
Compare
do you have a simpe (terminal) reactive-banana program that fails? |
As far as I know, |
@luite @HeinrichApfelmus still have problems with my code but I was not yet able to cook it down to a small test, which reproduces that. The efect is still the same, when the gc hits the first time the reactive code stops working. What I'am basicly doing is:
My current theory is, but as I said I wasn't able to reproduce yet, that stil something in the garbage collection is "wrong" and that something between the DOM event handler and the reactive-banana Event (fire function) is beeing garbage collected (esp. with ghcjs-dom beeing a "foreign" library). But i will further investigate. Btw. actualy the patch behind this pull request still makes it work again, but there is obviously a memory leak then (found my firefox on macos with a virtual memory of 12G after developing a whole day on the project ;)) |
For these things it's important that you retain and release callbacks for the event handlers properly (for which there is unfortunately no convenient automatic way in JS). There could well be something wrong with the retention/scanning code related to those. I'm working on callbacks and the low level thread API today and I'll test this if I have time. |
I keep the the cleanup handlers in a big list i produce using a Writer Monad, so they should at least be somewhat referenced from my main. I also keep an pointer to the DOM Elements (although they are inserterted to the dom). But maybe you find something there. thnx! |
Are you sure these values are live in the main thread? The can easily be dead if the thread has already stopped or never uses them anymore (for example if you just have it looping). Anyway that looks like it's going to be a bit too much guesswork. I'm going to add more testcases for callbacks etc so I might accidentally run into the problem, but otherwise i'm going to need a reasonably simple way to reproduce the problem before i can fix it. |
I've come across a weird bug and I wonder if it's related to this. Check out this program: {-# LANGUAGE OverloadedStrings #-}
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class
import GHCJS.Types
import GHCJS.DOM
import GHCJS.DOM.Element as Element
import GHCJS.DOM.Node as Node
import GHCJS.DOM.Document as Document
import GHCJS.DOM.EventM
import Reactive.Banana.Combinators
import Reactive.Banana.Frameworks
import Debug.Trace
main = runWebGUI $ \webView -> do
Just document <- webViewGetDomDocument webView
Just body <- getBody document
let networkDescription :: MomentIO ()
networkDescription = do
Just div <- document `createElement` (Just ("div" :: JSString))
Just textInput <- document `createElement` (Just ("input" :: JSString))
div `appendChild` (Just textInput)
body `appendChild` (Just div)
(clicks, fireClick) <- newEvent
liftIO $ on div Element.click $ do
eventData <- ask
liftIO $ fireClick eventData
-- Remove any one of these reactimates and it's all good.
reactimate (undefined <$> never)
reactimate (undefined <$> never)
reactimate (undefined <$> never)
reactimate (undefined <$> never)
reactimate ((\_ -> trace "Click" (return ())) <$> clicks)
return ()
network <- compile networkDescription
actuate network
return () Running this, you'll see an input box. Clicking on it should print "Click", and it always does at least once. If you click very quickly, you may get 3 or 4 prints, but then it stops working. It seems there's something special about 5 reactimates; removing any one of the useless reactimates in that block of 4 gives the expected behaviour: clicking always prints "Click".
Addendum: I flipped on -DGHCJS_TRACE_WEAK. I find that, with 4 reactimates, nothing is ever finalized. With 5, after the first click, 40 weak pointers are finalized, and then the click output stops. Addendum 2: this branch actually does seem to fix it :) I did a ghcjs-boot pointing to this branch but I didn't verify that the |
I have exactly the same problem, and this pull request fixes it. Not sure if it is related, but the change in ghcjs/ghcjs#450 alone does not fix the problem. So I have applied both changes to my local version of the file. I see there have been no conversation in this thread since Dec 2015. Are there any obstacles against this PR? |
I closed the PR because at least the first version got rid of all finalization, so it didn't really fix the problem but replace it with a different one that is somewhat harder to spot (memory leak). There have been a few small fixes wrt traversal of some heap objects (small arrays and some specific closure variables). Are you running the latest version of the master branch? If you still have a problem, can you make a small program that demonstrates it. Ideally without any dependencies outside what |
Thanks, @luite ! |
Hi @luite!
With this patch I made reactive-banana work again. It didn't actually include your very recent thread related patch, as they produce "a uncaught excpetion: Thread aborted" on startup of my application.
But with this small patch my reactive banana code works again without any problems.