Exemple #1
0
func (c *conn) readResponses() {
	defer c.close()

	for {
		r, err := c.readR()
		if err != nil {
			c.clk.Lock()
			if c.err == nil {
				c.err = err
			}
			c.clk.Unlock()
			return
		}

		if r.ErrCode != nil && *r.ErrCode == proto.Response_REDIRECT {
			c.redirectAddr = pb.GetString(r.ErrDetail)
			c.redirected = true
		}

		tag := pb.GetInt32(r.Tag)
		flags := pb.GetInt32(r.Flags)

		c.cblk.Lock()
		ch, ok := c.cb[tag]
		if ok && ch == nil {
			c.cblk.Unlock()
			continue
		}
		if flags&Done != 0 {
			c.cb[tag] = nil, false
		}
		c.cblk.Unlock()

		if !ok {
			log.Printf(
				"%v unexpected: tag=%d flags=%d rev=%d path=%q value=%v len=%d err_code=%v err_detail=%q",
				ch,
				tag,
				flags,
				pb.GetInt64(r.Rev),
				pb.GetString(r.Path),
				r.Value,
				pb.GetInt32(r.Len),
				pb.GetInt32((*int32)(r.ErrCode)),
				pb.GetString(r.ErrDetail),
			)
			continue
		}

		if flags&Valid != 0 {
			ch <- r
		}

		if flags&Done != 0 {
			close(ch)
		}
	}
}
Exemple #2
0
func (c *conn) getdir(t *T, tx txn) {
	path := pb.GetString(t.Path)

	if g := c.getterFor(t); g != nil {
		ents, rev := g.Get(path)

		if rev == store.Missing {
			c.respond(t, Valid|Done, nil, noEnt)
			return
		}

		if rev != store.Dir {
			c.respond(t, Valid|Done, nil, notDir)
			return
		}

		sort.SortStrings(ents)
		offset := int(pb.GetInt32(t.Offset))
		if offset < 0 || offset >= len(ents) {
			c.respond(t, Valid|Done, nil, erange)
			return
		}

		e := ents[offset]
		c.respond(t, Valid|Done, tx.cancel, &R{Path: &e})
	}
}
Exemple #3
0
func (c *conn) walk(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	offset := pb.GetInt32(t.Offset)
	if offset < 0 {
		c.respond(t, Valid|Done, nil, erange)
		return
	}

	if g := c.getterFor(t); g != nil {
		var r R
		f := func(path, body string, rev int64) (stop bool) {
			if offset == 0 {
				r.Path = &path
				r.Value = []byte(body)
				r.Rev = &rev
				return true
			}
			offset--
			return false
		}
		if store.Walk(g, glob, f) {
			c.respond(t, Set|Valid|Done, nil, &r)
		} else {
			c.respond(t, Valid|Done, nil, erange)
		}
	}
}
Exemple #4
0
func (c *conn) events(t *T) (*Watch, os.Error) {
	cb, err := c.send(t)
	if err != nil {
		return nil, err
	}

	evs := make(chan *Event)
	w := &Watch{evs, c, cb, *t.Tag}
	go func() {
		for r := range cb {
			var ev Event
			if err := r.err(); err != nil {
				ev.Err = err
			} else {
				ev.Rev = pb.GetInt64(r.Rev)
				ev.Path = pb.GetString(r.Path)
				ev.Body = r.Value
				ev.Flag = pb.GetInt32(r.Flags)
			}
			evs <- &ev
		}
		close(evs)
	}()

	return w, nil
}
Exemple #5
0
// referenceValueToKey is the same as protoToKey except the input is a
// PropertyValue_ReferenceValue instead of a Reference.
func referenceValueToKey(r *pb.PropertyValue_ReferenceValue) (k *Key, err error) {
	appID := proto.GetString(r.App)
	for _, e := range r.Pathelement {
		k = &Key{
			kind:     proto.GetString(e.Type),
			stringID: proto.GetString(e.Name),
			intID:    proto.GetInt64(e.Id),
			parent:   k,
			appID:    appID,
		}
		if !k.valid() {
			return nil, ErrInvalidKey
		}
	}
	return
}
Exemple #6
0
func (c *conn) watch(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	var w *store.Watch
	rev := pb.GetInt64(t.Rev)
	if rev == 0 {
		w, err = store.NewWatch(c.s.St, glob), nil
	} else {
		w, err = store.NewWatchFrom(c.s.St, glob, rev)
	}

	switch err {
	case nil:
		// nothing
	case store.ErrTooLate:
		c.respond(t, Valid|Done, nil, tooLate)
	default:
		c.respond(t, Valid|Done, nil, errResponse(err))
	}

	go func() {
		defer w.Stop()

		// TODO buffer (and possibly discard) events
		for {
			select {
			case ev := <-w.C:
				if closed(w.C) {
					return
				}

				r := R{
					Path:  &ev.Path,
					Value: []byte(ev.Body),
					Rev:   &ev.Seqn,
				}

				var flag int32
				switch {
				case ev.IsSet():
					flag = Set
				case ev.IsDel():
					flag = Del
				}

				c.respond(t, Valid|flag, tx.cancel, &r)

			case <-tx.cancel:
				c.closeTxn(*t.Tag)
				return
			}
		}
	}()
}
Exemple #7
0
// Create creates a channel and returns a token for use by the client.
// The clientID is an appication-provided string used to identify the client.
func Create(c appengine.Context, clientID string) (token string, err error) {
	req := &channel_proto.CreateChannelRequest{
		ApplicationKey: &clientID,
	}
	resp := &channel_proto.CreateChannelResponse{}
	err = c.Call(service, "CreateChannel", req, resp, nil)
	token = proto.GetString(resp.ClientId)
	return
}
Exemple #8
0
// loadMapEntry converts a Property into an entry of an existing Map,
// or into an element of a slice-valued Map entry.
func loadMapEntry(m Map, k *Key, p *pb.Property) os.Error {
	var (
		result    interface{}
		sliceType reflect.Type
	)
	switch {
	case p.Value.Int64Value != nil:
		if p.Meaning != nil && *p.Meaning == pb.Property_GD_WHEN {
			result = Time(*p.Value.Int64Value)
			sliceType = reflect.TypeOf([]Time(nil))
		} else {
			result = *p.Value.Int64Value
			sliceType = reflect.TypeOf([]int64(nil))
		}
	case p.Value.BooleanValue != nil:
		result = *p.Value.BooleanValue
		sliceType = reflect.TypeOf([]bool(nil))
	case p.Value.StringValue != nil:
		if p.Meaning != nil && *p.Meaning == pb.Property_BLOB {
			result = []byte(*p.Value.StringValue)
			sliceType = reflect.TypeOf([][]byte(nil))
		} else if p.Meaning != nil && *p.Meaning == pb.Property_BLOBKEY {
			result = appengine.BlobKey(*p.Value.StringValue)
			sliceType = reflect.TypeOf([]appengine.BlobKey(nil))
		} else {
			result = *p.Value.StringValue
			sliceType = reflect.TypeOf([]string(nil))
		}
	case p.Value.DoubleValue != nil:
		result = *p.Value.DoubleValue
		sliceType = reflect.TypeOf([]float64(nil))
	case p.Value.Referencevalue != nil:
		key, err := referenceValueToKey(p.Value.Referencevalue)
		if err != nil {
			return err
		}
		result = key
		sliceType = reflect.TypeOf([]*Key(nil))
	default:
		return nil
	}
	name := proto.GetString(p.Name)
	if proto.GetBool(p.Multiple) {
		var s reflect.Value
		if x := m[name]; x != nil {
			s = reflect.ValueOf(x)
		} else {
			s = reflect.MakeSlice(sliceType, 0, 0)
		}
		s = reflect.Append(s, reflect.ValueOf(result))
		m[name] = s.Interface()
	} else {
		m[name] = result
	}
	return nil
}
Exemple #9
0
func (c *CheckResult) stringMap() (smap map[string]string) {
	smap = map[string]string{
		"Hostname":    fmt.Sprintf("%s", proto.GetString(c.Hostname)),
		"ServiceName": fmt.Sprintf("%s", proto.GetString(c.ServiceName)),
		"Status":      fmt.Sprintf("%d", int32((*c.Status))),
		"CheckPassive": fmt.Sprintf("%d", func() (i int32) {
			if proto.GetBool(c.CheckPassive) {
				i = 1
			} else {
				i = 0
			}
			return i
		}()),
		"CheckOutput":    fmt.Sprintf("%s", strings.Trim(strconv.Quote(proto.GetString(c.CheckOutput)), "\"")),
		"StartTimestamp": fmt.Sprintf("%f", float64(proto.GetInt64(c.StartTimestamp))/1000000000),
		"EndTimestamp":   fmt.Sprintf("%f", float64(proto.GetInt64(c.EndTimestamp))/1000000000),
		"TimeNow":        fmt.Sprintf("%d", time.Seconds()),
	}
	return smap
}
Exemple #10
0
// protoToRecord converts a RequestLog, the internal Protocol Buffer
// representation of a single request-level log, to a Record, its
// corresponding external representation.
func protoToRecord(rl *log_proto.RequestLog) *Record {
	return &Record{
		AppID:             *rl.AppId,
		VersionID:         *rl.VersionId,
		RequestID:         *rl.RequestId,
		IP:                *rl.Ip,
		Nickname:          proto.GetString(rl.Nickname),
		StartTime:         *rl.StartTime,
		EndTime:           *rl.EndTime,
		Latency:           *rl.Latency,
		MCycles:           *rl.Mcycles,
		Method:            *rl.Method,
		Resource:          *rl.Resource,
		HTTPVersion:       *rl.HttpVersion,
		Status:            *rl.Status,
		ResponseSize:      *rl.ResponseSize,
		Referrer:          proto.GetString(rl.Referrer),
		UserAgent:         proto.GetString(rl.UserAgent),
		URLMapEntry:       *rl.UrlMapEntry,
		Combined:          *rl.Combined,
		APIMCycles:        proto.GetInt64(rl.ApiMcycles),
		Host:              proto.GetString(rl.Host),
		Cost:              proto.GetFloat64(rl.Cost),
		TaskQueueName:     proto.GetString(rl.TaskQueueName),
		TaskName:          proto.GetString(rl.TaskName),
		WasLoadingRequest: proto.GetBool(rl.WasLoadingRequest),
		PendingTime:       proto.GetInt64(rl.PendingTime),
		Finished:          proto.GetBool(rl.Finished),
		AppLogs:           protoToAppLogs(rl.Line),
	}
}
Exemple #11
0
// loadStruct converts an EntityProto into an existing struct.
// It returns an error if the destination struct is unable to hold the entity.
func loadStruct(sv reflect.Value, k *Key, e *pb.EntityProto) os.Error {
	var fieldName, reason string
	for _, p := range e.Property {
		if errStr := loadStructField(sv, p); errStr != "" {
			fieldName, reason = proto.GetString(p.Name), errStr
		}
	}
	for _, p := range e.RawProperty {
		if errStr := loadStructField(sv, p); errStr != "" {
			fieldName, reason = proto.GetString(p.Name), errStr
		}
	}
	if reason != "" {
		return &ErrFieldMismatch{
			Key:        k,
			StructType: sv.Type(),
			FieldName:  fieldName,
			Reason:     reason,
		}
	}
	return nil
}
Exemple #12
0
func (c *conn) getdir(t *T, tx txn) {
	path := pb.GetString(t.Path)

	if g := c.getterFor(t); g != nil {
		go func() {
			ents, rev := g.Get(path)

			if rev == store.Missing {
				c.respond(t, Valid|Done, nil, noEnt)
				return
			}

			if rev != store.Dir {
				c.respond(t, Valid|Done, nil, notDir)
				return
			}

			offset := int(pb.GetInt32(t.Offset))
			limit := int(pb.GetInt32(t.Limit))

			if limit <= 0 {
				limit = len(ents)
			}

			if offset < 0 {
				offset = 0
			}

			end := offset + limit
			if end > len(ents) {
				end = len(ents)
			}

			for _, e := range ents[offset:end] {
				select {
				case <-tx.cancel:
					c.closeTxn(*t.Tag)
					return
				default:
				}

				c.respond(t, Valid, tx.cancel, &R{Path: &e})
			}

			c.respond(t, Done, nil, &R{})
		}()
	}
}
Exemple #13
0
func (c *conn) get(t *T, tx txn) {
	if g := c.getterFor(t); g != nil {
		v, rev := g.Get(pb.GetString(t.Path))
		if rev == store.Dir {
			c.respond(t, Valid|Done, nil, isDir)
			return
		}

		var r R
		r.Rev = &rev
		if len(v) == 1 { // not missing
			r.Value = []byte(v[0])
		}
		c.respond(t, Valid|Done, nil, &r)
	}
}
Exemple #14
0
func (c *conn) walk(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	offset := pb.GetInt32(t.Offset)

	var limit int32 = math.MaxInt32
	if t.Limit != nil {
		limit = pb.GetInt32(t.Limit)
	}

	if g := c.getterFor(t); g != nil {
		go func() {
			f := func(path, body string, rev int64) (stop bool) {
				select {
				case <-tx.cancel:
					c.closeTxn(*t.Tag)
					return true
				default:
				}

				if offset <= 0 && limit > 0 {
					var r R
					r.Path = &path
					r.Value = []byte(body)
					r.Rev = &rev
					c.respond(t, Valid|Set, tx.cancel, &r)

					limit--
				}

				offset--
				return false
			}

			stopped := store.Walk(g, glob, f)

			if !stopped {
				c.respond(t, Done, nil, &R{})
			}
		}()
	}
}
Exemple #15
0
func (c *conn) wait(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	var w *store.Watch
	rev := pb.GetInt64(t.Rev)
	if rev == 0 {
		w, err = store.NewWatch(c.s.St, glob), nil
	} else {
		w, err = store.NewWatchFrom(c.s.St, glob, rev)
	}

	switch err {
	case nil:
		// nothing
	case store.ErrTooLate:
		c.respond(t, Valid|Done, nil, tooLate)
	default:
		c.respond(t, Valid|Done, nil, errResponse(err))
	}

	go func() {
		defer w.Stop()
		ev := <-w.C
		r := R{
			Path:  &ev.Path,
			Value: []byte(ev.Body),
			Rev:   &ev.Seqn,
		}

		var flag int32
		switch {
		case ev.IsSet():
			flag = Set
		case ev.IsDel():
			flag = Del
		}

		c.respond(t, Valid|flag, nil, &r)
	}()
}
Exemple #16
0
func (t *txn) stat() {
	if t.c.access == false {
		t.respondOsError(os.EACCES)
		return
	}

	go func() {
		g, err := t.getter()
		if err != nil {
			t.respondOsError(err)
			return
		}

		len, rev := g.Stat(proto.GetString(t.req.Path))
		t.resp.Len = &len
		t.resp.Rev = &rev
		t.respond()
	}()
}
Exemple #17
0
// Receives messages from remote client and acts upon them if appropriate.
func (cl *client) RecvLoop(cs chan<- Msg) {
	defer logAndClose(cl.conn)
	for {
		msg, err := readMessage(cl.conn)
		if err != nil {
			// Remove client if something went wrong
			cs <- removeClientMsg{cl, "Reading message from client failed: " + err.String()}
			return
		}
		switch *msg.Type {
		case protocol.Message_Type(protocol.Message_DISCONNECT):
			cs <- removeClientMsg{cl, proto.GetString(msg.Disconnect.ReasonStr)}
			return
		default:
			// TODO: If no proper avatar has been started, this will block, fix?
			// We could check cl.avatar for nil
			cl.RecvQueue <- msg // Forward to avatar
		}
	}
}
Exemple #18
0
func main() {
	flag.Usage = usage
	flag.Parse()
	if *helpShort || *helpLong || flag.NArg() == 0 {
		flag.Usage()
		os.Exit(1)
	}

	fds, err := parser.ParseFiles(flag.Args(), strings.Split(*importPath, ",", -1))
	if err != nil {
		log.Exitf("Failed parsing: %v", err)
	}
	resolver.ResolveSymbols(fds)
	fmt.Println("-----")
	proto.MarshalText(os.Stdout, fds)
	fmt.Println("-----")

	// Find plugin.
	pluginPath := fullPath(*pluginBinary, strings.Split(os.Getenv("PATH"), ":", -1))
	if pluginPath == "" {
		log.Exitf("Failed finding plugin binary %q", *pluginBinary)
	}

	// Start plugin subprocess.
	pluginIn, meOut, err := os.Pipe()
	if err != nil {
		log.Exitf("Failed creating pipe: %v", err)
	}
	meIn, pluginOut, err := os.Pipe()
	if err != nil {
		log.Exitf("Failed creating pipe: %v", err)
	}
	pid, err := os.ForkExec(pluginPath, nil, nil, "/", []*os.File{pluginIn, pluginOut, os.Stderr})
	if err != nil {
		log.Exitf("Failed forking plugin: %v", err)
	}
	pluginIn.Close()
	pluginOut.Close()

	// Send request.
	cgRequest := &plugin.CodeGeneratorRequest{
		FileToGenerate: flag.Args(),
		// TODO: proto_file should be topologically sorted (bottom-up)
		ProtoFile: fds.File,
	}
	buf, err := proto.Marshal(cgRequest)
	if err != nil {
		log.Exitf("Failed marshaling CG request: %v", err)
	}
	_, err = meOut.Write(buf)
	if err != nil {
		log.Exitf("Failed writing CG request: %v", err)
	}
	meOut.Close()

	w, err := os.Wait(pid, 0)
	if err != nil {
		log.Exitf("Failed waiting for plugin: %v", err)
	}
	if w.ExitStatus() != 0 {
		log.Exitf("Plugin exited with status %d", w.ExitStatus())
	}

	// Read response.
	cgResponse := new(plugin.CodeGeneratorResponse)
	if buf, err = ioutil.ReadAll(meIn); err != nil {
		log.Exitf("Failed reading CG response: %v", err)
	}
	if err = proto.Unmarshal(buf, cgResponse); err != nil {
		log.Exitf("Failed unmarshaling CG response: %v", err)
	}

	// TODO: check cgResponse.Error

	// TODO: write files
	for _, f := range cgResponse.File {
		fmt.Printf("--[ %v ]--\n", proto.GetString(f.Name))
		fmt.Println(proto.GetString(f.Content))
	}
	fmt.Println("-----")
}
Exemple #19
0
func newError(t *txn) *Error {
	return &Error{
		Err:    *t.resp.ErrCode,
		Detail: proto.GetString(t.resp.ErrDetail),
	}
}
Exemple #20
0
// loadStructField converts a Property into a field of an existing struct,
// or into an element of a slice-typed struct field.
// It returns an error message, or "" for success.
func loadStructField(sv reflect.Value, p *pb.Property) string {
	fieldName := proto.GetString(p.Name)
	v := sv.FieldByName(fieldName)
	if !v.IsValid() {
		return "no such struct field"
	}
	if unexported(fieldName) {
		return "unexported struct field"
	}
	var slice reflect.Value
	if proto.GetBool(p.Multiple) {
		if v.Kind() != reflect.Slice {
			return "multiple-valued property requires a slice field type"
		}
		if v.Len() > maxSliceFieldLen-1 {
			return "slice is too long"
		}
		slice = v
		v = reflect.New(v.Type().Elem()).Elem()
	}
	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if p.Value.Int64Value == nil {
			return typeMismatchReason(p, v)
		}
		x := *p.Value.Int64Value
		if v.OverflowInt(x) {
			return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
		}
		v.SetInt(x)
	case reflect.Bool:
		if p.Value.BooleanValue == nil {
			return typeMismatchReason(p, v)
		}
		v.SetBool(*p.Value.BooleanValue)
	case reflect.String:
		if p.Value.StringValue == nil {
			return typeMismatchReason(p, v)
		}
		v.SetString(*p.Value.StringValue)
	case reflect.Float32, reflect.Float64:
		if p.Value.DoubleValue == nil {
			return typeMismatchReason(p, v)
		}
		x := *p.Value.DoubleValue
		if v.OverflowFloat(x) {
			return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
		}
		v.SetFloat(x)
	case reflect.Ptr:
		if _, ok := v.Interface().(*Key); !ok {
			return typeMismatchReason(p, v)
		}
		if p.Value.Referencevalue == nil {
			return typeMismatchReason(p, v)
		}
		k, err := referenceValueToKey(p.Value.Referencevalue)
		if err != nil {
			return "stored key was invalid"
		}
		v.Set(reflect.ValueOf(k))
	case reflect.Slice:
		if _, ok := v.Interface().([]byte); !ok {
			return typeMismatchReason(p, v)
		}
		if p.Value.StringValue == nil {
			return typeMismatchReason(p, v)
		}
		b := []byte(*p.Value.StringValue)
		v.Set(reflect.ValueOf(b))
	default:
		return typeMismatchReason(p, v)
	}
	if slice.IsValid() {
		slice.Set(reflect.Append(slice, v))
	}
	return ""
}
Exemple #21
0
func (c *conn) stat(t *T, tx txn) {
	if g := c.getterFor(t); g != nil {
		ln, rev := g.Stat(pb.GetString(t.Path))
		c.respond(t, Valid|Done, nil, &R{Len: &ln, Rev: &rev})
	}
}