Skip to content
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

Jormungandr m with getTipId implementation #321

Merged
merged 2 commits into from Jun 5, 2019

Conversation

Anviking
Copy link
Collaborator

@Anviking Anviking commented May 24, 2019

Issue Number

#219

Overview

  • Spelling fix in Cardano.Wallet.Jormungandr.Api, and temporarily removed all endpoints from the Api but GetTipId
  • I added a Jörmungandr m client in Cardano.Wallet.Jormungandr.Network
  • I implemented getTipId, testing that it works, and that it can return Left ErrNetworkUnreachable. 404 is not a possibility .
  • I added waitForConnection to node at launch

Comments

Relevant API definition:

Skärmavbild 2019-05-29 kl  13 12 26

@Anviking Anviking self-assigned this May 24, 2019
, mkJormungandr

-- * Re-export
, BaseUrl (..)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some gratuitous re-exports here to avoid the dependencies in .cabal and import-statements for these tiny things.


startNode = do
handle <- async $ launch $ return $ Command
"jormungandr"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network branch 4 times, most recently from c78975a to 5793f43 Compare May 24, 2019 17:53
@KtorZ KtorZ force-pushed the anviking/219/jörmungandr-network branch from 5793f43 to 586c722 Compare May 27, 2019 08:30
@KtorZ KtorZ mentioned this pull request May 27, 2019
12 tasks
@Anviking Anviking marked this pull request as ready for review May 27, 2019 10:41
@Anviking Anviking changed the base branch from anviking/219/jörmungandr-network to master May 27, 2019 10:41
@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch from af72a39 to 5034821 Compare May 27, 2019 10:42
Copy link
Contributor

@akegalj akegalj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good start

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 5 times, most recently from b3eeb5a to 9b69e6f Compare May 28, 2019 12:12
length (transactions b) `shouldBe` 1

describe "Error paths" $ beforeAll newClient $ do
it "gets a 'ErrNetworkUnreachable' if jormungandr isn't up (1)"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For http-bridge we test this on the NetworkLayer. I used the Jormungandr-client here as NetworkLayer isn't implemented yet.

@Anviking Anviking requested a review from KtorZ May 28, 2019 12:19
return $ Left ErrNetworkTipNotFound
x -> do
let ctx = safeLink api (Proxy @GetTipId)
left ErrNetworkTipNetworkUnreachable <$> defaultHandler ctx x
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm kind-of not comfortable yet with how the servant-client requests are written, the error handling or the tests, but I'm not sure its worth focusing on, since we already have the same thing going on for the HttpBridge.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "focusing on" ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making an attempt at refactoring.

Not in the pr now, but for instance I find the duplication of parentId (Just count) off

        run (cGetBlockDescendantIds parentId (Just count))  >>= \case
            Left (FailureResponse e) | responseStatusCode e == status404 ->
              return $ Left ErrGetDescendantsParentNotFound
            x -> do
                let ctx = safeLink
                        api
                        (Proxy @GetBlockDescendantIds)
                        parentId
                        (Just count)
                left ErrGetDescendantsNetworkUnreachable <$> defaultHandler ctx x

lib/jormungandr/src/Cardano/Wallet/Jormungandr/Network.hs Outdated Show resolved Hide resolved
:: Int -> IO (NetworkLayer IO)
newNetworkLayer port = mkNetworkLayer <$> newHttpBridge port
where
newHttpBridge = undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the network layer isn't implemented, let's not have it part of the PR at all 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it commented still, if you don't mind, as it is the end-goal of the module.

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 4 times, most recently from 35ad859 to 80bf249 Compare May 29, 2019 13:34
@Anviking Anviking changed the title Jormungandr m with getTipId and getBlock implementation Jormungandr m with getTipId implementation May 29, 2019
@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 4 times, most recently from 4b4392d to 728d65a Compare June 3, 2019 18:37
@Anviking Anviking requested review from KtorZ and rvl June 3, 2019 20:52
@Anviking
Copy link
Collaborator Author

Anviking commented Jun 3, 2019

@rvl thanks, I think it makes much more sense than retrying in the client.

I added some simple helpers for (2) in 728d65a, and some simple tests in
23a28ce.

I added fa07dea and baccb9d

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch from 23a28ce to baccb9d Compare June 4, 2019 02:33
waitForConnection
:: NetworkLayer IO
-> IO ()
waitForConnection nw = loop 20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't we reuse waitForConnection from Jourmungadr.Network module ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. They requests are different* and they are pattern-matching on different errors.

*) Which to me appears like a thing we want: embracing the difference between NetworkLayer and the potentially underlying Jormungandr client.

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 2 times, most recently from d02c6a6 to 0370c9a Compare June 4, 2019 09:19
@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 3 times, most recently from 7d1343b to befdada Compare June 4, 2019 12:06
-- | Tries to waits 20 s, until 'networkTip networkLayer' succeeds.
waitForConnection
:: NetworkLayer IO
-> Int -- ^ Number of retries / timeout in seconds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly what Quantity is for! To convey this kind of information 😉 Every time you see yourself putting a comment to explain a What (and not a Why), ask yourself if you couldn't instead craft a better type that answers it.

