Giter Club home page Giter Club logo

kronos-android's Introduction

Kronos-Android

Synchronized Time Android Library

Kronos is an open source Network Time Protocol (NTP) synchronization library for providing a trusted clock on the JVM.

Unlike the device clock, the time reported by Kronos is unaffected when the local time is changed while your app is running. Instead, Kronos stores accurate time along with a delta between the NTP time and the system uptime. Since uptime increases monotonically, Kronos isn't affected by device time changes. Accessing KronosClock.getCurrentTimeMs() will return the local time based on the last known accurate time + delta since last sync.

Introduction

Include the following in your build.gradle file:

implementation "com.lyft.kronos:kronos-android:$latest_version"

Obtain a Kronos clock that is synchronized with NTP servers.

class YourApplication : Application() {
    
    lateinit var kronosClock: KronosClock
    
    override fun onCreate() {
        super.onCreate()
        
        kronosClock = AndroidClockFactory.createKronosClock(applicationContext)
        kronosClock.syncInBackground()
    }
}

Replace usages of

System.currentTimeMillis()

with

kronosClock.getCurrentTimeMs()

If the NTP server cannot be reached or Kronos has not yet been synced, getCurrentTimeMs() will return time from the fallback clock and trigger syncInBackground(). If you'd rather control the fallback, you can use getCurrentNtpTimeMs(), which returns null instead of falling back.  To get metadata with an individual timestamp, use KronosClock.getCurrentTime(), which returns an instance of KronosTime. KronosTime contains the currentTime and the timeSinceLastNtpSyncMs, which will be null if currentTime is coming from the device clock.

Since it relies on system uptime, Kronos detects and requires a new sync after each reboot. 

Customization

Kronos comes with a set of reasonable default configurations. You can customize the configuration by using AndroidClockFactory.createKronosClock with the following optional parameters:

  • syncListener
    • Allows you to log sync operation successes and errors, which maybe useful for custom analytics. Pass an implementation of SyncListener.
  • ntpHosts
    • Specify a list of NTP servers with which to sync. Default servers are set to the NTP pool.
  • requestTimeoutMs
    • Lengthen or shorten the timeout value. If the NTP server fails to respond within the given time, the next server will be contacted. If none of the server respond within the given time, the sync operation will be considered a failure.
  • minWaitTimeBetweenSyncMs
    • Kronos attempts a synchronization at most once a minute. If you want to change the frequency, supply the desired interval in milliseconds. Note that you should also supply a cacheExpirationMs value. For example, if you shorten the minWaitTimeBetweenSyncMs to 30 seconds, but leave the cacheExpirationMs to 1 minute, it will have no affect because the cache is still valid within the 1 minute window.
  • cacheExpirationMs
    • Kronos will perform a background sync if the cache is stale. The cache is valid for 1 minute by default. It is simpliest to keep the cacheExpirationMs value the same as minWaitTimeBetweenSyncMs value.

With or without Android

For usage with non-Android modules, Kronos provides access to the Kotlin-only base library called Kronos-Java, which depends on an externally provided local clock and a cache. The Android library simply abstracts away the creation of the clock and cache by extracting the Android system clock from a provided Context and creating its own cache using SharedPreferences.

To use Kronos-Java include the following in your build.gradle file:

implementation "com.lyft.kronos:kronos-java:$latest_version"

Version infromation are listed under releases

Looking for Kronos for your iOS application? Check out Kronos for iOS

License

Copyright (C) 2018 Lyft Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

kronos-android's People

Contributors

ameliariely avatar amphora001 avatar artem-zinnatullin avatar arturdryomov avatar ghackett avatar keith avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kronos-android's Issues

Fatal Exception: java.util.concurrent.RejectedExecutionException

Hello, this is a very weird error that happened just once after thousands of tests being done, and cannot replicate, but here is the stacktrace:

Fatal Exception: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@398a2b3[Not completed] rejected from java.util.concurrent.ThreadPoolExecutor@3020070[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
       at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2072)
       at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:834)
       at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1364)
       at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
       at java.util.concurrent.Executors$DelegatedExecutorService.submit(Executors.java:671)
       at com.lyft.kronos.internal.ntp.SntpServiceImpl.syncInBackground(SntpService.kt:119)
       at com.lyft.kronos.internal.ntp.SntpServiceImpl.currentTime(SntpService.kt:109)
       at com.lyft.kronos.internal.KronosClockImpl.getCurrentTime(KronosClockImpl.kt:19)
       at com.lyft.kronos.KronosClock$DefaultImpls.getCurrentTimeMs(KronosClock.java:39)
       at com.lyft.kronos.internal.KronosClockImpl.getCurrentTimeMs(KronosClockImpl.kt:8)

It points directly to SntpService.kt:

override fun syncInBackground() {
        ensureServiceIsRunning()

        if (state.get() != State.SYNCING) {
            executor.submit { sync() }
        }
    }

Maybe should try/catch for RejectedExecutionException? Cheers.

Allow set custom port for NTP server

Hi,
your SntpClient.java has hardcoded NTP port.
https://github.com/lyft/Kronos-Android/blob/master/kronos-java/src/main/java/com/lyft/kronos/internal/ntp/SntpClient.java#L91

Sometimes is useful host custom NTP server on different then well known (blocked) port.

What about parse port for NTP server from host using : as separator and NTP_PORT as fallback?
Define host like host := "hostname[:port]" where hostname is string containing DNS or IP address of target NTP server and optional port for target listening port number.

Right before dns resolve(InetAddress address = dnsResolver.resolve(host);).

NTP query behavior

If I specify multiple NTP hosts, when I do an NTP sync, are all of them queried or the process stops as soon as one query to one of the hosts is successful?

Can't import library

Hi!
I can't import library using File -> New > Import module ... > Source directory >
kronos-android [+] Import
kronos-java [+] Import

After that I have following issue:

Could not read script '/Users/proft/Projects/Android/Sandbox/gradle/publish-android.gradle' as it does not exist.

What should I do?

Ignoring NTP update due to low skew

Receive timed out from NEP Server once and then get this error
Receive timed out
after that receiving
Ignoring NTP update due to low skew

v0.0.1-alpha10 same as v0.0.1-alpha09

Has anyone else seen this? I recently updated my build.gradle implementation to the newest version and when I rebuild the project/perform gradle sync, I see the alpha10 library in my project, but checking out the source reveals the files are in the same state as they were in the alpha09 version.
Screen Shot 2021-02-09 at 12 44 18 PM
Screen Shot 2021-02-09 at 12 44 43 PM
Screen Shot 2021-02-09 at 12 44 52 PM

Some screenshots of the project and the files that I saw were modified in the release notes but seemed to not be modified in the new alpha10 package.

Checking the maven repo shows alpha10 being the latest version too so a little confused here.

ticksDelta is extremely unstable

Hey, I started using Kronos a few days ago. May I have few questions regarding time sync/drifting on android?

The time seems to be complately unstable, almost each sync process ends with different diff

2020-05-01 01:49:16.804 6818-6928/Application$onCr: [kronos][sync] success sync ticksDelta[-118] responseTimeMs[222]
2020-05-01 01:50:16.934 6818-6928/Application$onCr: [kronos][sync] success sync ticksDelta[-151] responseTimeMs[129]
2020-05-01 01:50:16.994 6818-6928/Application$onCr: [kronos][sync] success sync ticksDelta[-128] responseTimeMs[56]

The calls are a minute apart from each other but the responses say that the device clock drifted 20milliseconds

Is it standard behavior of Android or am I doing something wrong?

Target API level 29

Hi,

Is there a reason for not targeting the API level 29?

We've experienced a problem with Samsung devices where the clock was behaving strangely (Felt like displaying random times). I tried to make detailed logging by forking the library and adding the modules to our project. Then we realized that we couldn't get the logs from Samsung device with API level 29. I only managed the logs working by targeting API level 29. We are still not sure if the original problem is solved of course.

There I was wondering why the library is targeting API level 27 and whether we can do anything about it or not.

Wrong Time

Some times the clock gives wrong time in andorid
While the time in device is correct

as on 17 Dec the device and NTP server time are correct
but koronos clock gives the time of 12 dec 21.

On restarting the device the clock starts giving correct timing.
Is there something need to be hit on error or something is forgetted by me

Default NTP hosts?

Nowhere in the documentation it says what are the default NTP hosts used. Could you please add it so that users can choose if to use them or replace them with others?

Unusable

I've always the same error in dependencies:
ERROR: Failed to resolve: com.lyft.kronos:kronos-android:0.0.1-alpha05
This library is unusable.

getCurrentTimeMs() return the wrong date time everytime I manually change the device clock

If I do something like:

  • Open my app
  • Minimize it and go to System > Date & Time and then change the device clock for some wrong date & time
  • Then come back to my app and try to call getCurrentTimeMs() this will give me the wrong date that I manually setup

If I have an internet connection, after that wrong response the next one works as expected, giving me the right date & time.

If that is expected behavior could you please explain a little bit more why this happens? And what do you recommend to minimize that behavior?

I am now calling kronosClock.syncInBackground(); every time my app goes to the foreground, please let me know if there is any other better strategy to deal with it.

Thank you in advance, and congrats for the work, apart from that minor issue this library is great!

Cache and "refresh" behavior not clear

If the cacheExpirationMs is 1 minute and minWaitTimeBetweenSyncMs is 5 minutes, what will happen when I do a getCurrentTime() at minute 3? Will the value in the cache be used even though it is expired, will a sync be forced even though it still has 2 minutes left or will it just use the local device time?

Migrate to Androidx?

Hi is it possible for Kronos to move to useing androidx dependencies?
This is one of the only handful of libs that still require me to use jetifier.

* com.lyft.kronos:kronos-android:0.0.1-alpha09
  \-- com.lyft.kronos:kronos-java:0.0.1-alpha09
   \-- com.android.support:support-annotations:28.0.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.