Beispiel #1
0
// HandleCall handles incoming messages from `gen_server:call/2`, if returns non-nil term,
// then calling process have reply
// Call `gen_server:call({go_srv, gonode@localhost}, Message)` at Erlang node
func (gs *gonodeSrv) HandleCall(message *erl.Term, from *erl.Tuple) (reply *erl.Term) {
	log.Printf("GO_SRV: HandleCall: %#v, From: %#v", *message, *from)

	// Just create new term tuple where first element is atom 'ok', second 'go_reply' and third is original message
	replyTerm := erl.Term(erl.Tuple{erl.Atom("ok"), erl.Atom("go_reply"), *message})
	reply = &replyTerm
	return
}
Beispiel #2
0
func (currNode *Node) handleTerms(c net.Conn, wchan chan []erl.Term, terms []erl.Term) {
	nLog("Node terms: %#v", terms)

	if len(terms) == 0 {
		return
	}
	switch t := terms[0].(type) {
	case erl.Tuple:
		if len(t) > 0 {
			switch act := t.Element(1).(type) {
			case int:
				switch act {
				case REG_SEND:
					if len(terms) == 2 {
						currNode.RegSend(t.Element(2), t.Element(4), terms[1])
					} else {
						nLog("*** ERROR: bad REG_SEND: %#v", terms)
					}
				default:
					nLog("Unhandled node message (act %d): %#v", act, t)
				}
			case erl.Atom:
				switch act {
				case erl.Atom("$go_set_node"):
					nLog("SET NODE %#v", t)
					currNode.neighbors[t[1].(erl.Atom)] = nodeConn{conn: c, wchan: wchan}
				}
			default:
				nLog("UNHANDLED ACT: %#v", t.Element(1))
			}
		}
	}
}
Beispiel #3
0
func (n *Node) registrator() {
	for {
		select {
		case req := <-n.registry.storeChan:
			// FIXME: make proper allocation, now it just stub
			var id uint32 = 0
			for k, _ := range n.channels {
				if k.Id >= id {
					id = k.Id + 1
				}
			}
			var pid erl.Pid
			pid.Node = erl.Atom(n.FullName)
			pid.Id = id
			pid.Serial = 0 // FIXME
			pid.Creation = byte(n.Creation)

			n.channels[pid] = req.channels
			req.replyTo <- pid
		case req := <-n.registry.regNameChan:
			n.registered[req.name] = req.pid
		case req := <-n.registry.unregNameChan:
			delete(n.registered, req.name)
		}
	}
}
Beispiel #4
0
// Init initializes process state using arbitrary arguments
func (gs *gonodeSrv) Init(args ...interface{}) {
	log.Printf("GO_SRV: Init: %#v", args)

	// Self-registration with name go_srv
	gs.Node.Register(erl.Atom("go_srv"), gs.Self)

	// Store first argument as channel
	gs.completeChan = args[0].(chan bool)
}
Beispiel #5
0
func (rpcs *rpcRex) HandleCall(message *erl.Term, from *erl.Tuple) (reply *erl.Term) {
	nLog("REX: HandleCall: %#v, From: %#v", *message, *from)
	switch req := (*message).(type) {
	case erl.Tuple:
		if len(req) > 0 {
			switch act := req[0].(type) {
			case erl.Atom:
				if string(act) == "call" {
					nLog("RPC CALL: Module: %#v, Function: %#v, Args: %#v, GroupLeader: %#v", req[1], req[2], req[3], req[4])
					replyTerm := erl.Term(erl.Tuple{req[1], req[2]})
					reply = &replyTerm
				}
			}
		}
	}
	if reply == nil {
		replyTerm := erl.Term(erl.Tuple{erl.Atom("badrpc"), erl.Atom("unknown")})
		reply = &replyTerm
	}
	return
}
Beispiel #6
0
// Send sends message to destination process withoud source
func (currNode *Node) Send(to erl.Pid, message erl.Term) {
	nLog("Send: %#v, %#v", to, message)
	if string(to.Node) == currNode.FullName {
		nLog("Send to local node")
		pcs := currNode.channels[to]
		pcs.in <- message
	} else {
		nLog("Send to remote node: %#v, %#v", to, currNode.neighbors[to.Node])

		msg := []erl.Term{erl.Tuple{SEND, erl.Atom(""), to}, message}
		currNode.neighbors[to.Node].wchan <- msg
	}
}
Beispiel #7
0
func TestDecodeStruct3(t *testing.T) {
	type testStruct struct {
		types.Atom
		X uint8
		i *big.Int
		S string
	}
	type testStruct3 struct {
		T testStruct
		i [2]byte
		Y int
	}
	var ts testStruct3

	nilBig := (*big.Int)(nil)
	nilArr := [2]byte{0, 0}

	in := bytes.NewBuffer([]byte{
		131,
		104, 2,
		104, 3,
		100, 0, 4, 98, 108, 97,
		104, 97, 4,
		108, 0, 0, 0, 4,
		98, 0, 0, 4, 68,
		98, 0, 0, 4, 75,
		98, 0, 0, 4, 50,
		98, 0, 0, 4, 48,
		106,
		98, 0, 0, 2, 154,
	})
	exp := testStruct3{
		testStruct{
			types.Atom("blah"),
			4,
			nilBig,
			"фыва",
		},
		nilArr,
		666,
	}
	if err := Decode(in, &ts); err != nil {
		t.Fatal(err)
	} else if l := in.Len(); l != 0 {
		t.Errorf("buffer len %d", l)
	} else if ts != exp {
		t.Errorf("expected %v, got %v", exp, ts)
	}
}
Beispiel #8
0
func (nk *netKernel) HandleCall(message *erl.Term, from *erl.Tuple) (reply *erl.Term) {
	nLog("NET_KERNEL: HandleCall: %#v, From: %#v", *message, *from)
	switch t := (*message).(type) {
	case erl.Tuple:
		if len(t) == 2 {
			switch tag := t[0].(type) {
			case erl.Atom:
				if string(tag) == "is_auth" {
					nLog("NET_KERNEL: is_auth: %#v", t[1])
					replyTerm := erl.Term(erl.Atom("yes"))
					reply = &replyTerm
				}
			}
		}
	}
	return
}
Beispiel #9
0
func TestDecodeStruct(t *testing.T) {
	type testStruct struct {
		types.Atom
		X uint8
		S string
	}
	var ts testStruct

	in := bytes.NewBuffer([]byte{
		131, 104, 3, 100, 0, 4, 98, 108, 97, 104, 97, 4, 108, 0, 0, 0, 4, 98,
		0, 0, 4, 68, 98, 0, 0, 4, 75, 98, 0, 0, 4, 50, 98, 0, 0, 4, 48, 106,
	})
	if err := Decode(in, &ts); err != nil {
		t.Fatal(err)
	} else if l := in.Len(); l != 0 {
		t.Errorf("buffer len %d", l)
	} else if exp := (testStruct{types.Atom("blah"), 4, "фыва"}); ts != exp {
		t.Errorf("expected %v, got %v", exp, ts)
	}
}
Beispiel #10
0
func (gns *globalNameServer) HandleCall(message *erl.Term, from *erl.Tuple) (reply *erl.Term) {
	nLog("GLOBAL_NAME_SERVER: HandleCall: %#v, From: %#v", *message, *from)
	replyTerm := erl.Term(erl.Atom("reply"))
	reply = &replyTerm
	return
}
Beispiel #11
0
func (gns *globalNameServer) Init(args ...interface{}) {
	nLog("GLOBAL_NAME_SERVER: Init: %#v", args)
	gns.Node.Register(erl.Atom("global_name_server"), gns.Self)
}
Beispiel #12
0
// data structures and vice versa.
package etf

import (
	"encoding/binary"
	"errors"
	"fmt"
	read "github.com/goerlang/etf/read"
	t "github.com/goerlang/etf/types"
	"io"
	"math/big"
	"reflect"
)

var (
	atomType     = reflect.ValueOf(t.Atom("")).Type()
	ErrBadFormat = errors.New("etf: bad format")
)

// Decode unmarshals a value and stores it to a variable pointed by ptr.
func Decode(r io.Reader, ptr interface{}) (err error) {
	b := make([]byte, 1)
	_, err = io.ReadFull(r, b)
	if err == nil {
		if b[0] != t.EtVersion {
			err = fmt.Errorf("version %d not supported", b[0])
			return
		}

		p := reflect.ValueOf(ptr)
		err = decode(r, p)
Beispiel #13
0
func (nk *netKernel) Init(args ...interface{}) {
	nLog("NET_KERNEL: Init: %#v", args)
	nk.Node.Register(erl.Atom("net_kernel"), nk.Self)
}
Beispiel #14
0
// ProcessLoop executes during whole time of process life.
// It receives incoming messages from channels and handle it using methods of behaviour implementation
func (gs *GenServerImpl) ProcessLoop(pcs procChannels, pd Process, args ...interface{}) {
	pd.(GenServer).Init(args...)
	//pcs.ctl <- erl.Tuple{erl.Atom("$go_ctl"), erl.Tuple{erl.Atom("control-message"), erl.Atom("example")}}
	defer func() {
		if r := recover(); r != nil {
			// TODO: send message to parent process
			log.Printf("GenServer recovered: %#v", r)
		}
	}()
	for {
		var message erl.Term
		var fromPid erl.Pid
		select {
		case msg := <-pcs.in:
			message = msg
		case msgFrom := <-pcs.inFrom:
			message = msgFrom[1]
			fromPid = msgFrom[0].(erl.Pid)
		case ctlMsg := <-pcs.ctl:
			switch m := ctlMsg.(type) {
			case erl.Tuple:
				switch mtag := m[0].(type) {
				case erl.Atom:
					switch mtag {
					case erl.Atom("$go_ctl"):
						nLog("Control message: %#v", m)
					default:
						nLog("Unknown message: %#v", m)
					}
				default:
					nLog("Unknown message: %#v", m)
				}
			default:
				nLog("Unknown message: %#v", m)
			}
			continue
		}
		nLog("Message from %#v", fromPid)
		switch m := message.(type) {
		case erl.Tuple:
			switch mtag := m[0].(type) {
			case erl.Atom:
				switch mtag {
				case erl.Atom("$go_ctl"):
					nLog("Control message: %#v", message)
				case erl.Atom("$gen_call"):
					fromTuple := m[1].(erl.Tuple)
					reply := pd.(GenServer).HandleCall(&m[2], &fromTuple)
					if reply != nil {
						gs.Reply(&fromTuple, reply)
					}
				case erl.Atom("$gen_cast"):
					pd.(GenServer).HandleCast(&m[1])
				default:
					pd.(GenServer).HandleInfo(&message)
				}
			default:
				nLog("mtag: %#v", mtag)
				pd.(GenServer).HandleInfo(&message)
			}
		default:
			nLog("m: %#v", m)
			pd.(GenServer).HandleInfo(&message)
		}
	}
}
Beispiel #15
0
func (rpcs *rpcRex) Init(args ...interface{}) {
	nLog("REX: Init: %#v", args)
	rpcs.Node.Register(erl.Atom("rex"), rpcs.Self)
}