Also, the comment seems to be a lie.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the comment seems to be a lie.

Fair point.

This is exactly what Quantity is for!

If we do retry it won't matter, but:

This is exactly what Quantity is for!

Hmmmmmmm.… 🤔

As long as we don't just

f (Quantity 1000000) 

sure, maybe.

Replacing the stock threadDelay with a typed version — everywhere — might be an idea too.

TIO.putStrLn "[INFO] waiting for connection to the node..."
threadDelay 1000000
loop (retries - 1)
Left e -> throwIO e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to simply use functions from retry here, which already encapsulate nicely this logic. This would also allow to simply take a retryPolicy as an argument (instead of an untyped Int) and, to provide a default policy next to the waitForConnection function for an easy usage:

waitForConnection defaultPolicy 

In testing, this would allow to pass in a different policy for which the cumulative delay can be just 500ms or so, to avoid hanging for nothing in tests.

ErrNetworkTipNetworkUnreachable _ -> True
_ -> False

it "returns when the network becomes availible" $ do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo available -> available

-- returns within (3s + 3s extra)
res <- race
(threadDelay 6000000)
(waitForConnection c 20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woudl be nice to be consistent with variable names. c is called nw in the previous test and in the helper function. Try to pick a name, and stick to it 👍

-- Start the bridge after 3s, and make sure waitForConnection
-- returns within (3s + 3s extra)
res <- race
(threadDelay 6000000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid "magic numbers" and use named constant -> let sixtySeconds = 60000000 etc .. At the very least, use a numeric separator to make thousands more obvious.

handle <- async . launch . return
$ httpBridgeWithSetup (threadDelay 3000000)
-- Start the bridge after 3s, and make sure waitForConnection
-- returns within (3s + 3s extra)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this extra 3s ? Can't we just start the bridge and call wait for connection.. That's how we would normally use it, isn't it ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was to check that waitForConnection did in-fact return within a reasonable time, not just that it returned. Overkill?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm. I still don't get it? Also, are we sure that 3 seconds is indeed enough in every environment? I'd rather just wait for connection, and verify that it resolve. If it always return within 3 seconds, then why wait for 20s in the implementation? If we are ready to wait up-to 20s that's what we should be testing here and this should never throw.

TIO.putStrLn "[INFO] waiting for connection to the node..."
threadDelay 1000000
loop (retries - 1)
| otherwise -> throwIO e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function already exists in Cardnao.Wallet.Network. What's the rationale for having both?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To have it for both Jormungandr, and NetworkLayer. (Ignoring HttpBridge as I haven't seen a need for it)

#321 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what's the need for the one in Jörmungandr? Why isn't it possible to get the same "feature" using only the NetworkLayer ? What does it bring us to specialize this to Jormungandr?

Copy link
Collaborator Author

@Anviking Anviking Jun 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could decide to not have integration tests for Jormungandr. Then we wouldn't need another waitForConnection. I don't see why we shouldn't have though.

If we instead were to here implement and test networkTip networkLayer, that would rely on both jormungandr getTipId (implemented) and getBlock (not implemented), as getTipId doesn't return a BlockHeader.

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 2 times, most recently from 59bf517 to 173ab2e Compare June 4, 2019 18:43
@Anviking Anviking requested a review from KtorZ June 4, 2019 18:44
@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch from 173ab2e to b50c21b Compare June 4, 2019 18:51
@Anviking
Copy link
Collaborator Author

Anviking commented Jun 4, 2019

Following discussion with @KtorZ I've now:

  • removed the integration tests for Jormungandr. We'll test the corresponding NetworkLayer instead. No need for a jormungandr-specific waitForConnection then.
  • Named the client JormungandrLayer

And, well, we use the retry package now too.

handle <- async . launch . return
$ httpBridgeWithSetup (threadDelay 3000000)
-- Start the bridge after 3s, and make sure waitForConnection
-- returns within (3s + 3s extra)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm. I still don't get it? Also, are we sure that 3 seconds is indeed enough in every environment? I'd rather just wait for connection, and verify that it resolve. If it always return within 3 seconds, then why wait for 20s in the implementation? If we are ready to wait up-to 20s that's what we should be testing here and this should never throw.

-- >>> mgr <- newManager defaultManagerSettings
-- >>> j = mkJormungandrLayer mgr (BaseUrl Http "localhost" 8080 "")
-- >>> runExceptT $ getTipId j
-- Right (BlockId (Hash {getHash = "26c640a3de09b74398c14ca0a137ec78"}))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@akegalj akegalj Jun 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, are we sure that 3 seconds is indeed enough in every environment?

I am sure my machine will be exceptional :)

@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch 2 times, most recently from 2e21d4e to c9958e2 Compare June 5, 2019 09:36
@Anviking Anviking force-pushed the anviking/219/jörmungandr-network-2 branch from c9958e2 to 56db060 Compare June 5, 2019 09:56
@Anviking Anviking merged commit dca30dd into master Jun 5, 2019
@Anviking Anviking deleted the anviking/219/jörmungandr-network-2 branch June 5, 2019 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants