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

Rewrite of the ntp-client #1327

Merged
merged 27 commits into from
Feb 5, 2020
Merged

Rewrite of the ntp-client #1327

merged 27 commits into from
Feb 5, 2020

Conversation

MarcFontaine
Copy link
Contributor

@MarcFontaine MarcFontaine commented Dec 5, 2019

This PR started as a refactoring of the ntp-client but evolved into a re-implementation.
(Therefore it does not make sense to review it as a diff)

@MarcFontaine MarcFontaine self-assigned this Dec 5, 2019
@MarcFontaine MarcFontaine mentioned this pull request Jan 10, 2020
5 tasks
@MarcFontaine MarcFontaine changed the title Remove use of time-units package Rewrite of the ntp-client Jan 13, 2020
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/ntp-client.cabal Outdated Show resolved Hide resolved
ntp-client/ntp-client.cabal Outdated Show resolved Hide resolved
@coot coot added the ntp-client Issues related to ntp-client label Jan 16, 2020
ntp-client/src/Network/NTP/Packet.hs Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
Right _ -> traceWith tracer NtpTracePacketSent
Left e -> do
traceWith tracer $ NtpTracePacketSentError e
ioError e
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use a onException (or catch if you only want to act on IOExceptions). This will make transition to MonadCatcheasier (it does not have the low levelSystem.IO` exception control flow functions).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lets leave that for a new PR

ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/ntp-client.cabal Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Query.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Query.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Query.hs Outdated Show resolved Hide resolved
case (firstAddr AF_INET addr, firstAddr AF_INET6 addr) of
(Nothing, Nothing) -> do
traceWith tracer $ NtpTraceLookupServerFailed server
ioError $ userError $ "lookup NTP server failed " ++ server
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use a custom exception rather than IOError? Is there something specific to IOError in the rest of the code base that relies on the fact that it is an IOException? (e.g. an error handler that must catch it).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, to keep it simple the rest of the code only handles IOErrors explicitly and only IOErrors
and Async exceptions are expected to happen. All other exception are propagated.
All other exceptions are probably caused by bugs in the program.

ntp-client/src/Network/NTP/Query.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Query.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Trace.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
ntp-client/src/Network/NTP/Client.hs Outdated Show resolved Hide resolved
@MarcFontaine MarcFontaine requested a review from coot February 4, 2020 09:28
@MarcFontaine MarcFontaine requested a review from coot February 4, 2020 18:46
coot and others added 11 commits February 4, 2020 19:48
It is not needed outside of `Query` module
GHC will be able to free memory taken by the tread earlier.
The test suite does not need rts, -threaded and -N options set.
* use explicit recursion
* queryLoop - it must write the returned value by 'ntpQuery', otherwise
  a thread waiting for the update will not receive it.  It is up the the
  application to decide what to do if 'NtpSyncUnavailable' is received.
* improve documentation
* return type is 'IO Void', which clearly indicates that this is
  an infinite loop.
When triggering a forceful update, check if the client is not already
enaged in ntp protocols.  If not trigger update, otherwise wait for
completion of running ntp protocol instances.
This matches other test suites in 'ouroboros-network' package.
* mask async exception to guarantee that all threads are cancelled
* no need to use `waitAnyCancel` inside `withAsync`` callback, `waitAny`
  is enough for threads started with `withAsync`.
@coot
Copy link
Contributor

coot commented Feb 5, 2020

bors r+

iohk-bors bot added a commit that referenced this pull request Feb 5, 2020
1327: Rewrite of the ntp-client r=coot a=MarcFontaine

This PR started as a refactoring of the ntp-client but evolved into a re-implementation.
(Therefore it does not make sense to review it as a diff)


Co-authored-by: MarcFontaine <[email protected]>
Co-authored-by: MarcFontaine <[email protected]>
Co-authored-by: Marcin Szamotulski <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Feb 5, 2020

@iohk-bors iohk-bors bot merged commit 981abc5 into master Feb 5, 2020
@iohk-bors iohk-bors bot deleted the mafo/client2 branch February 5, 2020 09:21
Copy link
Contributor Author

@MarcFontaine MarcFontaine left a comment

Choose a reason for hiding this comment

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

I would expect the following:

  • client runs OK for a while and then error
  • retry in 5 10 20 40... seconds
  • client runs OK for a while (expected this resets retry sequence) , and then error
  • EXPECTED : retry in 5 10 20 40 ... seconds
  • IMPLEMENTATION : retry in 80 160 320 .. seconds

@coot
Copy link
Contributor

coot commented Feb 5, 2020

@MarcFontaine could you elaborate. The client will use 5 10 20 ... up to 600 intervals between restarts: https://github.com/input-output-hk/ouroboros-network/blob/master/ntp-client/src/Network/NTP/Client.hs#L98

@coot
Copy link
Contributor

coot commented Feb 5, 2020

arg, there's a mistake, it should be:

2 * delay `min` 600

not max :D

@MarcFontaine
Copy link
Contributor Author

I created an issue we can discuss it there:
#1583

Copy link
Contributor Author

@MarcFontaine MarcFontaine left a comment

Choose a reason for hiding this comment

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

This does not work:
getAddrInfo needs a Just value for at least one of the HostName or ServiceName arguments

Comment on lines 72 to 73
udpLocalAddresses :: IO [AddrInfo]
-- Hints Host Service
udpLocalAddresses = Socket.getAddrInfo (Just hints) Nothing (Just $ show port)
udpLocalAddresses = Socket.getAddrInfo (Just hints) Nothing Nothing
where
hints = Socket.defaultHints
{ addrFlags = [AI_PASSIVE]
, addrSocketType = Datagram
}
port = Socket.defaultPort
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This does not work:
getAddrInfo needs at least one Just argument.

@mark-stopka
Copy link
Contributor

Hi,
is there an option to disable built-in ntp-client and use system time instead?

@coot
Copy link
Contributor

coot commented Feb 25, 2020

Hi @mark-stopka
The reason for having this component is to check that system clock time is in sync with the rest of the world. It is not used to set or read time.

It's worth to mention that this is not to substitute a proper ntp client run as a system service.

@mark-stopka
Copy link
Contributor

mark-stopka commented Feb 25, 2020

Hi @coot, thanks for your feedback,
I was just asking, because Linux Kernel patches introducing Time Namespaces is maybe going to be introduced in Linux 5.6.0. Lot of people running pools on the ITNv1 with Jormungandr were following official guides, which included steps to configure Chrony NTP client and they were obviously failing for all those who did not have real VMs, but rather LXC containers. I'd expect Linux 5.6.x to be LTS distributions in few years time =).

Thanks for confirming,
I'll have a look around a logic that you use your application specific time or it's delta with system time for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ntp-client Issues related to ntp-client technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants