diff --git a/src/Hash2Pub/DHTProtocol.hs b/src/Hash2Pub/DHTProtocol.hs index f431da9..a2dd676 100644 --- a/src/Hash2Pub/DHTProtocol.hs +++ b/src/Hash2Pub/DHTProtocol.hs @@ -501,11 +501,15 @@ requestQueryID :: LocalNodeState -- ^ NodeState of the querying node -- TODO: deal with lookup failures requestQueryID ns targetID = do firstCacheSnapshot <- readTVarIO . nodeCacheSTM $ ns - queryIdLookupLoop firstCacheSnapshot ns targetID + -- TODO: make maxAttempts configurable + queryIdLookupLoop firstCacheSnapshot ns 50 targetID -- | like 'requestQueryID, but allows passing of a custom cache, e.g. for joining -queryIdLookupLoop :: NodeCache -> LocalNodeState -> NodeID -> IO RemoteNodeState -queryIdLookupLoop cacheSnapshot ns targetID = do +queryIdLookupLoop :: NodeCache -> LocalNodeState -> Int -> NodeID -> IO RemoteNodeState +-- return node itself as default fallback value against infinite recursion. +-- TODO: consider using an Either instead of a default value +queryIdLookupLoop _ ns 0 _ = pure $ toRemoteNodeState ns +queryIdLookupLoop cacheSnapshot ns maxAttempts targetID = do let localResult = queryLocalCache ns cacheSnapshot (lNumBestNodes ns) targetID -- FOUND can only be returned if targetID is owned by local node case localResult of @@ -522,8 +526,7 @@ queryIdLookupLoop cacheSnapshot ns targetID = do addCacheEntryPure now ) cacheSnapshot entrySet in - -- TODO: this could lead to infinite recursion on an empty cache. Consider returning the node itself as default value - queryIdLookupLoop newLCache ns targetID + queryIdLookupLoop newLCache ns (maxAttempts - 1) targetID sendQueryIdMessages :: (Integral i) diff --git a/src/Hash2Pub/FediChord.hs b/src/Hash2Pub/FediChord.hs index 152abd9..8337b06 100644 --- a/src/Hash2Pub/FediChord.hs +++ b/src/Hash2Pub/FediChord.hs @@ -165,7 +165,7 @@ fediChordJoin cacheSnapshot nsSTM = do ns <- readTVarIO nsSTM -- get routed to the currently responsible node, based on the response -- from the bootstrapping node - currentlyResponsible <- queryIdLookupLoop cacheSnapshot ns $ getNid ns + currentlyResponsible <- queryIdLookupLoop cacheSnapshot ns 50 $ getNid ns -- 2. then send a join to the currently responsible node joinResult <- requestJoin currentlyResponsible nsSTM case joinResult of