예제 #1
0
// etcd needs to be initialized beforehand
func TestControllerInitEtcdLayout(t *testing.T) {
	etcdClient := etcd.NewClient([]string{"http://localhost:4001"})

	tests := []struct {
		name          string
		numberOfTasks uint64
	}{
		{"test-1", 2},
		{"test-2", 4},
	}

	for i, tt := range tests {
		c := New(tt.name, etcdClient, tt.numberOfTasks, []string{"Parents", "Children"})
		c.InitEtcdLayout()

		for taskID := uint64(0); taskID < tt.numberOfTasks; taskID++ {
			key := etcdutil.FreeTaskPath(c.name, strconv.FormatUint(taskID, 10))
			if _, err := etcdClient.Get(key, false, false); err != nil {
				t.Errorf("task %d: etcdClient.Get %v failed: %v", i, key, err)
			}
			key = etcdutil.MetaPath(c.name, taskID)
			if _, err := etcdClient.Get(key, false, false); err != nil {
				t.Errorf("task %d: etcdClient.Get %v failed: %v", i, key, err)
			}
		}

		c.DestroyEtcdLayout()
	}
}
예제 #2
0
// watch meta flag and receive any notification.
func (f *framework) watchMeta() {
	watchPath := etcdutil.MetaPath(f.name, f.taskID)

	// The function parses the watch response of meta flag, and passes the result
	// to central event handling.
	responseHandler := func(resp *etcd.Response) {
		// Note: Why "get"?
		// We first try to get the index. If there's value in it, we also parse it.
		if resp.Action != "set" && resp.Action != "get" {
			return
		}
		epoch, taskID, linkType, meta, err := parseMetaValue(resp.Node.Value)
		if err != nil {
			f.log.Panicf("parseMetaValue failed: %v", err)
		}
		f.metaChan <- &metaChange{
			from:     taskID,
			epoch:    epoch,
			linkType: linkType,
			meta:     meta,
		}
	}

	f.metaWatchStop = make(chan bool, 1)
	// Need to pass in taskID to make it work. Didn't know why.
	err := etcdutil.WatchMeta(f.etcdClient, watchPath, f.metaWatchStop, responseHandler)
	if err != nil {
		f.log.Panicf("WatchMeta failed. path: %s, err: %v", watchPath, err)
	}
}
예제 #3
0
func (f *framework) FlagMeta(ctx context.Context, linkType, meta string) {
	epoch, ok := ctx.Value(epochKey).(uint64)
	if !ok {
		f.log.Panicf("Can not find epochKey in FlagMeta, epoch: %d", epoch)
	}
	// send the meta change notification to every task of specified link type.
	for _, id := range f.topology[linkType].GetNeighbors(epoch) {
		// The value is made of "epoch-fromID-metadata"
		//
		// Epoch is prepended to meta. When a new one starts and replaces
		// the old one, it doesn't need to handle previous things, whose
		// epoch is smaller than current one.
		value := fmt.Sprintf("%d-%d-%s-%s", epoch, f.taskID, linkType, meta)
		_, err := f.etcdClient.Set(etcdutil.MetaPath(f.name, id), value, 0)
		if err != nil {
			f.log.Panicf("etcdClient.Set failed; key: %s, value: %s, error: %v",
				etcdutil.MetaPath(f.name, id), value, err)
		}
	}
}
예제 #4
0
func (c *Controller) InitEtcdLayout() error {
	// Initilize the job epoch to 0
	etcdutil.MustCreate(c.etcdclient, c.logger, etcdutil.EpochPath(c.name), "0", 0)
	c.setupWatchOnJobStatus()
	// initiate etcd data layout for tasks
	// currently it creates as many unassigned tasks as task masters.
	for i := uint64(0); i < c.numOfTasks; i++ {
		key := etcdutil.FreeTaskPath(c.name, strconv.FormatUint(i, 10))
		etcdutil.MustCreate(c.etcdclient, c.logger, key, "", 0)
		key = etcdutil.MetaPath(c.name, i)
		etcdutil.MustCreate(c.etcdclient, c.logger, key, "", 0)
	}
	return nil
}