@@ -101,8 +101,6 @@ import Reflex.NotReady.Class
101import Reflex.Patch
101import Reflex.Patch
102import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
102import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
106#ifdef DEBUG_TRACE_EVENTS
104#ifdef DEBUG_TRACE_EVENTS
107import qualified Data.ByteString.Char8 as BS8
105import qualified Data.ByteString.Char8 as BS8
108import System.IO (stderr)
106import System.IO (stderr)
@@ -1322,12 +1320,17 @@ traceM _ _ = return ()
1327whoCreatedIORef :: IORef a -> IO [String]
1323whoCreatedIORef :: IORef a -> IO [String]
1328whoCreatedIORef (IORef a) = whoCreated $! a
1324whoCreatedIORef (IORef a) = whoCreated $! a
1330#ifdef DEBUG_CYCLES
1326#ifdef DEBUG_CYCLES
1328+data EventLoopException = EventLoopException (Forest String)
1329+instance Exception EventLoopException
1331+instance Show EventLoopException where
1332+ show (EventLoopException stacks) = "Causality loop detected:\n" <> drawForest stacks
1331groupByHead :: Eq a => [NonEmpty a] -> [(a, NonEmpty [a])]
1334groupByHead :: Eq a => [NonEmpty a] -> [(a, NonEmpty [a])]
1332groupByHead = \case
1335groupByHead = \case
1333 [] -> []
1336 [] -> []
@@ -1339,8 +1342,19 @@ groupByHead = \case
1340listsToForest :: Eq a => [[a]] -> Forest a
1343listsToForest :: Eq a => [[a]] -> Forest a
1341listsToForest l = fmap (\(a, l') -> Node a $ listsToForest $ toList l') $ groupByHead $ catMaybes $ fmap nonEmpty l
1344listsToForest l = fmap (\(a, l') -> Node a $ listsToForest $ toList l') $ groupByHead $ catMaybes $ fmap nonEmpty l
1348+data EventLoopException = EventLoopException
1349+instance Exception EventLoopException
1351+instance Show EventLoopException where
1352+ show EventLoopException = "Causality loop detected: \n" <>
1353+ "no location information, compile with --enable-profiling and reflex with flag 'debug-cycles'"
1344{-# INLINE propagateSubscriberHold #-}
1358{-# INLINE propagateSubscriberHold #-}
1345propagateSubscriberHold :: forall x p. (HasSpiderTimeline x, Patch p) => Hold x p -> p -> EventM x ()
1359propagateSubscriberHold :: forall x p. (HasSpiderTimeline x, Patch p) => Hold x p -> p -> EventM x ()
1346propagateSubscriberHold h a = do
1360propagateSubscriberHold h a = do
@@ -1871,11 +1885,11 @@ checkCycle height = do
1871#ifdef DEBUG_CYCLES
1885#ifdef DEBUG_CYCLES
1872 nodesInvolvedInCycle <- walkInvalidHeightParents $ eventSubscribedMerge subscribed
1886 nodesInvolvedInCycle <- walkInvalidHeightParents $ eventSubscribedMerge subscribed
1873 stacks <- forM nodesInvolvedInCycle $ \(Some es) -> whoCreatedEventSubscribed es
1887 stacks <- forM nodesInvolvedInCycle $ \(Some es) -> whoCreatedEventSubscribed es
1874− let cycleInfo = ":\n" <> drawForest (listsToForest stacks)
1888+ throwIO (EventLoopException stacks)
1876− let cycleInfo = ""
1890+ throwIO EventLoopException
1878− error $ "Causality loop found" <> cycleInfo
1892+
1880mergeSubscriber :: forall x k v s a. (HasSpiderTimeline x, GCompare k) => Merge x k v s -> EventM x (k a) -> Subscriber x (v a)
1894mergeSubscriber :: forall x k v s a. (HasSpiderTimeline x, GCompare k) => Merge x k v s -> EventM x (k a) -> Subscriber x (v a)
1881mergeSubscriber m getKey = Subscriber
1895mergeSubscriber m getKey = Subscriber