Commit f3e8a1fd authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f3f9949f
......@@ -30,6 +30,7 @@ import (
"sync/atomic"
"lab.nexedi.com/kirr/neo/go/xcommon/xnet"
_ "lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet" // XXX temp
)
// NodeLink is a node-node link in NEO
......
......@@ -59,10 +59,17 @@ type traceEvent struct {
//Name string
//Argv string
PkgPath string // XXX -> pkg ?
// TODO += Pos
Pkgi *loader.PackageInfo
*ast.FuncDecl
}
// traceImport represents 1 trace:import directive
type traceImport struct {
Pos token.Position
PkgPath string
}
// TypedArgv returns argument list with types
func (te *traceEvent) TypedArgv() string {
//format.Node(&buf, fset, te.FuncDecl.Type.Params)
......@@ -96,12 +103,18 @@ func (te *traceEvent) Argv() string {
return strings.Join(argv, ", ")
}
// byEventName provides []traceEvent ordering by event name
// byEventName provides []*traceEvent ordering by event name
type byEventName []*traceEvent
func (v byEventName) Less(i, j int) bool { return v[i].Name.Name < v[j].Name.Name }
func (v byEventName) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v byEventName) Len() int { return len(v) }
// byPkgPath provides []*traceImport ordering by package path
type byPkgPath []*traceImport
func (v byPkgPath) Less(i, j int) bool { return v[i].PkgPath < v[j].PkgPath }
func (v byPkgPath) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v byPkgPath) Len() int { return len(v) }
// traceEventCodeTmpl is code template generated for one trace event
var traceEventCodeTmpl = template.Must(template.New("traceevent").Parse(`
// traceevent: {{.Name}}({{.TypedArgv}}) XXX better raw .Text (e.g. comments)
......@@ -142,12 +155,10 @@ func {{.Name}}_Attach(pg *tracing.ProbeGroup, probe func({{.TypedArgv}})) *traci
`))
// traceEventImportTmpl is code template generated for importing one trace event
var traceEventImportTmpl = template.Must(template.New("traceimport").Parse(`
// traceimport: {{.Pkgi.Pkg.Path}} {{.Name}}
// FIXME func args typs must be qualified
var traceEventImportTmpl = template.Must(template.New("traceimport").Parse(`
//go:linkname {{.Pkgi.Pkg.Name}}_{{.Name}}_Attach {{.Pkgi.Pkg.Path}}.{{.Name}}_Attach
func {{.Pkgi.Pkg.Name}}_{{.Name}}_Attach(*tracing.ProbeGroup, func(.TypedArgv)) *tracing.Probe
func {{.Pkgi.Pkg.Name}}_{{.Name}}_Attach(*tracing.ProbeGroup, func({{.TypedArgv}})) *tracing.Probe
`))
// parseTraceEvent parses trace event definition into traceEvent
......@@ -179,20 +190,20 @@ func parseTraceEvent(pkgi *loader.PackageInfo, text string) (*traceEvent, error)
return nil, fmt.Errorf("trace event must not return results")
}
return &traceEvent{pkgi.Pkg.Path(), declf}, nil
return &traceEvent{pkgi, declf}, nil
}
// Package represents tracing-related information about a package
type Package struct {
PkgPath string
Eventv []*traceEvent // trace events this package defines
Importv []string // packages (pkgpath) this package trace imports
Eventv []*traceEvent // trace events this package defines
Importv []*traceImport // packages (pkgpath) this package trace imports
}
// packageTrace returns tracing information about a package
func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package {
eventv := []*traceEvent{}
importv := []string{}
importv := []*traceImport{}
// go through files of the package and process //trace: directives
for _, file := range pkgi.Files { // ast.File
......@@ -226,8 +237,13 @@ func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package {
eventv = append(eventv, event)
case "//trace:import":
// XXX reject duplicate imports
importv = append(importv, arg)
// reject duplicate imports
for _, imported := range importv {
if arg == imported.PkgPath {
log.Fatalf("%v: duplicate trace import of %v (previous at %v)", pos, arg, imported.Pos)
}
}
importv = append(importv, &traceImport{Pos: pos, PkgPath: arg})
default:
log.Fatalf("%v: unknown tracing directive %q", pos, directive)
......@@ -237,7 +253,7 @@ func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package {
}
sort.Sort(byEventName(eventv))
sort.Strings(importv)
sort.Sort(byPkgPath(importv))
return &Package{PkgPath: pkgi.Pkg.Path(), Eventv: eventv, Importv: importv}
}
......@@ -268,7 +284,7 @@ func tracegen(pkgpath string) error {
for _, event := range pkg.Eventv {
err = traceEventCodeTmpl.Execute(os.Stdout, event)
if err != nil {
panic(err)
panic(err) // XXX
}
}
......@@ -276,8 +292,23 @@ func tracegen(pkgpath string) error {
// generate code for trace:import imports
fmt.Println()
for _, pkgpath := range pkg.Importv {
fmt.Printf("// traceimport TODO %v\n", pkgpath)
for _, timport := range pkg.Importv {
fmt.Printf("// traceimport: %v\n", timport.PkgPath)
pkgi = lprog.Package(timport.PkgPath)
if pkgi == nil {
// TODO do not require vvv
log.Fatalf("%v: package %s must be also regularly imported", timport.Pos, timport.PkgPath)
}
pkg = packageTrace(lprog, pkgi)
for _, event := range pkg.Eventv {
err = traceEventImportTmpl.Execute(os.Stdout, event)
if err != nil {
panic(err) // XXX
}
}
}
// TODO check export hash
......
......@@ -53,4 +53,19 @@ func traceConnSend_Attach(pg *tracing.ProbeGroup, probe func(c *Conn, msg Msg))
return &p.Probe
}
// traceimport TODO lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet
// traceimport: lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet
//go:linkname pipenet_traceAccept_Attach lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet.traceAccept_Attach
func pipenet_traceAccept_Attach(*tracing.ProbeGroup, func(conn net.Conn)) *tracing.Probe
//go:linkname pipenet_traceDial_Attach lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet.traceDial_Attach
func pipenet_traceDial_Attach(*tracing.ProbeGroup, func(addr string)) *tracing.Probe
//go:linkname pipenet_traceListen_Attach lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet.traceListen_Attach
func pipenet_traceListen_Attach(*tracing.ProbeGroup, func(laddr string)) *tracing.Probe
//go:linkname pipenet_traceNew_Attach lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet.traceNew_Attach
func pipenet_traceNew_Attach(*tracing.ProbeGroup, func(name string)) *tracing.Probe
//go:linkname pipenet_traceNewHost_Attach lab.nexedi.com/kirr/neo/go/xcommon/xnet/pipenet.traceNewHost_Attach
func pipenet_traceNewHost_Attach(*tracing.ProbeGroup, func(host *Host)) *tracing.Probe
......@@ -137,6 +137,9 @@ func New(name string) *Network {
return &Network{name: name, hostMap: make(map[string]*Host)}
}
//XXX temp
//trace:event traceNewHost(host *Host)
// Host returns network access point by name
// if there was no such host before it creates new one
func (n *Network) Host(name string) *Host {
......@@ -147,6 +150,7 @@ func (n *Network) Host(name string) *Host {
if host == nil {
host = &Host{network: n, name: name}
n.hostMap[name] = host
traceNewHost(host)
}
return host
......@@ -173,11 +177,15 @@ func (h *Host) resolveAddr(addr string) (host *Host, port int, err error) {
return host, port, nil
}
// XXX temp
//trace:event traceListen(laddr string)
// Listen starts new listener
// It either allocates free port if laddr is "", or binds to laddr.
// Once listener is started, Dials could connect to listening address.
// Connection requests created by Dials could be accepted via Accept.
func (h *Host) Listen(laddr string) (net.Listener, error) {
traceListen(laddr)
h.network.mu.Lock()
defer h.network.mu.Unlock()
......@@ -250,6 +258,9 @@ func (l *listener) Close() error {
return nil
}
// XXX temp
//trace:event traceAccept(conn net.Conn)
// Accept tries to connect to Dial called with addr corresponding to our listener
func (l *listener) Accept() (net.Conn, error) {
h := l.socket.host
......@@ -274,13 +285,18 @@ func (l *listener) Accept() (net.Conn, error) {
n.mu.Unlock()
req.resp <- skc.conn
traceAccept(sks.conn)
return sks.conn, nil
}
}
// XXX temp
//trace:event traceDial(addr string)
// Dial dials address on the network
// It tries to connect to Accept called on listener corresponding to addr.
func (h *Host) Dial(ctx context.Context, addr string) (net.Conn, error) {
traceDial(addr)
var netaddr net.Addr
derr := func(err error) error {
return &net.OpError{Op: "dial", Net: h.Network(), Addr: netaddr, Err: err}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment