PetSet returns valid replica count in status

If the first pod is not healthy and next pods are not yet created, do
not provide the status with incorrect replica count
pull/6/head
Maciej Kwiek 2016-09-06 13:50:32 +03:00
parent 13a0ce6822
commit 0bec588202
4 changed files with 31 additions and 4 deletions

View File

@ -248,7 +248,7 @@ func (f *fakePetClient) deletePetAtIndex(index int) {
}
func (f *fakePetClient) setHealthy(index int) error {
if len(f.pets) < index {
if len(f.pets) <= index {
return fmt.Errorf("Index out of range, len %v index %v", len(f.pets), index)
}
f.pets[index].pod.Status.Phase = api.PodRunning

View File

@ -81,6 +81,15 @@ type petSyncer struct {
blockingPet *pcb
}
// errUnhealthyPet is returned when a we either know for sure a pet is unhealthy,
// or don't know its state but assume it is unhealthy. It's used as a signal to the caller for further operations like updating status.replicas.
// This is not a fatal error.
type errUnhealthyPet string
func (e errUnhealthyPet) Error() string {
return string(e)
}
// Sync syncs the given pet.
func (p *petSyncer) Sync(pet *pcb) error {
if pet == nil {
@ -103,8 +112,9 @@ func (p *petSyncer) Sync(pet *pcb) error {
return p.Update(realPet, pet)
}
if p.blockingPet != nil {
glog.Infof("Create of %v in PetSet %v blocked by unhealthy pet %v", pet.pod.Name, pet.parent.Name, p.blockingPet.pod.Name)
return nil
message := errUnhealthyPet(fmt.Sprintf("Create of %v in PetSet %v blocked by unhealthy pet %v", pet.pod.Name, pet.parent.Name, p.blockingPet.pod.Name))
glog.Info(message)
return message
}
// This is counted as a create, even if it fails. We can't skip indices
// because some pets might allocate a special role to earlier indices.

View File

@ -348,7 +348,14 @@ func (psc *PetSetController) syncPetSet(ps *apps.PetSet, pets []*api.Pod) (int,
case deletePet:
err = petManager.Delete(pet)
}
if err != nil {
switch err.(type) {
case errUnhealthyPet:
// We are not passing this error up, but we don't increment numPets if we encounter it,
// since numPets directly translates to petset.status.replicas
continue
case nil:
continue
default:
it.errs = append(it.errs, err)
}
}

View File

@ -267,3 +267,13 @@ func TestPetSetBlockingPetIsCleared(t *testing.T) {
t.Errorf("Unexpected blocking pet, err %v: %+v", err, p)
}
}
// TODO(mkwiek): test if the petset.Status.Replicas is actually correct
func TestPetSetReplicaCount(t *testing.T) {
psc, fc := newFakePetSetController()
ps := newPetSet(3)
i, _ := psc.syncPetSet(ps, fc.getPodList())
if i != len(fc.getPodList()) {
t.Errorf("syncPetSet should return actual amount of pods")
}
}