Skip to content

Truncate time to milliseconds#554

Merged
ndolhii merged 8 commits intomasterfrom
truncate-time-to-milliseconds
Aug 12, 2020
Merged

Truncate time to milliseconds#554
ndolhii merged 8 commits intomasterfrom
truncate-time-to-milliseconds

Conversation

@ndolhii
Copy link
Contributor

@ndolhii ndolhii commented Aug 6, 2020

If we run a spine-based project under the Java 11 platform we randomly may encounter the issue when Time.currentTime() returns an invalid timestamp.

The issue is that Time uses the SystemTimeProvider by default, which rely on the fact that Instant.now() returns time in millisecond precision, that was true for Java 8. The SystemTimeProvider emulates nanoseconds in order to split in time events that happened in the same millisecond, but if we have time with increased precision it leads us to the situation when the resulting amount of nanoseconds with emulation is bigger than allowed. This happens because starting from Java 9 Instant.now() may return time with increased precision if the underlying clock supports it. This issue also described in #553.

In this PR I made the SystemTimeProvider explicitly truncate time to the millisecond precision.

@ndolhii ndolhii self-assigned this Aug 6, 2020
@codecov
Copy link

codecov bot commented Aug 6, 2020

Codecov Report

Merging #554 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##             master     #554   +/-   ##
=========================================
  Coverage     73.87%   73.87%           
  Complexity     2968     2968           
=========================================
  Files           507      507           
  Lines         12004    12006    +2     
  Branches        672      672           
=========================================
+ Hits           8868     8870    +2     
  Misses         2909     2909           
  Partials        227      227           

@ndolhii ndolhii requested a review from armiol August 6, 2020 14:12
@ndolhii
Copy link
Contributor Author

ndolhii commented Aug 6, 2020

@armiol PTAL.

Copy link
Collaborator

@armiol armiol left a comment

Choose a reason for hiding this comment

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

@nick-dolgiy as discussed, let's bring up the performance by using System.currentTimeMillis() directly instead of using the same data through the Instant API and transformation logic.

Also, we need to document the changes. In particular, describe the context of the problem we solve and reference the JDK issue.

@ndolhii ndolhii requested a review from armiol August 7, 2020 13:35
@ndolhii
Copy link
Contributor Author

ndolhii commented Aug 7, 2020

@armiol PTAL again

Copy link
Collaborator

@armiol armiol left a comment

Choose a reason for hiding this comment

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

@nick-dolgiy LGTM in general. Please see my comments.

* <p>Starting from Java 9 the precision of time may differ from platform to platform and
* depends on the underlying clock used by the JVM, the
* <a href='https://bugs.openjdk.java.net/browse/JDK-8068730'>issue</a> on this in the
* JDK bug system. To be consistent on different platforms and use {@link IncrementalNanos}
Copy link
Collaborator

Choose a reason for hiding this comment

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

JDK issue tracker.

@VisibleForTesting
static class SystemTimeProvider implements Provider {

public static final int NANOSECONDS_IN_MILLISECOND = 1_000_000;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's hide this constant.

Also, please look around. I would think there is a constant like this somewhere, already defined for you.

* <p>The nanosecond value is reset for each new passed {@link Instant} value.
* <p>The nanosecond value is reset for each new passed {@code seconds} and {@code nanos}
* values.
* That allows to receive {@code 1 000} distinct time values per millisecond.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please move this line to the previous one.

Copy link
Collaborator

@armiol armiol left a comment

Choose a reason for hiding this comment

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

Added another comment.

/**
* {@inheritDoc}
*
* <p>Starting from Java 9 the precision of time may differ from platform to platform and
Copy link
Collaborator

Choose a reason for hiding this comment

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

@nick-dolgiy

Please see my suggested edit below.

<p>Starting from Java 9 the precision of time may differ from platform to platform and depends 
on the underlying clock used by the JVM. See the corresponding
 <a href='https://bugs.openjdk.java.net/browse/JDK-8068730'>issue</a> on this matter.

<p>In order to provide consistent behavior on different platforms and avoid the overflow 
of the emulated nanosecond value, this method intentionally uses the system time 
with the millisecond precision. Therefore even if the system clock may offer more precise values, 
the {@code System.currentTimeMillis()} is used as a base for the returned values.

@ndolhii ndolhii requested a review from armiol August 12, 2020 07:18
@ndolhii
Copy link
Contributor Author

ndolhii commented Aug 12, 2020

@armiol PTAL again.

@ndolhii ndolhii merged commit cd379db into master Aug 12, 2020
@ndolhii ndolhii deleted the truncate-time-to-milliseconds branch August 12, 2020 09:41
yuri-sergiichuk added a commit to SpineEventEngine/chat-bot that referenced this pull request Aug 14, 2020
The new `base` version has the Java time fix related directly to Java9+ (see SpineEventEngine/base-libraries#554 for details).

We must force dependencies because the `Bootstrap` plugin configured Spine dependencies for us with the versions pre-configured in the plugin itself.
@dmitrykuzmin dmitrykuzmin mentioned this pull request Sep 8, 2020
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.

2 participants