Documentation ¶
Index ¶
- Variables
- type Author
- type FSM
- type FSMHints
- func (*FSMHints) Descriptor() ([]byte, []int)
- func (m FSMHints) LiveLogSegments() ([]Fnode, SegmentSet, error)
- func (m *FSMHints) Marshal() (dAtA []byte, err error)
- func (m *FSMHints) MarshalTo(dAtA []byte) (int, error)
- func (*FSMHints) ProtoMessage()
- func (m *FSMHints) ProtoSize() (n int)
- func (m *FSMHints) Reset()
- func (m *FSMHints) String() string
- func (m *FSMHints) Unmarshal(dAtA []byte) error
- func (m *FSMHints) XXX_DiscardUnknown()
- func (m *FSMHints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *FSMHints) XXX_Merge(src proto.Message)
- func (m *FSMHints) XXX_Size() int
- func (m *FSMHints) XXX_Unmarshal(b []byte) error
- type FileRecorder
- type Fnode
- type FnodeSegments
- func (*FnodeSegments) Descriptor() ([]byte, []int)
- func (m *FnodeSegments) Marshal() (dAtA []byte, err error)
- func (m *FnodeSegments) MarshalTo(dAtA []byte) (int, error)
- func (*FnodeSegments) ProtoMessage()
- func (m *FnodeSegments) ProtoSize() (n int)
- func (m *FnodeSegments) Reset()
- func (m *FnodeSegments) String() string
- func (m *FnodeSegments) Unmarshal(dAtA []byte) error
- func (m *FnodeSegments) XXX_DiscardUnknown()
- func (m *FnodeSegments) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *FnodeSegments) XXX_Merge(src proto.Message)
- func (m *FnodeSegments) XXX_Size() int
- func (m *FnodeSegments) XXX_Unmarshal(b []byte) error
- type Player
- type Property
- func (*Property) Descriptor() ([]byte, []int)
- func (m *Property) Marshal() (dAtA []byte, err error)
- func (m *Property) MarshalTo(dAtA []byte) (int, error)
- func (*Property) ProtoMessage()
- func (m *Property) ProtoSize() (n int)
- func (m *Property) Reset()
- func (m *Property) String() string
- func (m *Property) Unmarshal(dAtA []byte) error
- func (m *Property) XXX_DiscardUnknown()
- func (m *Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *Property) XXX_Merge(src proto.Message)
- func (m *Property) XXX_Size() int
- func (m *Property) XXX_Unmarshal(b []byte) error
- type RecordedAferoFS
- func (r RecordedAferoFS) Create(name string) (afero.File, error)
- func (r RecordedAferoFS) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error)
- func (r RecordedAferoFS) Remove(name string) error
- func (r RecordedAferoFS) RemoveAll(path string) error
- func (r RecordedAferoFS) Rename(oldname, newname string) error
- type RecordedOp
- func (*RecordedOp) Descriptor() ([]byte, []int)
- func (m *RecordedOp) Marshal() (dAtA []byte, err error)
- func (m *RecordedOp) MarshalTo(dAtA []byte) (int, error)
- func (*RecordedOp) ProtoMessage()
- func (m *RecordedOp) ProtoSize() (n int)
- func (m *RecordedOp) Reset()
- func (m *RecordedOp) String() string
- func (m *RecordedOp) Unmarshal(dAtA []byte) error
- func (m *RecordedOp) XXX_DiscardUnknown()
- func (m *RecordedOp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *RecordedOp) XXX_Merge(src proto.Message)
- func (m *RecordedOp) XXX_Size() int
- func (m *RecordedOp) XXX_Unmarshal(b []byte) error
- type RecordedOp_Create
- func (*RecordedOp_Create) Descriptor() ([]byte, []int)
- func (m *RecordedOp_Create) Marshal() (dAtA []byte, err error)
- func (m *RecordedOp_Create) MarshalTo(dAtA []byte) (int, error)
- func (*RecordedOp_Create) ProtoMessage()
- func (m *RecordedOp_Create) ProtoSize() (n int)
- func (m *RecordedOp_Create) Reset()
- func (m *RecordedOp_Create) String() string
- func (m *RecordedOp_Create) Unmarshal(dAtA []byte) error
- func (m *RecordedOp_Create) XXX_DiscardUnknown()
- func (m *RecordedOp_Create) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *RecordedOp_Create) XXX_Merge(src proto.Message)
- func (m *RecordedOp_Create) XXX_Size() int
- func (m *RecordedOp_Create) XXX_Unmarshal(b []byte) error
- type RecordedOp_Link
- func (*RecordedOp_Link) Descriptor() ([]byte, []int)
- func (m *RecordedOp_Link) Marshal() (dAtA []byte, err error)
- func (m *RecordedOp_Link) MarshalTo(dAtA []byte) (int, error)
- func (*RecordedOp_Link) ProtoMessage()
- func (m *RecordedOp_Link) ProtoSize() (n int)
- func (m *RecordedOp_Link) Reset()
- func (m *RecordedOp_Link) String() string
- func (m *RecordedOp_Link) Unmarshal(dAtA []byte) error
- func (m *RecordedOp_Link) XXX_DiscardUnknown()
- func (m *RecordedOp_Link) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *RecordedOp_Link) XXX_Merge(src proto.Message)
- func (m *RecordedOp_Link) XXX_Size() int
- func (m *RecordedOp_Link) XXX_Unmarshal(b []byte) error
- type RecordedOp_Write
- func (*RecordedOp_Write) Descriptor() ([]byte, []int)
- func (m *RecordedOp_Write) Marshal() (dAtA []byte, err error)
- func (m *RecordedOp_Write) MarshalTo(dAtA []byte) (int, error)
- func (*RecordedOp_Write) ProtoMessage()
- func (m *RecordedOp_Write) ProtoSize() (n int)
- func (m *RecordedOp_Write) Reset()
- func (m *RecordedOp_Write) String() string
- func (m *RecordedOp_Write) Unmarshal(dAtA []byte) error
- func (m *RecordedOp_Write) XXX_DiscardUnknown()
- func (m *RecordedOp_Write) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *RecordedOp_Write) XXX_Merge(src proto.Message)
- func (m *RecordedOp_Write) XXX_Size() int
- func (m *RecordedOp_Write) XXX_Unmarshal(b []byte) error
- type RecordedRocksDB
- type Recorder
- func (r *Recorder) BuildHints() FSMHints
- func (r *Recorder) RecordCreate(path string) *FileRecorder
- func (r *Recorder) RecordLink(src, target string)
- func (r *Recorder) RecordRemove(path string)
- func (r *Recorder) RecordRename(src, target string)
- func (r *Recorder) StrongBarrier() *client.AsyncAppend
- func (r *Recorder) WeakBarrier() *client.AsyncAppend
- type Segment
- func (*Segment) Descriptor() ([]byte, []int)
- func (m *Segment) Marshal() (dAtA []byte, err error)
- func (m *Segment) MarshalTo(dAtA []byte) (int, error)
- func (*Segment) ProtoMessage()
- func (m *Segment) ProtoSize() (n int)
- func (m *Segment) Reset()
- func (m *Segment) String() string
- func (m *Segment) Unmarshal(dAtA []byte) error
- func (s Segment) Validate() error
- func (m *Segment) XXX_DiscardUnknown()
- func (m *Segment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *Segment) XXX_Merge(src proto.Message)
- func (m *Segment) XXX_Size() int
- func (m *Segment) XXX_Unmarshal(b []byte) error
- type SegmentSet
Constants ¶
This section is empty.
Variables ¶
var ( ErrChecksumMismatch = fmt.Errorf("checksum mismatch") ErrExpectedHintedFnode = fmt.Errorf("op is not create, and an Fnode was hinted") ErrFnodeNotTracked = fmt.Errorf("fnode not tracked") ErrLinkExists = fmt.Errorf("link exists") ErrNoSuchLink = fmt.Errorf("fnode has no such link") ErrNotHintedAuthor = fmt.Errorf("op author does not match the next hinted author") ErrPropertyExists = fmt.Errorf("property exists") ErrWrongSeqNo = fmt.Errorf("wrong sequence number") )
var ( ErrInvalidLengthRecordedOp = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowRecordedOp = fmt.Errorf("proto: integer overflow") )
Functions ¶
This section is empty.
Types ¶
type Author ¶
type Author uint32
Author is a random, unique ID which identifies a processes that creates RecordedOps. It's used by FSM to allow for reconciliation of divergent histories in the recovery log, through hints as to which Authors produced which Segments in the final history.
func NewRandomAuthorID ¶
NewRandomAuthorID creates and returns a new, randomized Author ID.
type FSM ¶
type FSM struct { // Recovery log which this FSM tracks operations of. Log pb.Journal // Expected sequence number and checksum of next operation. NextSeqNo int64 NextChecksum uint32 // Target paths and contents of small files which are managed outside of // regular Fnode tracking. Property updates are triggered upon rename of // a tracked Fnode to a well-known property file path. // // Property paths must be "sinks" which: // * Are never directly written to. // * Are never renamed or linked from. // * Have exactly one hard-link (eg, only "rename" to the property path is // supported; "link" is not as it would introduce a second hard-link). Properties map[string]string // Maps from Fnode to current state of the node. LiveNodes map[Fnode]*fnodeState // Indexes current target paths of LiveNodes. Links map[string]Fnode // contains filtered or unexported fields }
FSM implements a finite state machine over RecordedOp. In particular FSM applies RecordedOp in order, verifying the SeqNo and Checksum of each operation. This ensures that only operations which are linear and consistent are applied.
func (*FSM) Apply ¶
func (m *FSM) Apply(op *RecordedOp, frame []byte) error
Apply attempts to transition the FSMs state by |op| & |frame|. It either performs a transition, or returns an error detailing how the operation is not consistent with prior applied operations or hints. A state transition occurs if and only if the returned err is nil, with one exception: ErrFnodeNotTracked may be returned to indicate that the operation is consistent and a transition occurred, but that FSMHints also indicate the Fnode no longer exists at the point-in-time at which the FSMHints were created, and the caller may therefor want to skip corresponding local playback actions.
func (*FSM) BuildHints ¶
BuildHints constructs FSMHints which enable a future FSM to rebuild this FSM's state.
type FSMHints ¶
type FSMHints struct { // Log is the Journal name holding recorded log content. Log github_com_LiveRamp_gazette_v2_pkg_protocol.Journal `protobuf:"bytes,1,opt,name=log,proto3,casttype=github.com/LiveRamp/gazette/v2/pkg/protocol.Journal" json:"log,omitempty"` // Live Fnodes and their Segments as-of the generation of these FSMHints. LiveNodes []FnodeSegments `protobuf:"bytes,2,rep,name=live_nodes,json=liveNodes" json:"live_nodes"` // Property files and contents as-of the generation of these FSMHints. Properties []Property `protobuf:"bytes,3,rep,name=properties" json:"properties"` }
FSMHints represents a manifest of Fnodes which were still live (eg, having remaining links) at the time the FSMHints were produced, as well as any Properties. It allows a Player of the log to identify minimal Segments which must be read to recover all Fnodes, and also contains sufficient metadata for a Player to resolve all possible conflicts it could encounter while reading the log, to arrive at a consistent view of file state which exactly matches that of the Recorder producing the FSMHints. Next tag: 4.
func (*FSMHints) Descriptor ¶
func (FSMHints) LiveLogSegments ¶
func (m FSMHints) LiveLogSegments() ([]Fnode, SegmentSet, error)
LiveLogSegments flattens hinted LiveNodes into an ordered list of Fnodes, and the set of recovery log Segments which fully contain them.
func (*FSMHints) ProtoMessage ¶
func (*FSMHints) ProtoMessage()
func (*FSMHints) XXX_DiscardUnknown ¶
func (m *FSMHints) XXX_DiscardUnknown()
func (*FSMHints) XXX_Marshal ¶
func (*FSMHints) XXX_Unmarshal ¶
type FileRecorder ¶
type FileRecorder struct { *Recorder // contains filtered or unexported fields }
FileRecorder records operations applied to a specific file opened with RecordCreate.
func (*FileRecorder) RecordWrite ¶
func (r *FileRecorder) RecordWrite(data []byte)
RecordWrite records the write of |data| at the current file offset.
type Fnode ¶
type Fnode int64
An Fnode is an identifier which represents a file across its renames, links, and un-links within a file-system. When a file is created, it's assigned an Fnode value equal to the RecordedOp.SeqNo which created it.
type FnodeSegments ¶
type FnodeSegments struct { // Fnode being hinted. Fnode Fnode `protobuf:"varint,1,opt,name=fnode,proto3,casttype=Fnode" json:"fnode,omitempty"` // Segments of the Fnode in the log. Currently, FSM tracks only a single // Segment per Fnode per Author. A specific implication of this is that Fnodes // modified over long periods of time will result in Segments spanning large // chunks of the log. For best performance, Fnodes should be opened & written // once, and then never be modified again (this is RocksDB's behavior). // If supporting this case is desired, FSM will have to be a bit smarter about // not extending Segments which gap over significant portions of the log // (eg, there's a trade-off to make over size of the hinted manifest, vs // savings incurred on playback by being able to skip portions of the log). Segments []Segment `protobuf:"bytes,2,rep,name=segments" json:"segments"` }
FnodeSegments captures log Segments containing all RecordedOps of the Fnode.
func (*FnodeSegments) Descriptor ¶
func (*FnodeSegments) Descriptor() ([]byte, []int)
func (*FnodeSegments) Marshal ¶
func (m *FnodeSegments) Marshal() (dAtA []byte, err error)
func (*FnodeSegments) ProtoMessage ¶
func (*FnodeSegments) ProtoMessage()
func (*FnodeSegments) ProtoSize ¶
func (m *FnodeSegments) ProtoSize() (n int)
func (*FnodeSegments) Reset ¶
func (m *FnodeSegments) Reset()
func (*FnodeSegments) String ¶
func (m *FnodeSegments) String() string
func (*FnodeSegments) Unmarshal ¶
func (m *FnodeSegments) Unmarshal(dAtA []byte) error
func (*FnodeSegments) XXX_DiscardUnknown ¶
func (m *FnodeSegments) XXX_DiscardUnknown()
func (*FnodeSegments) XXX_Marshal ¶
func (m *FnodeSegments) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*FnodeSegments) XXX_Merge ¶
func (dst *FnodeSegments) XXX_Merge(src proto.Message)
func (*FnodeSegments) XXX_Size ¶
func (m *FnodeSegments) XXX_Size() int
func (*FnodeSegments) XXX_Unmarshal ¶
func (m *FnodeSegments) XXX_Unmarshal(b []byte) error
type Player ¶
type Player struct { FSM *FSM // FSM recovered at Play completion. Nil if an error was encountered. Dir string // Local directory into which the log is recovered. // contains filtered or unexported fields }
Player reads from a log to rebuild encoded file operations onto the local filesystem.
func (*Player) Done ¶
func (p *Player) Done() <-chan struct{}
Done returns a channel which selects when Play has completed. If Play returned no error, then Player.FSM & Dir will hold the recovered FSM and its local directory. Otherwise, both will be zero-valued.
func (*Player) FinishAtWriteHead ¶
func (p *Player) FinishAtWriteHead()
FinishAtWriteHead requests that playback complete upon reaching the current write head. Only one invocation of FinishAtWriteHead or InjectHandoff may be made of a Player instance.
func (*Player) InjectHandoff ¶
InjectHandoff requests that playback complete upon injecting a no-op handoff of the given |author| at the log head. Only one invocation of InjectHandoff or FinishAtWriteHead may be made of a Player instance. |author| must be non- zero or InjectHandoff panics.
func (*Player) Play ¶
func (p *Player) Play(ctx context.Context, hints FSMHints, dir string, ajc client.AsyncJournalClient) error
Play uses the prepared Player to play back the FSMHints. It returns on the first encountered unrecoverable error, including context cancellation, or upon a successful FinishAtWriteHead or InjectHandoff.
type Property ¶
type Property struct { // Filesystem path of this property, relative to the common base directory. Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` // Complete file content of this property. Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` }
Property is a small file which rarely changes, and is thus managed outside of regular Fnode tracking. See FSM.Properties.
func (*Property) Descriptor ¶
func (*Property) ProtoMessage ¶
func (*Property) ProtoMessage()
func (*Property) XXX_DiscardUnknown ¶
func (m *Property) XXX_DiscardUnknown()
func (*Property) XXX_Marshal ¶
func (*Property) XXX_Unmarshal ¶
type RecordedAferoFS ¶
RecordedAferoFS adapts a Recorder to wrap a afero.Fs instance.
func (RecordedAferoFS) Remove ¶
func (r RecordedAferoFS) Remove(name string) error
func (RecordedAferoFS) RemoveAll ¶
func (r RecordedAferoFS) RemoveAll(path string) error
func (RecordedAferoFS) Rename ¶
func (r RecordedAferoFS) Rename(oldname, newname string) error
type RecordedOp ¶
type RecordedOp struct { // Monotonically-increasing sequence number of this operation. SeqNo int64 `protobuf:"varint,1,opt,name=seq_no,json=seqNo,proto3" json:"seq_no,omitempty"` // Previous FSM checksum to which this operation should be applied (eg, the // expected checksum arrived at after applying the previous operation. Checksum uint32 `protobuf:"fixed32,2,opt,name=checksum,proto3" json:"checksum,omitempty"` // Author is the unique ID of the Recorder which wrote this RecordedOp. // Each Recorder randomly generates an Author ID at startup, and thereafter // applies it to all operations it records. Author Author `protobuf:"fixed32,3,opt,name=author,proto3,casttype=Author" json:"author,omitempty"` // First and last byte offset (exclusive) of this RecordedOp. These are meta- // fields which are not populated in the recorded log (as Recorders cannot // know at what offsets their writes will land in the log). Instead, Players // attach offsets as they deserialize RecordedOps from the committed log. FirstOffset int64 `protobuf:"varint,9,opt,name=first_offset,json=firstOffset,proto3" json:"first_offset,omitempty"` LastOffset int64 `protobuf:"varint,10,opt,name=last_offset,json=lastOffset,proto3" json:"last_offset,omitempty"` Create *RecordedOp_Create `protobuf:"bytes,4,opt,name=create" json:"create,omitempty"` Link *RecordedOp_Link `protobuf:"bytes,5,opt,name=link" json:"link,omitempty"` Unlink *RecordedOp_Link `protobuf:"bytes,6,opt,name=unlink" json:"unlink,omitempty"` Write *RecordedOp_Write `protobuf:"bytes,7,opt,name=write" json:"write,omitempty"` // Property indicates a property file has been created or updated. Property *Property `protobuf:"bytes,8,opt,name=property" json:"property,omitempty"` }
RecordedOp records states changes occuring within a local file-system. Next tag: 11.
func (*RecordedOp) Descriptor ¶
func (*RecordedOp) Descriptor() ([]byte, []int)
func (*RecordedOp) Marshal ¶
func (m *RecordedOp) Marshal() (dAtA []byte, err error)
func (*RecordedOp) ProtoMessage ¶
func (*RecordedOp) ProtoMessage()
func (*RecordedOp) ProtoSize ¶
func (m *RecordedOp) ProtoSize() (n int)
func (*RecordedOp) Reset ¶
func (m *RecordedOp) Reset()
func (*RecordedOp) String ¶
func (m *RecordedOp) String() string
func (*RecordedOp) Unmarshal ¶
func (m *RecordedOp) Unmarshal(dAtA []byte) error
func (*RecordedOp) XXX_DiscardUnknown ¶
func (m *RecordedOp) XXX_DiscardUnknown()
func (*RecordedOp) XXX_Marshal ¶
func (m *RecordedOp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*RecordedOp) XXX_Merge ¶
func (dst *RecordedOp) XXX_Merge(src proto.Message)
func (*RecordedOp) XXX_Size ¶
func (m *RecordedOp) XXX_Size() int
func (*RecordedOp) XXX_Unmarshal ¶
func (m *RecordedOp) XXX_Unmarshal(b []byte) error
type RecordedOp_Create ¶
type RecordedOp_Create struct { // Filesystem path of this file, relative to the common base directory. Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` }
Create a new "File Node" (Fnode), initially linked to |path|. Fnodes play a similar role to Posix inodes: they identify a specific file object while being invariant to (and spanning across) its current or future path links. The assigned Fnode ID is the |seq_no| of this RecordedOp.
func (*RecordedOp_Create) Descriptor ¶
func (*RecordedOp_Create) Descriptor() ([]byte, []int)
func (*RecordedOp_Create) Marshal ¶
func (m *RecordedOp_Create) Marshal() (dAtA []byte, err error)
func (*RecordedOp_Create) MarshalTo ¶
func (m *RecordedOp_Create) MarshalTo(dAtA []byte) (int, error)
func (*RecordedOp_Create) ProtoMessage ¶
func (*RecordedOp_Create) ProtoMessage()
func (*RecordedOp_Create) ProtoSize ¶
func (m *RecordedOp_Create) ProtoSize() (n int)
func (*RecordedOp_Create) Reset ¶
func (m *RecordedOp_Create) Reset()
func (*RecordedOp_Create) String ¶
func (m *RecordedOp_Create) String() string
func (*RecordedOp_Create) Unmarshal ¶
func (m *RecordedOp_Create) Unmarshal(dAtA []byte) error
func (*RecordedOp_Create) XXX_DiscardUnknown ¶
func (m *RecordedOp_Create) XXX_DiscardUnknown()
func (*RecordedOp_Create) XXX_Marshal ¶
func (m *RecordedOp_Create) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*RecordedOp_Create) XXX_Merge ¶
func (dst *RecordedOp_Create) XXX_Merge(src proto.Message)
func (*RecordedOp_Create) XXX_Size ¶
func (m *RecordedOp_Create) XXX_Size() int
func (*RecordedOp_Create) XXX_Unmarshal ¶
func (m *RecordedOp_Create) XXX_Unmarshal(b []byte) error
type RecordedOp_Link ¶
type RecordedOp_Link struct { // Fnode being linked or unlinked. Fnode Fnode `protobuf:"varint,1,opt,name=fnode,proto3,casttype=Fnode" json:"fnode,omitempty"` // Filesystem path being un/linked, relative to the common base directory. Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` }
Link or unlink an Fnode to a filesystem path.
func (*RecordedOp_Link) Descriptor ¶
func (*RecordedOp_Link) Descriptor() ([]byte, []int)
func (*RecordedOp_Link) Marshal ¶
func (m *RecordedOp_Link) Marshal() (dAtA []byte, err error)
func (*RecordedOp_Link) ProtoMessage ¶
func (*RecordedOp_Link) ProtoMessage()
func (*RecordedOp_Link) ProtoSize ¶
func (m *RecordedOp_Link) ProtoSize() (n int)
func (*RecordedOp_Link) Reset ¶
func (m *RecordedOp_Link) Reset()
func (*RecordedOp_Link) String ¶
func (m *RecordedOp_Link) String() string
func (*RecordedOp_Link) Unmarshal ¶
func (m *RecordedOp_Link) Unmarshal(dAtA []byte) error
func (*RecordedOp_Link) XXX_DiscardUnknown ¶
func (m *RecordedOp_Link) XXX_DiscardUnknown()
func (*RecordedOp_Link) XXX_Marshal ¶
func (m *RecordedOp_Link) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*RecordedOp_Link) XXX_Merge ¶
func (dst *RecordedOp_Link) XXX_Merge(src proto.Message)
func (*RecordedOp_Link) XXX_Size ¶
func (m *RecordedOp_Link) XXX_Size() int
func (*RecordedOp_Link) XXX_Unmarshal ¶
func (m *RecordedOp_Link) XXX_Unmarshal(b []byte) error
type RecordedOp_Write ¶
type RecordedOp_Write struct { // Fnode being written to. Fnode Fnode `protobuf:"varint,1,opt,name=fnode,proto3,casttype=Fnode" json:"fnode,omitempty"` // Byte-offset within the file to which this write is applied. Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` // Length of the write. Length int64 `protobuf:"varint,3,opt,name=length,proto3" json:"length,omitempty"` }
Write indicates |length| bytes should be written at |offset| to |fnode|. In a serialization stream, we expect |length| raw bytes of content to immediately follow this operation.
func (*RecordedOp_Write) Descriptor ¶
func (*RecordedOp_Write) Descriptor() ([]byte, []int)
func (*RecordedOp_Write) Marshal ¶
func (m *RecordedOp_Write) Marshal() (dAtA []byte, err error)
func (*RecordedOp_Write) ProtoMessage ¶
func (*RecordedOp_Write) ProtoMessage()
func (*RecordedOp_Write) ProtoSize ¶
func (m *RecordedOp_Write) ProtoSize() (n int)
func (*RecordedOp_Write) Reset ¶
func (m *RecordedOp_Write) Reset()
func (*RecordedOp_Write) String ¶
func (m *RecordedOp_Write) String() string
func (*RecordedOp_Write) Unmarshal ¶
func (m *RecordedOp_Write) Unmarshal(dAtA []byte) error
func (*RecordedOp_Write) XXX_DiscardUnknown ¶
func (m *RecordedOp_Write) XXX_DiscardUnknown()
func (*RecordedOp_Write) XXX_Marshal ¶
func (m *RecordedOp_Write) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*RecordedOp_Write) XXX_Merge ¶
func (dst *RecordedOp_Write) XXX_Merge(src proto.Message)
func (*RecordedOp_Write) XXX_Size ¶
func (m *RecordedOp_Write) XXX_Size() int
func (*RecordedOp_Write) XXX_Unmarshal ¶
func (m *RecordedOp_Write) XXX_Unmarshal(b []byte) error
type RecordedRocksDB ¶
type RecordedRocksDB struct{ *Recorder }
RecordedRocksDB adapts a Recorder to be a rocksdb.EnvObserver
func (RecordedRocksDB) DeleteDir ¶
func (r RecordedRocksDB) DeleteDir(dirname string)
func (RecordedRocksDB) DeleteFile ¶
func (r RecordedRocksDB) DeleteFile(path string)
func (RecordedRocksDB) LinkFile ¶
func (r RecordedRocksDB) LinkFile(src, target string)
func (RecordedRocksDB) NewWritableFile ¶
func (r RecordedRocksDB) NewWritableFile(path string) gorocksdb.WritableFileObserver
func (RecordedRocksDB) RenameFile ¶
func (r RecordedRocksDB) RenameFile(src, target string)
type Recorder ¶
type Recorder struct {
// contains filtered or unexported fields
}
Recorder observes a sequence of changes to a file-system, and preserves those changes via a written Gazette journal of file-system operations. Note that we can't ever fail to write some portion of the recorded log, and then return control back to the database (and its client). To do so would allow for inconsistency in the local database state, vs the recorded log. For this reason, Recorder's implementation is crash-only and panics on error.
func NewRecorder ¶
NewRecorder creates and returns a Recorder.
func (*Recorder) BuildHints ¶
BuildHints returns FSMHints which may be played back to fully reconstruct the local filesystem state observed by this Recorder. It may block while pending operations sync to the log.
func (*Recorder) RecordCreate ¶
func (r *Recorder) RecordCreate(path string) *FileRecorder
RecordCreate records the creation of file |path|, and returns a FileRecorder which records file operations.
func (*Recorder) RecordLink ¶
RecordLink records the creation of a hard link from |src| to |target|.
func (*Recorder) RecordRemove ¶
RecordRemove records the removal of the file at |path|.
func (*Recorder) RecordRename ¶
RecordRename records the rename of |src| to |target|.
func (*Recorder) StrongBarrier ¶
func (r *Recorder) StrongBarrier() *client.AsyncAppend
StrongBarrier issues a zero-byte append which has dependencies on all other pending appends of the AsyncAppendClient. When this barrier completes, it is guaranteed that all writes of the AsyncAppendClient which were pending at issuance of the barrier (including writes of this Recorder) have committed.
func (*Recorder) WeakBarrier ¶
func (r *Recorder) WeakBarrier() *client.AsyncAppend
WeakBarrier issues a zero-byte append with no dependencies. When this barrier completes, it is guaranteed that all content recorded prior to the barrier has also committed. Writes to *other* journals which were pending at issuance of the barrier may still be ongoing.
type Segment ¶
type Segment struct { // Author which wrote RecordedOps of this Segment. Author Author `protobuf:"fixed32,1,opt,name=author,proto3,casttype=Author" json:"author,omitempty"` // First (lowest) sequence number of RecordedOps within this Segment. FirstSeqNo int64 `protobuf:"varint,2,opt,name=first_seq_no,json=firstSeqNo,proto3" json:"first_seq_no,omitempty"` // First byte offset of the Segment, where |first_seq_no| is recorded. // If this Segment was produced by a Recorder, this is guaranteed only to be a // lower-bound (eg, a Player reading at this offset may encounter irrelevant // operations prior to the RecordedOp indicated by the tuple // (|author|, |first_seq_no|, |first_checksum|). If a Player produced the Segment, // first_offset is exact. FirstOffset int64 `protobuf:"varint,3,opt,name=first_offset,json=firstOffset,proto3" json:"first_offset,omitempty"` // Checksum of the RecordedOp having |first_seq_no|. FirstChecksum uint32 `protobuf:"fixed32,4,opt,name=first_checksum,json=firstChecksum,proto3" json:"first_checksum,omitempty"` // Last (highest, inclusive) sequence number of RecordedOps within this Segment. LastSeqNo int64 `protobuf:"varint,5,opt,name=last_seq_no,json=lastSeqNo,proto3" json:"last_seq_no,omitempty"` // Last offset (exclusive) of the Segment. Zero means the offset is not known // (eg, because the Segment was produced by a Recorder). LastOffset int64 `protobuf:"varint,6,opt,name=last_offset,json=lastOffset,proto3" json:"last_offset,omitempty"` }
Segment is a contiguous chunk of recovery log written by a single Author. Recorders track Segments they have written, for use in providing hints to future readers of the log. A key point to understand is that Gazette append semantics mean that Recorders *cannot know* exactly what offsets their writes are applied to in the log, nor guarantee that their operations are not being interleaved with those of other writers. Log Players are aware of these limitations, and use Segments to resolve conflicts of possible interpretation of the log. Segments produced by a Player are exact, since Players observe all recorded operations at their exact offsets. Next tag: 7.
func (*Segment) Descriptor ¶
func (*Segment) ProtoMessage ¶
func (*Segment) ProtoMessage()
func (*Segment) XXX_DiscardUnknown ¶
func (m *Segment) XXX_DiscardUnknown()
func (*Segment) XXX_Marshal ¶
func (*Segment) XXX_Unmarshal ¶
type SegmentSet ¶
type SegmentSet []Segment
SegmentSet is a collection of Segment with the following invariants:
- Entries have strictly increasing SeqNo, and are non-overlapping (s[i].LastSeqNo < s[i+1].SeqNo; note this implies a single author for any covered SeqNo).
- Entries have monotonically increasing FirstOffset.
- Entries have monotonically increasing LastOffset, however a strict suffix of entries are permitted to have a LastOffset of zero (implied infinite LastOffset).
func (*SegmentSet) Add ¶
func (s *SegmentSet) Add(segment Segment) error
Add a Segment to this SegmentSet. An error is returned if |segment| would result in an inconsistent SegmentSet.
func (SegmentSet) Intersect ¶
func (s SegmentSet) Intersect(firstOffset, lastOffset int64) SegmentSet
Intersect returns a slice of this SegmentSet which overlaps with the provided [firstOffset, lastOffset) range.