Skip to content

Commit

Permalink
Merge pull request #162 from shreyas-s-rao/patch-0.6.3
Browse files Browse the repository at this point in the history
Cherry pick stop signal handling and snapshot sorting fixes
  • Loading branch information
shreyas-s-rao authored May 14, 2019
2 parents b4791b1 + 5433a42 commit cc5bd9a
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 11 deletions.
16 changes: 9 additions & 7 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,15 @@ func NewServerCommand(stopCh <-chan struct{}) *cobra.Command {
}
} else {
startWithFullSnapshot = true
if ssrStopped, err := ssr.CollectEventsSincePrevSnapshot(ssrStopCh); err != nil {
if ssrStopped {
logger.Infof("Snapshotter stopped.")
ackCh <- emptyStruct
handler.Status = http.StatusServiceUnavailable
return
}
ssrStopped, err := ssr.CollectEventsSincePrevSnapshot(ssrStopCh)
if ssrStopped {
logger.Info("Snapshotter stopped.")
ackCh <- emptyStruct
handler.Status = http.StatusServiceUnavailable
logger.Info("Shutting down...")
return
}
if err != nil {
if etcdErr, ok := err.(*errors.EtcdError); ok == true {
logger.Errorf("Failed to take first delta snapshot: snapshotter failed with etcd error: %v", etcdErr)
} else {
Expand Down
1 change: 0 additions & 1 deletion pkg/snapshot/restorer/restorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ func (r *Restorer) applyDeltaSnapshots(client *clientv3.Client, ro RestoreOption

firstDeltaSnap := snapList[0]

r.logger.Infof("Applying delta snapshot %s", path.Join(firstDeltaSnap.SnapDir, firstDeltaSnap.SnapName))
if err := r.applyFirstDeltaSnapshot(client, *firstDeltaSnap); err != nil {
return err
}
Expand Down
23 changes: 22 additions & 1 deletion pkg/snapstore/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ func (s *Snapshot) GenerateSnapshotName() {

// GenerateSnapshotDirectory prepares the snapshot directory name from metadata
func (s *Snapshot) GenerateSnapshotDirectory() {
s.SnapDir = fmt.Sprintf("%s-%d", "Backup", s.CreatedOn.Unix())
s.SnapDir = fmt.Sprintf("Backup-%d", s.CreatedOn.Unix())
}

// GetSnapshotDirectoryCreationTimeInUnix returns the creation time for snapshot directory.
func (s *Snapshot) GetSnapshotDirectoryCreationTimeInUnix() (int64, error) {
tok := strings.TrimPrefix(s.SnapDir, "Backup-")
return strconv.ParseInt(tok, 10, 64)
}

// ParseSnapshot parse <snapPath> to create snapshot structure
Expand Down Expand Up @@ -106,6 +112,21 @@ func ParseSnapshot(snapPath string) (*Snapshot, error) {
func (s SnapList) Len() int { return len(s) }
func (s SnapList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SnapList) Less(i, j int) bool {
// Ignoring errors here, as we assume at this stage the error won't happen.
iCreationTime, err := s[i].GetSnapshotDirectoryCreationTimeInUnix()
if err != nil {
logrus.Errorf("Failed to get snapshot directory creation time for snapshot: %s, with error: %v", path.Join(s[i].SnapDir, s[i].SnapName), err)
}
jCreationTime, err := s[j].GetSnapshotDirectoryCreationTimeInUnix()
if err != nil {
logrus.Errorf("Failed to get snapshot directory creation time for snapshot: %s, with error: %v", path.Join(s[j].SnapDir, s[j].SnapName), err)
}
if iCreationTime < jCreationTime {
return true
}
if iCreationTime > jCreationTime {
return false
}
if s[i].CreatedOn.Unix() == s[j].CreatedOn.Unix() {
if !s[i].IsChunk && s[j].IsChunk {
return true
Expand Down
75 changes: 73 additions & 2 deletions pkg/snapstore/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,95 +32,166 @@ var _ = Describe("Snapshot", func() {
It("sorts snapshot by creation time", func() {
interval := int64(5)
now := time.Now().Unix()
snapdir := fmt.Sprintf("Backup-%d", now)
snap1 := Snapshot{
CreatedOn: time.Unix(now, 0).UTC(),
StartRevision: 0,
LastRevision: 2088,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snap2 := Snapshot{
CreatedOn: time.Unix(now+1*interval, 0).UTC(),
StartRevision: 0,
LastRevision: 1988,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snap3 := Snapshot{
CreatedOn: time.Unix(now+2*interval, 0).UTC(),
StartRevision: 0,
LastRevision: 1888,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snap4 := Snapshot{
CreatedOn: time.Unix(now+3*interval, 0).UTC(),
StartRevision: 0,
LastRevision: 1788,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snap5 := Snapshot{
CreatedOn: time.Unix(now+4*interval, 0).UTC(),
StartRevision: 0,
LastRevision: 1688,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snap6 := Snapshot{
CreatedOn: time.Unix(now+5*interval, 0).UTC(),
StartRevision: 0,
LastRevision: 1588,
Kind: SnapshotKindFull,
SnapDir: snapdir,
}
snapList := SnapList{&snap4, &snap3, &snap1, &snap6, &snap2, &snap5}
sort.Sort(snapList)
expectedSnapList := SnapList{&snap1, &snap2, &snap3, &snap4, &snap5, &snap6}
for i := 0; i < len(snapList); i++ {
Expect(snapList[i].CreatedOn.Unix()).To(Equal(now + int64(i)*interval))
Expect(snapList[i]).Should(Equal(expectedSnapList[i]))
}
})
})

Context("when provied with list of snapshots where few have the same timestamp", func() {
It("sorts snapshot by creation time as well as start revision", func() {
interval := int64(5)
now := time.Now().Unix()
snapdir := fmt.Sprintf("Backup-%d", now)
snap1 := Snapshot{
CreatedOn: time.Unix(now, 0).UTC(),
StartRevision: 1001,
LastRevision: 1050,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snap2 := Snapshot{
CreatedOn: time.Unix(now+1*interval, 0).UTC(),
StartRevision: 1051,
LastRevision: 1200,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snap3 := Snapshot{
CreatedOn: time.Unix(now+1*interval, 0).UTC(),
StartRevision: 1201,
LastRevision: 1500,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snap4 := Snapshot{
CreatedOn: time.Unix(now+2*interval, 0).UTC(),
StartRevision: 1501,
LastRevision: 2000,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snap5 := Snapshot{
CreatedOn: time.Unix(now+2*interval, 0).UTC(),
StartRevision: 2001,
LastRevision: 2150,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snap6 := Snapshot{
CreatedOn: time.Unix(now+3*interval, 0).UTC(),
StartRevision: 2151,
LastRevision: 2160,
Kind: SnapshotKindDelta,
SnapDir: snapdir,
}
snapList := SnapList{&snap5, &snap2, &snap1, &snap4, &snap6, &snap3}
sort.Sort(snapList)
expectedSnapList := SnapList{&snap1, &snap2, &snap3, &snap4, &snap5, &snap6}
for i := 1; i < len(snapList); i++ {
Expect(snapList[i].CreatedOn.Unix()).Should(BeNumerically(">=", snapList[i-1].CreatedOn.Unix()))
Expect(snapList[i].StartRevision).Should(BeNumerically(">", snapList[i-1].StartRevision))
Expect(snapList[i]).Should(Equal(expectedSnapList[i]))
}
})

It("sorts snapshot in preference order of snap directory creation time followed by snapshot creation time and then start revision", func() {
interval := int64(5)
now := time.Now().Unix()
snapdir1 := fmt.Sprintf("Backup-%d", now)
snapdir2 := fmt.Sprintf("Backup-%d", now+2*interval)
snap1 := Snapshot{
CreatedOn: time.Unix(now, 0).UTC(),
StartRevision: 1001,
LastRevision: 1050,
Kind: SnapshotKindDelta,
SnapDir: snapdir1,
}
snap2 := Snapshot{
CreatedOn: time.Unix(now+1*interval, 0).UTC(),
StartRevision: 1051,
LastRevision: 1200,
Kind: SnapshotKindDelta,
SnapDir: snapdir1,
}
snap3 := Snapshot{
CreatedOn: time.Unix(now+1*interval, 0).UTC(),
StartRevision: 1201,
LastRevision: 1500,
Kind: SnapshotKindDelta,
SnapDir: snapdir1,
}
snap4 := Snapshot{
CreatedOn: time.Unix(now+2*interval, 0).UTC(),
StartRevision: 1501,
LastRevision: 2000,
Kind: SnapshotKindDelta,
SnapDir: snapdir2,
}
snap5 := Snapshot{
CreatedOn: time.Unix(now+2*interval, 0).UTC(),
StartRevision: 2001,
LastRevision: 2150,
Kind: SnapshotKindDelta,
SnapDir: snapdir2,
}
snap6 := Snapshot{
CreatedOn: time.Unix(now+3*interval, 0).UTC(),
StartRevision: 2151,
LastRevision: 2160,
Kind: SnapshotKindDelta,
SnapDir: snapdir1,
}
snapList := SnapList{&snap5, &snap2, &snap1, &snap4, &snap6, &snap3}
sort.Sort(snapList)
expectedSnapList := SnapList{&snap1, &snap2, &snap3, &snap6, &snap4, &snap5}
for i := 1; i < len(snapList); i++ {
Expect(snapList[i]).Should(Equal(expectedSnapList[i]))
}
})
})
Expand Down

0 comments on commit cc5bd9a

Please sign in to comment.