Ejemplo n.º 1
0
func (s *Server) mkChServer(conn InstConn, args []reflect.Value, enc *msgpack.Encoder) (err error) {
	typeChanDesc := reflect.TypeOf(&ChannelDescriptor{})
	for i, arg := range args {
		if arg.Type() != typeChanDesc {
			continue
		}
		chd := arg.Interface().(*ChannelDescriptor)
		// criar channel. Value
		ch := chd.Make(true)
		// substituir o ChannelDescriptor pelo channel criado
		args[i] = ch
		// criar sessão/instância
		instname, err := rand.Chars(16, rand.NumberLetters, "go")
		if err != nil {
			return e.Forward(err)
		}
		owners := auth.NewPlainTextCredentials()
		err = owners.Add(conn.Auth())
		if err != nil {
			return e.Forward(err)
		}
		err = s.Insts.NewChValueInstance(conn.SessionName(), instname, ch, chd.Dir, owners)
		if err != nil {
			return e.Forward(err)
		}

		// envia-las
		err = enc.Encode(instname)
		if err != nil {
			return e.Forward(err)
		}
	}
	return nil
}
Ejemplo n.º 2
0
func (vs *VirtualServer) SendToQueue(f interface{}, args ...interface{}) error {
	rnd, err := rand.Chars(10, rand.NumberLetters, "go")
	if err != nil {
		return e.Forward(err)
	}

	job := job.NewSimple(vs.VirtualServerName+rnd, vs.Prio, f, args...)

	vs.status.Log(status.Verbose, "Add job %v for %v to queue %v.", job.Name(), vs.VirtualServerName, vs.Prio)

	err = vs.Queue.Add(job)
	if err != nil {
		return e.Forward(err)
	}

	vs.status.Log(status.Verbose, "Waiting job %v return.", job.Name())

	job.Returns(&err)
	if err != nil {
		return e.Forward(err)
	}

	vs.status.Log(status.Verbose, "Job %v returned.", job.Name())
	return nil
}
Ejemplo n.º 3
0
func (p *protoServer) newInst(sess string, a auth.Auth, obj string, args ...interface{}) (string, error) {
	val, err := p.Cons.Construct(obj, args...)
	if err != nil {
		return "", e.Forward(err)
	}
	inst, err := rand.Chars(16, rand.NumberLetters, "go")
	if err != nil {
		return "", e.Forward(err)
	}
	owners := auth.NewPlainTextCredentials()
	err = owners.Add(a)
	if err != nil {
		return "", e.Forward(err)
	}
	err = p.Insts.New(sess, inst, val, owners)
	if err != nil {
		return "", e.Forward(err)
	}
	return inst, nil
}
Ejemplo n.º 4
0
func (d *Daemon) monitor() {
	go func() {
		d.monitoring = true
		var tries int
		unmonitor := true
	F:
		for {
			select {
			case <-time.After(d.Sleep):
				if d.Tries != 0 && tries > d.Tries+1 {
					d.monitoring = false
					if unmonitor {
						d.status.LogAndEmail(status.Normal, "", "Unmonitor daemon %v.", d.DaemonName)
						unmonitor = false
						continue F
					}
					continue F
				}
				d.changePid()
				if d.pid == -1 {
					d.status.LogAndEmail(status.Normal, "", "No pid file %v for %v.", d.PidFile, d.DaemonName)
					d.running = false
				} else {
					err := syscall.Kill(d.pid, 0)
					if err != nil && err.Error() == "no such process" {
						d.status.LogAndEmail(status.Normal, "", "%v process is gone.", d.DaemonName)
						d.running = false
					} else if err != nil {
						d.status.Log(status.Verbose, "Monitor failed for %v with error: %v", d.DaemonName, e.Trace(e.New(err)))
						d.running = false
					} else {
						d.running = true
					}
				}
				if d.running {
					err := d.ping()
					if e.Equal(err, ErrPingFailed) {
						d.running = false
					} else if err != nil && !e.Equal(err, ErrProtoNotSupported) && !e.Equal(err, ErrUrlIsEmpty) {
						d.status.Log(status.Verbose, "Monitor ping failed for %v with error: %v", d.DaemonName, e.Trace(e.Forward(err)))
						d.running = false
					}
					p, err := event.ProbeProcess(d.pid)
					if e.Equal(err, "process not found") {
						d.status.LogAndEmail(status.Normal, "", "%v process is gone.", d.DaemonName)
						d.running = false
					} else if err != nil {
						d.status.Log(status.Verbose, "ProbeCurrentProcess failed with error: %v", err)
					} else {
						d.SendEvent(p)
					}
				}
				if !d.running {
					tries++
					rnd, err := rand.Chars(10, rand.NumberLetters, "go")
					if err != nil {
						d.status.Log(status.Verbose, "Can't generate the job name for %v. Error: %v", d.DaemonName, e.Trace(e.Forward(err)))
						continue
					}
					job := job.NewSimple(d.DaemonName+rnd, d.Prio, func() error {
						err := d.restartProcess()
						if err != nil {
							d.status.LogAndEmail(status.Normal, "", "Can't restart process %v.", d.DaemonName)
							return e.Forward(err)
						}
						return nil
					})
					d.status.Log(status.Verbose, "Add job %v for %v to queue %v.", job.Name(), d.DaemonName, d.Prio)
					d.Queue.Add(job)
					d.status.Log(status.Verbose, "Waiting job %v return.", job.Name())
					job.Returns(&err)
					if err != nil {
						continue
					}
					d.status.LogAndEmail(status.Normal, "", "Restart command sent to %v.", d.DaemonName)
				} else {
					d.status.Log(status.Verbose, "%v process is running.", d.DaemonName)
					tries = 0
				}
			case <-d.killMonitor:
				d.status.Log(status.Normal, "Monitor %v stopped.", d.DaemonName)
				return
			}
		}
	}()
}
Ejemplo n.º 5
0
func MakeFile(pkg, pkgout, src string, debug bool) (*File, error) {
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
	if err != nil {
		return nil, e.New(err)
	}
	v := &Visitor{
		src:         src,
		Struct:      make(map[string]*Strct),
		Cmap:        ast.NewCommentMap(fset, f, f.Comments),
		StructOrder: make([]*Strct, 0),
		Pkgs:        NewPkgs(),
	}
	v.Pkgs.Have("crypto/tls")
	v.Pkgs.Have("fmt")
	v.Pkgs.Have("log")
	v.Pkgs.Have("reflect")
	v.Pkgs.Have("tls")
	v.Pkgs.Have("time")
	v.Pkgs.Have("github.com/fcavani/e")
	v.Pkgs.Have("github.com/fcavani/gormethods/auth")
	v.Pkgs.Have("github.com/fcavani/gormethods/client")
	v.Pkgs.Have("gopkg.in/vmihailenco/msgpack.v2")

	ast.Walk(v, f)

	file := &File{
		Package:     f.Name.Name,
		Debug:       debug,
		PkgComplete: f.Name.Name,
		Pkgs:        v.Pkgs.Packages(),
	}

	if pkg != "" {
		file.PkgComplete = pkg
	}

	if pkgout != "" {
		file.Package = pkgout
	}

	objs := make(map[string]*Object)
	order := make([]string, 0)
	for _, f := range v.Functions {
		u := utf8string.NewString(f.RecvType)
		if u.RuneCount() > 0 && !unicode.IsUpper(u.At(0)) {
			continue
		}
		if f.RecvType == "" {
			continue
		}
		if FuncForbiden(f.Name) {
			continue
		}
		obj, found := objs[f.RecvType]
		if !found {
			function, err := makeFunction(f)
			if err != nil {
				return nil, e.Forward(err)
			}
			t := f.RecvType
			if f.PtrRecv {
				t = "*" + t
			}
			strct, found := v.Struct[f.RecvType]
			if !found {
				return nil, e.New("struct %v not found", f.RecvType)
			}
			objs[f.RecvType] = &Object{
				Name:       f.RecvType,
				NameClient: f.RecvType + "Client",
				RecvVar:    f.Recv,
				RecvType:   t,
				Functions:  []*Function{function},
				Type:       makeType(src, strct.Type),
				Comments:   strings.Replace(strct.Comments, f.RecvType, f.RecvType+"Client", -1),
			}
			v.Struct[f.RecvType].FunctionCount++
			order = append(order, f.RecvType)
		} else {
			function, err := makeFunction(f)
			if err != nil {
				return nil, e.Forward(err)
			}
			obj.Functions = append(obj.Functions, function)
		}
	}

	for _, s := range v.StructOrder {
		if s.FunctionCount == 0 {
			first, err := rand.Chars(1, rand.Letters, "go")
			if err != nil {
				return nil, e.Push(err, "can't create a name to the receiver for the struct")
			}
			recv, err := rand.Chars(2, rand.NumberLetters, "go")
			if err != nil {
				return nil, e.Push(err, "can't create a name to the receiver for the struct")
			}
			recv = strings.ToLower(first + recv)
			objs[s.Name] = &Object{
				Name:       s.Name,
				NameClient: s.Name + "Client",
				RecvVar:    recv,
				RecvType:   s.Name,
				Functions:  nil,
				Type:       makeType(src, s.Type),
				Comments:   strings.Replace(s.Comments, s.Name, s.Name+"Client", -1),
			}
		}
	}

	for _, s := range v.StructOrder {
		if obj, found := objs[s.Name]; found {
			file.Objects = append(file.Objects, obj)
		} else {
			return nil, e.New("object not found: %v", s.Name)
		}
	}

	return file, nil
}
Ejemplo n.º 6
0
func (s *Server) protoCall(conn InstConn) (err error) {
	enc := conn.Encoder()
	dec := conn.Decoder()
	defer func() {
		if err != nil {
			err = enc.Encode(&respCall{Err: err})
			if err != nil {
				log.ProtoLevel().Tag("server", "gormethods").Printf("Encode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), err)
				err = e.Push(err, ErrWire)
			}
		}
	}()

	inst, err := s.Insts.Get(conn.SessionName(), conn.InstanceName())
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Error getting the instance %v/%v: %v", conn.SessionName(), conn.InstanceName(), e.Forward(err))
		err = e.Forward(err)
		return
	}

	if inst.Type() != WithValue {
		log.Tag("server", "gormethods").Errorf("Instance %v/%v is of wrong type", conn.SessionName(), conn.InstanceName())
		return e.New("instance is of wrong type")
	}

	log.ProtoLevel().Tag("gormethods", "server", "call").Printf("Call %v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()))

	var req reqCall
	err = dec.Decode(&req)
	if e.Find(err, io.EOF) >= 0 {
		return e.Push(err, ErrWire)
	} else if err != nil {
		log.ProtoLevel().Tag("server", "gormethods").Printf("Decode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), err)
		err = e.Push(err, ErrWire)
		return
	}

	// Tratar argumentos (req.Args) com channel

	// 	criar channel
	// 	recebe do channel envia pelo conn
	// 	recebe do conn envia para channel
	// 	(faz isso até fechar o channel em um dos lados)

	// substutui em req.Args os channels

	// Se existem channels enviar instancias

	err = s.mkChServer(conn, req.Args, enc)
	if err != nil {
		err = e.Forward(err)
		log.Tag("server", "gormethods").Errorf("Channel arguments setup failed: %v", err)
		return
	}

	method := inst.Instance().MethodByName(req.Method)
	if !method.IsValid() {
		err = e.Push(e.New(ErrMethodNotFound), e.New("method %v not found", req.Method))
		log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
		return
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Call %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	var retvals []reflect.Value
	if method.Type().IsVariadic() {
		retvals = method.CallSlice(req.Args)
	} else {
		retvals = method.Call(req.Args)
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Call returned %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	for i := range retvals {
		var exp *Export
		exp, err = s.Insts.ExportGet(conn.SessionName(), conn.InstanceName(), req.Method, i)
		if err != nil {
			continue
		}
		var instname string
		instname, err = rand.Chars(16, rand.NumberLetters, "go")
		if err != nil {
			err = e.Push(err, "can't create the instance name for exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
			return
		}
		owners := auth.NewPlainTextCredentials()
		err = owners.Add(conn.Auth())
		if err != nil {
			err = e.Push(err, "can't authorize the exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
			return
		}
		err = s.Insts.New(conn.SessionName(), instname, retvals[i], owners)
		if err != nil {
			err = e.Push(err, "can't crete the instance for the exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), instname, err)
			return
		}
		for _, to := range exp.ToExport {
			err = s.Insts.Export(conn.SessionName(), instname, to)
			if err != nil {
				err = e.Push(err, e.New("can't export %v/%v %v %v %v to %v", conn.SessionName(), instname, to.Method, to.RetvalPos, types.Name(retvals[i].Interface()), types.Name(exp.Client)))
				log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
				return
			}
		}
		exp.Client.Associate(conn.SessionName(), instname, conn.Auth())
		retvals[i] = reflect.ValueOf(exp.Client)
		continue
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Send returned values %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	err = enc.Encode(&respCall{
		Vals: retvals,
		Err:  nil,
	})
	if err != nil {
		log.ProtoLevel().Tag("server", "gormethods").Printf("Encode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), err)
		err = e.Push(err, ErrWire)
		return
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Send returned values done %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	return
}