summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-06-28 19:22:00 -0400
committerJoe Crayne <joe@jerkface.net>2018-06-28 19:23:14 -0400
commit8b817ae44034b5a0740df369c002e8953a530840 (patch)
treeb8b8bac5d75d3421b22d861b8c95d8394e6eeebb
parent8ff122d2d381fc9b1dd5c16067fba19f89512261 (diff)
More performant pendingRoutes (IntMap -> Array).
-rw-r--r--OnionRouter.hs32
-rw-r--r--examples/dhtd.hs4
-rw-r--r--src/Network/Tox/Onion/Transport.hs9
3 files changed, 23 insertions, 22 deletions
diff --git a/OnionRouter.hs b/OnionRouter.hs
index e3c32fbe..b11a0bf6 100644
--- a/OnionRouter.hs
+++ b/OnionRouter.hs
@@ -72,7 +72,7 @@ data OnionRouter = OnionRouter
72 -- | Each of the 12 routes has a version number here that is set larger 72 -- | Each of the 12 routes has a version number here that is set larger
73 -- than the 'routeVersion' set in 'routeMap' when the route should be 73 -- than the 'routeVersion' set in 'routeMap' when the route should be
74 -- discarded and replaced with a fresh one. 74 -- discarded and replaced with a fresh one.
75 , pendingRoutes :: IntMap (TVar Int) 75 , pendingRoutes :: TArray Int Int
76 -- | Debug prints are written to this channel which is then flushed to 76 -- | Debug prints are written to this channel which is then flushed to
77 -- 'routeLogger'. 77 -- 'routeLogger'.
78 , routeLog :: TChan String 78 , routeLog :: TChan String
@@ -134,7 +134,7 @@ gotTimeout rr = rr
134 { timeoutCount = succ $ timeoutCount rr 134 { timeoutCount = succ $ timeoutCount rr
135 } 135 }
136 136
137data RouteEvent = BuildRoute RouteId 137newtype RouteEvent = BuildRoute RouteId
138 138
139newOnionRouter :: (String -> IO ()) -> IO OnionRouter 139newOnionRouter :: (String -> IO ()) -> IO OnionRouter
140newOnionRouter perror = do 140newOnionRouter perror = do
@@ -148,10 +148,10 @@ newOnionRouter perror = do
148 tn <- newTVar IntMap.empty 148 tn <- newTVar IntMap.empty
149 ti <- newTVar HashMap.empty 149 ti <- newTVar HashMap.empty
150 tc <- newTVar 0 150 tc <- newTVar 0
151 vs <- sequence $ replicate 12 (newTVar 0) 151 pr <- newArray (0,11) 0
152 rlog <- newTChan 152 rlog <- newTChan
153 return OnionRouter 153 return OnionRouter
154 { pendingRoutes = IntMap.fromList $ zip [0..11] vs 154 { pendingRoutes = pr
155 , onionDRG = drg 155 , onionDRG = drg
156 , pendingQueries = pq 156 , pendingQueries = pq
157 , routeMap = rm 157 , routeMap = rm
@@ -170,17 +170,19 @@ forkRouteBuilder or getnodes = do
170 me <- myThreadId 170 me <- myThreadId
171 labelThread me "OnionRouter" 171 labelThread me "OnionRouter"
172 forever $ do 172 forever $ do
173 let checkRebuild rid want_build stm = flip orElse stm $ do 173 let checkRebuild :: Int -> Int -> STM RouteEvent
174 wanted_ver <- readTVar want_build 174 checkRebuild rid wanted_ver = do
175 current_ver <- fmap routeVersion <$> readArray (routeMap or) rid 175 current_ver <- fmap routeVersion <$> readArray (routeMap or) rid
176 writeTChan (routeLog or) $ "ONION checkRebuild "++show(current_ver,wanted_ver) 176 writeTChan (routeLog or) $ "ONION checkRebuild "++show(current_ver,wanted_ver)
177 check $ maybe True (< wanted_ver) current_ver 177 check $ maybe True (< wanted_ver) current_ver
178 return $ BuildRoute $ RouteId rid 178 return $ BuildRoute $ RouteId rid
179 io <- atomically $ 179 io <- atomically $ {-# SCC "forkRouteBuilder.log" #-}
180 (readTChan (routeLog or) >>= return . routeLogger or) 180 (readTChan (routeLog or) >>= return . routeLogger or)
181 `orElse` 181 `orElse` {-# SCC "forkRouteBuilder.checkRebuild" #-}
182 (IntMap.foldrWithKey checkRebuild retry (pendingRoutes or) 182 (let stms = map (\rid -> checkRebuild rid =<< readArray (pendingRoutes or) rid)
183 >>= return . handleEvent getnodes or { routeThread = me }) 183 [0..11]
184 in do event <- foldr1 orElse stms
185 return $ handleEvent getnodes or { routeThread = me } event)
184 io 186 io
185 return or { routeThread = tid } 187 return or { routeThread = tid }
186 188
@@ -240,7 +242,9 @@ selectTrampolines or = do
240 routeLogger or $ unwords 242 routeLogger or $ unwords
241 ( "ONION Discarding insecure trampolines:" : (map (show . nodeAddr) ns) ) 243 ( "ONION Discarding insecure trampolines:" : (map (show . nodeAddr) ns) )
242 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep") 244 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep")
243 threadDelay 1000000 245 case ns of
246 [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate.
247 _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes.
244 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") 248 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines")
245 selectTrampolines or 249 selectTrampolines or
246 Right ns -> do 250 Right ns -> do
@@ -347,7 +351,7 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do
347 (freshRoute now r) 351 (freshRoute now r)
348 rid 352 rid
349 v <- routeVersion . fromJust <$> readArray (routeMap or) rid 353 v <- routeVersion . fromJust <$> readArray (routeMap or) rid
350 writeTVar (pendingRoutes or IntMap.! rid) v 354 writeArray (pendingRoutes or) rid v
351 ) 355 )
352 mb 356 mb
353 case mb of 357 case mb of
@@ -390,7 +394,7 @@ hookQueries or t8 tmethods = TransactionMethods
390 { dispatchRegister = \mvar od d -> {-# SCC "hookQ.dispatchRegister" #-} do -- :: MVar x -> d -> STM (tid, d) 394 { dispatchRegister = \mvar od d -> {-# SCC "hookQ.dispatchRegister" #-} do -- :: MVar x -> d -> STM (tid, d)
391 let ni = onionNodeInfo od 395 let ni = onionNodeInfo od
392 rid@(RouteId ridn) = fromMaybe (routeId (nodeId ni)) $ onionRouteSpec od 396 rid@(RouteId ridn) = fromMaybe (routeId (nodeId ni)) $ onionRouteSpec od
393 wanted <- {-# SCC "hookQ.wanted" #-} (readTVar (pendingRoutes or IntMap.! ridn)) 397 wanted <- {-# SCC "hookQ.wanted" #-} (readArray (pendingRoutes or) ridn)
394 mr <- {-# SCC "hookQ.mr_action" #-} (readArray (routeMap or) ridn) 398 mr <- {-# SCC "hookQ.mr_action" #-} (readArray (routeMap or) ridn)
395 -- Block query until a route is ready. 399 -- Block query until a route is ready.
396 check $ fromMaybe False $ do 400 check $ fromMaybe False $ do
@@ -431,7 +435,7 @@ hookQueries or t8 tmethods = TransactionMethods
431 mrr <- readArray (routeMap or) rid 435 mrr <- readArray (routeMap or) rid
432 forM_ mrr $ \rr -> do 436 forM_ mrr $ \rr -> do
433 when (routeVersion rr == pendingVersion pq) $ do 437 when (routeVersion rr == pendingVersion pq) $ do
434 let expireRoute = modifyTVar' (pendingRoutes or IntMap.! rid) expire 438 let expireRoute = modifyArray (pendingRoutes or) expire rid
435 expire ver | ver <= succ (pendingVersion pq) = succ (pendingVersion pq) 439 expire ver | ver <= succ (pendingVersion pq) = succ (pendingVersion pq)
436 | otherwise = ver 440 | otherwise = ver
437 modifyArray (routeMap or) (fmap gotTimeout) rid 441 modifyArray (routeMap or) (fmap gotTimeout) rid
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index 8e9e7692..7ed77d3a 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -935,7 +935,7 @@ clientSession s@Session{..} sock cnum h = do
935 ts <- readTVar $ trampolineNodes onionRouter 935 ts <- readTVar $ trampolineNodes onionRouter
936 tcnt <- readTVar $ trampolineCount onionRouter 936 tcnt <- readTVar $ trampolineCount onionRouter
937 icnt <- HashMap.size <$> readTVar (trampolineIds onionRouter) 937 icnt <- HashMap.size <$> readTVar (trampolineIds onionRouter)
938 rs <- mapM readTVar (pendingRoutes onionRouter) 938 rs <- getAssocs (pendingRoutes onionRouter)
939 pqs <- readTVar (pendingQueries onionRouter) 939 pqs <- readTVar (pendingQueries onionRouter)
940 let showRecord :: Int -> Int -> [String] 940 let showRecord :: Int -> Int -> [String]
941 showRecord n wanted_ver 941 showRecord n wanted_ver
@@ -945,7 +945,7 @@ clientSession s@Session{..} sock cnum h = do
945 then show routeVersion 945 then show routeVersion
946 else show routeVersion ++ "(pending)" ] 946 else show routeVersion ++ "(pending)" ]
947 | otherwise = [show n, "error!","","",""] 947 | otherwise = [show n, "error!","","",""]
948 r = map (uncurry showRecord) $ IntMap.toAscList rs 948 r = map (uncurry showRecord) rs
949 return $ do 949 return $ do
950 hPutClientChunk h $ unlines [ "trampolines: " ++ show (IntMap.size ts,tcnt,icnt) 950 hPutClientChunk h $ unlines [ "trampolines: " ++ show (IntMap.size ts,tcnt,icnt)
951 , "pending: " ++ show (W64.size pqs) ] 951 , "pending: " ++ show (W64.size pqs) ]
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index e2e136ae..7ed9702a 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -250,12 +250,9 @@ encodeOnionAddr crypto getRoute (msg,OnionDestination _ ni (Just rid)) = do
250 req <- wrapForRoute crypto msg ni route 250 req <- wrapForRoute crypto msg ni route
251 return ( runPut $ putRequest req 251 return ( runPut $ putRequest req
252 , nodeAddr $ routeNodeA route) 252 , nodeAddr $ routeNodeA route)
253 mapM' f x = do 253 m <- {-# SCC "encodeOnionAddr.getRoute" #-} getRoute ni rid
254 let _ = x :: Maybe OnionRoute 254 x <- {-# SCC "encodeOnionAddr.wrapForRoute" #-} mapM go m
255 -- dput XMisc $ "ONION encode sending to " ++ show ni 255 return x
256 -- dput XMisc $ "ONION encode getRoute -> " ++ show (fmap (\y -> map ($ y) [routeNodeA,routeNodeB,routeNodeC]) x)
257 mapM f x -- ONION encode getRoute -> Nothing
258 getRoute ni rid >>= mapM' go
259 256
260 257
261forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport 258forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport