hlc

package
v0.0.0-...-2b2087e Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2014 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package hlc implements the Hybrid Logical Clock outlined in "Logical Physical Clocks and Consistent Snapshots in Globally Distributed Databases", available online at http://www.cse.buffalo.edu/tech-reports/2014-04.pdf.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func UnixNano

func UnixNano() int64

UnixNano returns the local machine's physical nanosecond unix epoch timestamp as a convenience to create a HLC via c := hlc.NewHLClock(hlc.UnixNano).

Types

type HLClock

type HLClock struct {

	// HLClock contains a mutex used to lock the below
	// fields while methods operate on them.
	sync.Mutex
	// contains filtered or unexported fields
}

HLClock is a hybrid logical clock. Objects of this type model causality while maintaining a relation to physical time. Roughly speaking, timestamps consist of the largest wall clock time among all events, and a logical clock that ticks whenever an event happens in the future of the local physical clock. The data structure is thread safe and thus can safely be shared by multiple goroutines.

See NewHLClock for details.

func NewHLClock

func NewHLClock(physicalClock func() int64) *HLClock

NewHLClock creates a new hybrid logical clock associated with the given physical clock, initializing both wall time and logical time with zero.

The physical clock is typically given by the wall time of the local machine in unix epoch nanoseconds, using hlc.UnixNano. This is not a requirement.

Example

ExampleNewHLClock shows how to create a new hybrid logical clock based on the local machine's physical clock. The sanity checks in this example will, of course, not fail and the output will be the age of the Unix epoch in nanoseconds.

// Initialize a new clock, using the local
// physical clock.
c := NewHLClock(UnixNano)
// Update the state of the hybrid clock.
s := c.Now()
time.Sleep(50 * time.Nanosecond)
t := HLTimestamp{WallTime: UnixNano()}
// The sanity checks below will usually never be triggered.

// HLTimestamp implements the util.Ordered interface.
if s.Less(t) || !t.Less(s) {
	glog.Fatalf("The later timestamp is smaller than the earlier one")
}

if t.WallTime-s.WallTime > 0 {
	glog.Fatalf("HLC timestamp %d deviates from physical clock %d", s, t)
}

if s.Logical > 0 {
	glog.Fatalf("Trivial timestamp has logical component")
}

fmt.Printf("The Unix Epoch is now approximately %dns old.\n", t.WallTime)
Output:

func (*HLClock) MaxDrift

func (c *HLClock) MaxDrift() uint

MaxDrift returns the maximal drift allowed. A value of 0 means drift checking is disabled. See SetMaxDrift for details.

func (*HLClock) Now

func (c *HLClock) Now() (result HLTimestamp)

Now returns a timestamp associated with an event from the local machine that may be sent to other members of the distributed network. This is the counterpart of Update, which is passed a timestamp received from another member of the distributed network.

func (*HLClock) SetMaxDrift

func (c *HLClock) SetMaxDrift(delta uint)

SetMaxDrift sets the maximal drift in nanoseconds from the physical clock that a call to Update may cause. A well-chosen value is large enough to ignore a reasonable amount of clock skew but will prevent ill-configured nodes from dramatically skewing the wall time of the clock into the future.

A value of zero disables this safety feature. The default value for a new instance is zero.

func (*HLClock) Timestamp

func (c *HLClock) Timestamp() HLTimestamp

Timestamp returns a copy of the clock's current timestamp, without performing a clock adjustment.

func (*HLClock) Update

func (c *HLClock) Update(rt HLTimestamp) (result HLTimestamp, err error)

Update takes a hybrid timestamp, usually originating from an event received from another member of a distributed system. The clock is updated and the hybrid timestamp associated to the receipt of the event returned. An error may only occur if drift checking is active and the remote timestamp was rejected due to clock drift, in which case the state of the clock will not have been altered. To timestamp events of local origin, use Now instead.

type HLTimestamp

type HLTimestamp struct {
	// Holds a wall time, typically a unix epoch time
	// expressed in nanoseconds.
	WallTime int64
	// The logical component captures causality for
	// events whose wall times are equal. It is
	// effectively bounded by
	// (maximum clock skew)/(minimal ns between events)
	// and nearly impossible to overflow.
	Logical uint64
}

HLTimestamp represents a state of the hybrid logical clock.

func (HLTimestamp) Less

func (t HLTimestamp) Less(s HLTimestamp) bool

Less implements the util.Ordered interface, allowing the comparison of timestamps.

type ManualClock

type ManualClock int64

ManualClock is a convenience type to facilitate creating a hybrid logical clock whose physical clock is manually controlled.

Example

ExampleManualClock shows how a manual clock can be used as a physical clock. This is useful for testing.

var m ManualClock = 10
c := NewHLClock(m.UnixNano)
c.Now()
if c.Timestamp().WallTime != 10 {
	glog.Fatalf("manual clock error")
}
m = 20
c.Now()
if c.Timestamp().WallTime != 20 {
	glog.Fatalf("manual clock error")
}
Output:

func (*ManualClock) UnixNano

func (m *ManualClock) UnixNano() int64

UnixNano returns the underlying manual clock's timestamp.

Jump to

Keyboard shortcuts

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