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

Add custom timer instead of time.Now() cloak time #69

Closed
pheepi opened this issue Jan 14, 2020 · 3 comments
Closed

Add custom timer instead of time.Now() cloak time #69

pheepi opened this issue Jan 14, 2020 · 3 comments

Comments

@pheepi
Copy link
Contributor

pheepi commented Jan 14, 2020

I have my app using the cache library and several tests that check if records do not expire in a given timeout. These tests fail occasionally, because they run on a server sharing CPU with other services. I can never fix them, because the library depends on cloak time from time.Now(). The only ultimate solution here is to mock time. Do you think it would be possible to replace time.Now() with an interface representing current time? It would provide function Now(), but it could be custom and parameterized. Default implementation would still use time.Now().Unix(), but custom timer could be passed as a parameter. I have already written my own change.

By the way, it may also partly resolve issue #51.

@coocood
Copy link
Owner

coocood commented Jan 14, 2020

Can you try runtime.nanotime?

// NanoTime returns the current time in nanoseconds from a monotonic clock.
//go:linkname NanoTime runtime.nanotime
func NanoTime() int64

@pheepi
Copy link
Contributor Author

pheepi commented Jan 14, 2020

This is one possible way to change wall time. I suppose you have an interface with one method:

type Timer interface {
	Now() uint32
}

Integer type uint32 is used, because type of expireAt is also of this type. Then you can have several types with different implementation of Now():

func (timer WallTimer) Now() uint32 {
	return uint32(time.Now().Unix())
}
func (timer MonotonicTimer) Now() uint32 {
	return uint32(runtime.nanotime())
}

It allows you to use whatever representation of time you want:

  1. Wrap online or network clock.
  2. Fake time meant for tests where you can say how much you want to proceed in every time. See github.com/jonboulle/clockwork for example. This is my expectation.
  3. Have ability to stop clock. It might be useful, for example if the cache is optimized, but the system must migrate in 24h. It allows to persist whole cache.
  4. Optimize clock for speed, e.g. like in Replace time.Now with lower precision time source #51.

The point of this change is that everyone may need to represent time in a different way. I would let the current behavior with wall time, but add new constructor that accepts timer interface.

@coocood
Copy link
Owner

coocood commented Jan 14, 2020

@pheepi
Good idea.
Would you like to send a PR to add this interface?

pheepi added a commit to pheepi/freecache that referenced this issue Jan 14, 2020
pheepi added a commit to pheepi/freecache that referenced this issue Jan 15, 2020
@pheepi pheepi closed this as completed Jan 15, 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

No branches or pull requests

2 participants