fbclock

package
v0.0.0-...-b56da86 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 1, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

README

fbclock

Client C library and stateful Go daemon to provide true time API based on PTP time.

fbclock doesn't just provide a single timestamp, instead it provides an [Earliest, Latest] values that incorporate calculated Window of Uncertainty.

The idea is using the math based on observed PTP client metrics like offset/path delay/frequency adjustments that allows estimating the level of uncertainty for current time taken from the NIC PHC.

Then on each request to the fbclock API the client gets a tuple of [Earliest, Latest] values, with 6-9s guarantee that 'true time' lies withing this range.

C API

// what customers get
typedef struct fbclock_truetime {
  uint64_t earliest_ns;
  uint64_t latest_ns;
} fbclock_truetime;

// methods we provide
int fbclock_init(fbclock_lib* lib, const char* shm_path);
int fbclock_destroy(fbclock_lib* lib);
int fbclock_gettime(fbclock_lib* lib, fbclock_truetime* truetime);

Usage

As a preprequisite, you need working PTP client set up with ptp4l, using hardware timestamps. This requires a NIC with PHC support.

  • build the daemon go build github.com/facebook/time/fbclock/daemon
  • run it as root (it needs permissions to talk to ptp4l, and get frequency from PHC)
  • build the example client CLI (cd cmd/fbclock-bin && make), use it to exercise the API and get the current PHC time

C API can be used to build a client in any language. Clients don't need special permissions except for read access to SHM path and PHC device.

Math

fbclock-daemon uses 3 formulas to provide accurate [Earliest, Latest] values.

  • M is the measurement, based on N recent values we obtain from ptp4l, such as offset, path delay, or GM clock accuracy
  • W is the error bound before it's adjusted for holdover, based on recent values of M
  • Drift is the estimation of local oscillator drift during the holdover, based on changes in PHC frequency adjustments.

This all comes together when real WOU is calculated for each API call, when client part of the code uses W and Drift values received from fbclock-daemon and adjusts W based on how far in the past the latest synchronization with GM happened.

Architecture

fbclock architecture

Documentation

Index

Constants

View Source
const PTPPath = C.FBCLOCK_PTPPATH

PTPPath is the path we set for PTP device

Variables

This section is empty.

Functions

func FloatAsUint32

func FloatAsUint32(val float64) uint32

FloatAsUint32 stores float as multiplier of 2**16. Effectively this means we can store max 65k like this.

func MmapShmpData

func MmapShmpData(fd uintptr) (unsafe.Pointer, error)

MmapShmpData mmaps open file as fbclock shared memory. Used in tests only.

func StoreFBClockData

func StoreFBClockData(fd uintptr, d Data) error

StoreFBClockData will store fbclock data in shared mem, fd param should be open file descriptor of that shared mem.

func Uint32AsFloat

func Uint32AsFloat(val uint32) float64

Uint32AsFloat restores float that was stored as a multiplier of 2**16.

func Uint64ToUint32

func Uint64ToUint32(val uint64) uint32

Uint64ToUint32 converts uint64 to uint32, handling the overflow. If the uint64 value is more than MaxUint32, result is set to MaxUint32.

Types

type Data

type Data struct {
	IngressTimeNS        int64
	ErrorBoundNS         uint64
	HoldoverMultiplierNS float64 // float stored as multiplier of  2**16
}

Data is a Go equivalent of what we want to store in shared memory for fbclock to use

func ReadFBClockData

func ReadFBClockData(shmp unsafe.Pointer) (*Data, error)

ReadFBClockData will read Data from mmaped fbclock shared memory. Used in tests only

type FBClock

type FBClock struct {
	// contains filtered or unexported fields
}

FBClock wraps around fbclock C lib

func NewFBClock

func NewFBClock() (*FBClock, error)

NewFBClock returns new FBClock wrapper

func NewFBClockCustom

func NewFBClockCustom(path string) (*FBClock, error)

NewFBClockCustom returns new FBClock wrapper with custom path

func (*FBClock) Close

func (f *FBClock) Close() error

Close destroys fbclock wrapper

func (*FBClock) GetTime

func (f *FBClock) GetTime() (*TrueTime, error)

GetTime returns TrueTime

func (*FBClock) GetTimeUTC

func (f *FBClock) GetTimeUTC() (*TrueTime, error)

GetTimeUTC returns TrueTime in UTC

type Shm

type Shm struct {
	Path string
	File *os.File
}

Shm is POSIX shared memory

func OpenFBClockSHM

func OpenFBClockSHM() (*Shm, error)

OpenFBClockSHM returns opened POSIX shared mem used by fbclock

func OpenFBClockShmCustom

func OpenFBClockShmCustom(path string) (*Shm, error)

OpenFBClockShmCustom returns opened POSIX shared mem used by fbclock, with custom path

func OpenShm

func OpenShm(path string, flags int, permissions os.FileMode) (*Shm, error)

OpenShm opens POSIX shared memory

func (*Shm) Close

func (s *Shm) Close() error

Close cleans up open POSIX shm resources

type Stats

type Stats struct {
	Requests    int64
	Errors      int64
	WOUAvg      int64
	WOUMax      int64
	WOUlt10us   int64
	WOUlt100us  int64
	WOUlt1000us int64
	WOUge1000us int64
}

Stats aggregate stats for fbclock GetTime results

type StatsCollector

type StatsCollector struct {
	// contains filtered or unexported fields
}

StatsCollector collects stats based on GetTime results

func (*StatsCollector) Stats

func (s *StatsCollector) Stats() Stats

Stats returns collected stats

func (*StatsCollector) Update

func (s *StatsCollector) Update(tt *TrueTime, err error)

Update processes result of GetTime call and updates Stats

type TrueTime

type TrueTime struct {
	Earliest time.Time
	Latest   time.Time
}

TrueTime is a time interval we are confident the clock is right now

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL