Exemplo n.º 1
0
func MetakvSet(path string, v interface{}) {
	raw, err := json.Marshal(v)
	if err != nil {
		log.Fatalf("Failed to marshal value for %s: %s\n%v",
			path, err.Error(), v)
	}

	err = metakv.Set(path, raw, nil)
	if err != nil {
		log.Fatalf("Failed to set %s: %s", path, err.Error())
	}
}
Exemplo n.º 2
0
func (c *CfgMetaKv) setRawLOCKED(key string, val []byte, cas uint64) (
	uint64, error) {
	path := c.keyToPath(key)

	log.Printf("cfg_metakv: Set path: %v", path)

	err := metakv.Set(path, val, nil) // TODO: Handle rev better.
	if err != nil {
		return 0, err
	}

	return 1, nil
}
Exemplo n.º 3
0
func (s *settingsManager) handleCompactionTrigger(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}
	_, rev, err := metakv.Get(indexCompactonMetaPath)
	if err != nil {
		s.writeError(w, err)
		return
	}

	newToken := time.Now().String()
	if err = metakv.Set(indexCompactonMetaPath, []byte(newToken), rev); err != nil {
		s.writeError(w, err)
		return
	}

	s.writeOk(w)
}
Exemplo n.º 4
0
func (c *CfgMetaKv) SetKey(key string, val []byte) (
    uint64, error) {
    rev, err := c.cfgMem.GetRev(key, 0)
        if err != nil {
            return 0, err
        }
    if rev == nil {
        err = metakv.Add(c.makeKey(key), val)
    } else {
        err = metakv.Set(c.makeKey(key), val, rev)
    }
    if err == nil {
        cas, err = c.cfgMem.Set(key, val, CAS_FORCE)
            if err != nil {
                return 0, err
            }
    }
}
Exemplo n.º 5
0
func (s *settingsManager) handleSettingsReq(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}

	if r.Method == "POST" {
		bytes, _ := ioutil.ReadAll(r.Body)

		config := s.config.FilterConfig(".settings.")
		current, rev, err := metakv.Get(common.IndexingSettingsMetaPath)
		if err == nil {
			if len(current) > 0 {
				config.Update(current)
			}
			err = config.Update(bytes)
		}

		if err != nil {
			s.writeError(w, err)
			return
		}

		//settingsConfig := config.FilterConfig(".settings.")
		newSettingsBytes := config.Json()
		if err = metakv.Set(common.IndexingSettingsMetaPath, newSettingsBytes, rev); err != nil {
			s.writeError(w, err)
			return
		}
		s.writeOk(w)
	} else if r.Method == "GET" {
		settingsConfig, err := common.GetSettingsConfig(s.config)
		if err != nil {
			s.writeError(w, err)
			return
		}
		s.writeJson(w, settingsConfig.FilterConfig(".settings.").Json())
	} else {
		s.writeError(w, errors.New("Unsupported method"))
		return
	}
}
Exemplo n.º 6
0
// set() splits a nodeDefs into multiple child metakv entries and must
// be invoked with c.m.Lock()'ed.
func (a *cfgMetaKvNodeDefsSplitHandler) set(
	c *CfgMetaKv, key string, val []byte, cas uint64) (uint64, error) {
	path := c.keyToPath(key)

	curEntry := c.splitEntries[key]

	if cas != 0 && cas != curEntry.cas {
		log.Printf("cfg_metakv: Set split, key: %v, cas mismatch: %x != %x",
			key, cas, curEntry.cas)

		return 0, &CfgCASError{}
	}

	var curNodeDefs NodeDefs

	if curEntry.data != nil && len(curEntry.data) > 0 {
		err := json.Unmarshal(curEntry.data, &curNodeDefs)
		if err != nil {
			return 0, err
		}
	}

	var nd NodeDefs

	err := json.Unmarshal(val, &nd)
	if err != nil {
		return 0, err
	}

	// Analyze which children were added, removed, updated.
	//
	added := map[string]bool{}
	removed := map[string]bool{}
	updated := map[string]bool{}

	for k, v := range nd.NodeDefs {
		if curNodeDefs.NodeDefs == nil ||
			curNodeDefs.NodeDefs[k] == nil {
			added[k] = true
		} else {
			if !reflect.DeepEqual(curNodeDefs.NodeDefs[k], v) {
				updated[k] = true
			}
		}
	}

	if curNodeDefs.NodeDefs != nil {
		for k, _ := range curNodeDefs.NodeDefs {
			if nd.NodeDefs[k] == nil {
				removed[k] = true
			}
		}
	}

	log.Printf("cfg_metakv: Set split, key: %v,"+
		" added: %v, removed: %v, updated: %v",
		key, added, removed, updated)

LOOP:
	for k, v := range nd.NodeDefs {
		if c.nodeUUID != "" && c.nodeUUID != v.UUID {
			// If we have a nodeUUID, only add/update our
			// nodeDef, where other nodes will each add/update
			// only their own nodeDef's.
			log.Printf("cfg_metakv: Set split, key: %v,"+
				" skipping other node UUID: %v, self nodeUUID: %s",
				key, v.UUID, c.nodeUUID)

			continue LOOP
		}

		childNodeDefs := NodeDefs{
			UUID:        nd.UUID,
			NodeDefs:    map[string]*NodeDef{},
			ImplVersion: nd.ImplVersion,
		}
		childNodeDefs.NodeDefs[k] = v

		val, err = json.Marshal(childNodeDefs)
		if err != nil {
			return 0, err
		}

		childPath := path + "/" + k

		log.Printf("cfg_metakv: Set split, key: %v, childPath: %v",
			key, childPath)

		err = metakv.Set(childPath, val, nil)
		if err != nil {
			return 0, err
		}

		break LOOP
	}

	// Remove composite children entries from metakv only if
	// caller was attempting removals only.  This should work as
	// the caller usually has read-compute-write logic that only
	// removes node defs and does not add/update node defs in the
	// same read-compute-write code path.
	//
	if len(added) <= 0 && len(updated) <= 0 && len(removed) > 0 {
		for nodeDefUUID := range removed {
			childPath := path + "/" + nodeDefUUID

			log.Printf("cfg_metakv: Set delete, childPath: %v", childPath)

			err = metakv.Delete(childPath, nil)
			if err != nil {
				return 0, err
			}
		}
	}

	casResult := c.lastSplitCAS + 1
	c.lastSplitCAS = casResult
	return casResult, err
}
Exemplo n.º 7
0
func (c *CfgMetaKv) Set(key string, val []byte, cas uint64) (
	uint64, error) {
	log.Printf("cfg_metakv: Set, key: %v, cas: %x", key, cas)

	path := c.keyToPath(key)

	c.m.Lock()
	defer c.m.Unlock()

	if cfgMetaKvSplitKeys[key] {
		curEntry := c.splitEntries[key]

		if cas != 0 && cas != curEntry.cas {
			return 0, &CfgCASError{}
		}

		var curNodeDefs NodeDefs

		if curEntry.data != nil && len(curEntry.data) > 0 {
			err := json.Unmarshal(curEntry.data, &curNodeDefs)
			if err != nil {
				return 0, err
			}
		}

		var nd NodeDefs

		err := json.Unmarshal(val, &nd)
		if err != nil {
			return 0, err
		}

		// Analyze which children were added, removed, updated.
		//
		added := map[string]bool{}
		removed := map[string]bool{}
		updated := map[string]bool{}

		for k, v := range nd.NodeDefs {
			if curNodeDefs.NodeDefs == nil ||
				curNodeDefs.NodeDefs[k] == nil {
				added[k] = true
			} else {
				if curNodeDefs.NodeDefs[k].UUID != v.UUID {
					updated[k] = true
				}
			}
		}

		if curNodeDefs.NodeDefs != nil {
			for k, _ := range curNodeDefs.NodeDefs {
				if nd.NodeDefs[k] == nil {
					removed[k] = true
				}
			}
		}

		// Update metakv with child entries.
		//
		if len(added) > 0 || len(updated) > 0 {
			for k, v := range nd.NodeDefs {
				childNodeDefs := NodeDefs{
					UUID:        nd.UUID,
					NodeDefs:    map[string]*NodeDef{},
					ImplVersion: nd.ImplVersion,
				}
				childNodeDefs.NodeDefs[k] = v

				val, err = json.Marshal(childNodeDefs)
				if err != nil {
					return 0, err
				}

				childPath := path + "/" + k

				log.Printf("cfg_metakv: Set split key: %v, childPath: %v",
					key, childPath)

				err = metakv.Set(childPath, val, nil)
				if err != nil {
					return 0, err
				}
			}
		}

		// Remove composite children entries from metakv only if
		// caller was attempting removals only.  This should work as
		// the caller usually has read-modify-write logic that only
		// removes node defs and does not add/update node defs in the
		// same read-modify-write code path.
		//
		if len(added) <= 0 && len(updated) <= 0 && len(removed) > 0 {
			for nodeDefUUID := range removed {
				err = metakv.Delete(path+"/"+nodeDefUUID, nil)
				if err != nil {
					return 0, err
				}
			}
		}

		casResult := c.lastSplitCAS + 1
		c.lastSplitCAS = casResult
		return casResult, err
	}

	rev, err := c.cfgMem.GetRev(key, cas)
	if err != nil {
		return 0, err
	}

	if rev == nil {
		err = metakv.Add(path, val)
	} else {
		err = metakv.Set(path, val, rev)
	}
	if err != nil {
		return 0, err
	}

	return c.cfgMem.Set(key, val, CFG_CAS_FORCE)
}