diff options
author | joe <joe@jerkface.net> | 2017-11-08 01:02:26 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-11-08 02:30:43 -0500 |
commit | 8e1aad3e0abaacd11e5e95dbd21400ad06c88375 (patch) | |
tree | 9c09d0b5b6b01db96aaf090c931f182520cbfcae /src | |
parent | f7526e5dee6543404bedd1a13829305c9a107f15 (diff) |
Updated touchBucket for 15-second bootstrapping interval.
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/Kademlia/Bootstrap.hs | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/src/Network/Kademlia/Bootstrap.hs b/src/Network/Kademlia/Bootstrap.hs index f160000d..8ca0bb83 100644 --- a/src/Network/Kademlia/Bootstrap.hs +++ b/src/Network/Kademlia/Bootstrap.hs | |||
@@ -189,6 +189,48 @@ checkBucketFull space var resultCounter fin n found_node = do | |||
189 | _ | Set.size resultCount < fullcount -> True -- we haven't got many results, keep going | 189 | _ | Set.size resultCount < fullcount -> True -- we haven't got many results, keep going |
190 | _ -> False -- okay, good enough, let's quit. | 190 | _ -> False -- okay, good enough, let's quit. |
191 | 191 | ||
192 | -- | Called from 'refreshBucket' with the current time when a refresh of the | ||
193 | -- supplied bucket number finishes. | ||
194 | onFinishedRefresh :: BucketRefresher nid ni -> Int -> POSIXTime -> STM (IO ()) | ||
195 | onFinishedRefresh BucketRefresher { bootstrapCountdown | ||
196 | , bootstrapMode | ||
197 | , refreshQueue | ||
198 | , refreshBuckets } num now = do | ||
199 | bootstrapping <- readTVar bootstrapMode | ||
200 | if not bootstrapping then return $ hPutStrLn stderr $ "Finished non-boostrapping refresh: "++show num | ||
201 | else do | ||
202 | tbl <- readTVar refreshBuckets | ||
203 | action <- | ||
204 | if num /= R.bktCount tbl - 1 | ||
205 | then do modifyTVar' bootstrapCountdown (fmap pred) | ||
206 | return $ hPutStrLn stderr $ "BOOTSTRAP decrement" | ||
207 | else do | ||
208 | -- The last bucket finished. | ||
209 | cnt <- readTVar bootstrapCountdown | ||
210 | case cnt of | ||
211 | Nothing -> do | ||
212 | let fullsize = R.defaultBucketSize | ||
213 | notfull (n,len) | n==num = False | ||
214 | | len>=fullsize = False | ||
215 | | otherwise = True | ||
216 | unfull = case filter notfull $ zip [0..] (R.shape tbl) of | ||
217 | [] -> [(0,0)] -- Schedule at least 1 more refresh. | ||
218 | xs -> xs | ||
219 | forM_ unfull $ \(n,_) -> do | ||
220 | -- Schedule immediate refresh for unfull buckets (other than this one). | ||
221 | modifyTVar' refreshQueue $ Int.insert n (now - 1) | ||
222 | writeTVar bootstrapCountdown $! Just $! length unfull | ||
223 | return $ hPutStrLn stderr $ "BOOTSTRAP scheduling: "++show unfull | ||
224 | Just n -> do writeTVar bootstrapCountdown $! Just $! pred n | ||
225 | return $ hPutStrLn stderr "BOOTSTRAP decrement (last bucket)" | ||
226 | cnt <- readTVar bootstrapCountdown | ||
227 | if (cnt == Just 0) | ||
228 | then do | ||
229 | -- Boostrap finished! | ||
230 | writeTVar bootstrapMode False | ||
231 | writeTVar bootstrapCountdown Nothing | ||
232 | return $ do action ; hPutStrLn stderr $ "BOOTSTRAP complete (" ++ show num ++ ")." | ||
233 | else return $ do action ; hPutStrLn stderr $ "BOOTSTRAP progress " ++ show (num,R.bktCount tbl,cnt) | ||
192 | 234 | ||
193 | refreshBucket :: (Show nid, Ord ni, Ord nid, Hashable nid, Hashable ni) => | 235 | refreshBucket :: (Show nid, Ord ni, Ord nid, Hashable nid, Hashable ni) => |
194 | BucketRefresher nid ni -> Int -> IO Int | 236 | BucketRefresher nid ni -> Int -> IO Int |
@@ -217,6 +259,8 @@ refreshBucket r@BucketRefresher{ refreshSearch = sch | |||
217 | atomically $ searchIsFinished s >>= check | 259 | atomically $ searchIsFinished s >>= check |
218 | atomically $ searchCancel s | 260 | atomically $ searchCancel s |
219 | hPutStrLn stderr $ "Finish refresh " ++ show (n,sample) | 261 | hPutStrLn stderr $ "Finish refresh " ++ show (n,sample) |
262 | now <- getPOSIXTime | ||
263 | join $ atomically $ onFinishedRefresh r n now | ||
220 | rcount <- atomically $ do | 264 | rcount <- atomically $ do |
221 | c <- Set.size <$> readTVar resultCounter | 265 | c <- Set.size <$> readTVar resultCounter |
222 | b <- readTVar fin | 266 | b <- readTVar fin |
@@ -336,21 +380,30 @@ effectiveRefreshInterval BucketRefresher{ refreshInterval | |||
336 | -- | 380 | -- |
337 | -- We embed the result in the STM monad but currently, no STM state changes | 381 | -- We embed the result in the STM monad but currently, no STM state changes |
338 | -- occur until the returned IO action is invoked. TODO: simplify? | 382 | -- occur until the returned IO action is invoked. TODO: simplify? |
339 | touchBucket :: BucketRefresher nid ni | 383 | touchBucket :: SensibleNodeId nid ni |
384 | => BucketRefresher nid ni | ||
340 | -> RoutingTransition ni -- ^ What happened to the bucket? | 385 | -> RoutingTransition ni -- ^ What happened to the bucket? |
341 | -> STM (IO ()) | 386 | -> STM (IO ()) |
342 | touchBucket BucketRefresher{ refreshSearch | 387 | touchBucket r@BucketRefresher{ refreshSearch |
343 | , refreshInterval | 388 | , refreshInterval |
344 | , refreshBuckets | 389 | , refreshBuckets |
345 | , refreshQueue } | 390 | , refreshQueue |
391 | , refreshLastTouch | ||
392 | , bootstrapMode | ||
393 | , bootstrapCountdown } | ||
346 | RoutingTransition{ transitionedTo | 394 | RoutingTransition{ transitionedTo |
347 | , transitioningNode } | 395 | , transitioningNode } |
348 | = case transitionedTo of | 396 | = case transitionedTo of |
349 | Applicant -> return $ return () -- Ignore transition to applicant. | 397 | Applicant -> return $ return () -- Ignore transition to applicant. |
350 | _ -> return $ do -- Reschedule for any other transition. | 398 | _ -> return $ do -- Reschedule for any other transition. |
351 | now <- getPOSIXTime | 399 | now <- getPOSIXTime |
352 | atomically $ do | 400 | join $ atomically $ do |
353 | let space = searchSpace refreshSearch | 401 | let space = searchSpace refreshSearch |
354 | nid = kademliaLocation space transitioningNode | 402 | nid = kademliaLocation space transitioningNode |
355 | num <- R.bucketNumber space nid <$> readTVar refreshBuckets | 403 | tbl <- readTVar refreshBuckets |
356 | modifyTVar' refreshQueue $ Int.insert num (now + refreshInterval) | 404 | let num = R.bucketNumber space nid tbl |
405 | let action = return () | ||
406 | interval <- effectiveRefreshInterval r num | ||
407 | modifyTVar' refreshQueue $ Int.insert num (now + interval) | ||
408 | writeTVar refreshLastTouch now | ||
409 | return action | ||