Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
c2a1b63a
Commit
c2a1b63a
authored
Jun 09, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X naming: Packet = raw data; Message = meaningful object
Message can be delivered encoded in a packet.
parent
b13e8150
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
552 additions
and
555 deletions
+552
-555
go/neo/cluster_test.go
go/neo/cluster_test.go
+6
-0
go/neo/connection.go
go/neo/connection.go
+8
-8
go/neo/connection_test.go
go/neo/connection_test.go
+59
-70
go/neo/pkt.go
go/neo/pkt.go
+3
-1
go/neo/proto-marshal.go
go/neo/proto-marshal.go
+367
-367
go/neo/proto.go
go/neo/proto.go
+15
-15
go/neo/proto_test.go
go/neo/proto_test.go
+27
-27
go/neo/protogen.go
go/neo/protogen.go
+36
-36
go/neo/server/master.go
go/neo/server/master.go
+5
-5
go/neo/server/storage.go
go/neo/server/storage.go
+2
-2
go/neo/x_connection.go
go/neo/x_connection.go
+24
-24
No files found.
go/neo/cluster_test.go
View file @
c2a1b63a
...
@@ -53,6 +53,9 @@ func xfs1stor(net Network, path string) (*server.Storage, *fs1.FileStorage) {
...
@@ -53,6 +53,9 @@ func xfs1stor(net Network, path string) (*server.Storage, *fs1.FileStorage) {
// M drives cluster with 1 S through recovery -> verification -> service -> shutdown
// M drives cluster with 1 S through recovery -> verification -> service -> shutdown
func
TestMasterStorage
(
t
*
testing
.
T
)
{
func
TestMasterStorage
(
t
*
testing
.
T
)
{
// XXX temp disabled
return
net
:=
NetPipe
(
""
)
// test network FIXME New registers to global table
net
:=
NetPipe
(
""
)
// test network FIXME New registers to global table
M
:=
server
.
NewMaster
(
"abc1"
)
M
:=
server
.
NewMaster
(
"abc1"
)
S
,
_
:=
xfs1stor
(
net
,
"../zodb/storage/fs1/testdata/1.fs"
)
// XXX +readonly
S
,
_
:=
xfs1stor
(
net
,
"../zodb/storage/fs1/testdata/1.fs"
)
// XXX +readonly
...
@@ -70,6 +73,9 @@ func TestMasterStorage(t *testing.T) {
...
@@ -70,6 +73,9 @@ func TestMasterStorage(t *testing.T) {
// basic interaction between Client -- Storage
// basic interaction between Client -- Storage
func
TestClientStorage
(
t
*
testing
.
T
)
{
func
TestClientStorage
(
t
*
testing
.
T
)
{
// XXX temp disabled
return
Cnl
,
Snl
:=
NodeLinkPipe
()
Cnl
,
Snl
:=
NodeLinkPipe
()
wg
:=
WorkGroup
()
wg
:=
WorkGroup
()
...
...
go/neo/connection.go
View file @
c2a1b63a
...
@@ -297,7 +297,7 @@ func (nl *NodeLink) Accept() (c *Conn, err error) {
...
@@ -297,7 +297,7 @@ func (nl *NodeLink) Accept() (c *Conn, err error) {
}
}
}
}
// errRecvShutdown returns appropriate error when c.down is found ready in
Recv
// errRecvShutdown returns appropriate error when c.down is found ready in
recvPkt
func
(
c
*
Conn
)
errRecvShutdown
()
error
{
func
(
c
*
Conn
)
errRecvShutdown
()
error
{
switch
{
switch
{
case
atomic
.
LoadUint32
(
&
c
.
closed
)
!=
0
:
case
atomic
.
LoadUint32
(
&
c
.
closed
)
!=
0
:
...
@@ -323,8 +323,8 @@ func (c *Conn) errRecvShutdown() error {
...
@@ -323,8 +323,8 @@ func (c *Conn) errRecvShutdown() error {
}
}
}
}
//
Recv receives
packet from connection
//
recvPkt receives raw
packet from connection
func
(
c
*
Conn
)
Recv
()
(
*
PktBuf
,
error
)
{
func
(
c
*
Conn
)
recvPkt
()
(
*
PktBuf
,
error
)
{
select
{
select
{
case
<-
c
.
down
:
case
<-
c
.
down
:
return
nil
,
c
.
err
(
"recv"
,
c
.
errRecvShutdown
())
return
nil
,
c
.
err
(
"recv"
,
c
.
errRecvShutdown
())
...
@@ -441,13 +441,13 @@ func (c *Conn) errSendShutdown() error {
...
@@ -441,13 +441,13 @@ func (c *Conn) errSendShutdown() error {
}
}
}
}
//
Send sends
packet via connection
//
sendPkt sends raw
packet via connection
func
(
c
*
Conn
)
Send
(
pkt
*
PktBuf
)
error
{
func
(
c
*
Conn
)
sendPkt
(
pkt
*
PktBuf
)
error
{
err
:=
c
.
send
(
pkt
)
err
:=
c
.
send
Pkt2
(
pkt
)
return
c
.
err
(
"send"
,
err
)
return
c
.
err
(
"send"
,
err
)
}
}
func
(
c
*
Conn
)
send
(
pkt
*
PktBuf
)
error
{
func
(
c
*
Conn
)
send
Pkt2
(
pkt
*
PktBuf
)
error
{
// set pkt connId associated with this connection
// set pkt connId associated with this connection
pkt
.
Header
()
.
ConnId
=
hton32
(
c
.
connId
)
pkt
.
Header
()
.
ConnId
=
hton32
(
c
.
connId
)
var
err
error
var
err
error
...
@@ -541,7 +541,7 @@ func (nl *NodeLink) recvPkt() (*PktBuf, error) {
...
@@ -541,7 +541,7 @@ func (nl *NodeLink) recvPkt() (*PktBuf, error) {
// first read to read pkt header and hopefully up to page of data in 1 syscall
// first read to read pkt header and hopefully up to page of data in 1 syscall
pkt
:=
&
PktBuf
{
make
([]
byte
,
4096
)}
pkt
:=
&
PktBuf
{
make
([]
byte
,
4096
)}
// TODO reenable, but NOTE next packet can be also prefetched here -> use buffering ?
// TODO reenable, but NOTE next packet can be also prefetched here -> use buffering ?
//n, err := io.ReadAtLeast(nl.peerLink, p
kt
.Data, PktHeadLen)
//n, err := io.ReadAtLeast(nl.peerLink, p
tb
.Data, PktHeadLen)
n
,
err
:=
io
.
ReadFull
(
nl
.
peerLink
,
pkt
.
Data
[
:
PktHeadLen
])
n
,
err
:=
io
.
ReadFull
(
nl
.
peerLink
,
pkt
.
Data
[
:
PktHeadLen
])
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
...
go/neo/connection_test.go
View file @
c2a1b63a
...
@@ -72,24 +72,13 @@ func xaccept(nl *NodeLink) *Conn {
...
@@ -72,24 +72,13 @@ func xaccept(nl *NodeLink) *Conn {
return
c
return
c
}
}
func
xsend
(
c
*
Conn
,
pkt
*
PktBuf
)
{
func
xsend
Pkt
(
c
interface
{
sendPkt
(
*
PktBuf
)
error
}
,
pkt
*
PktBuf
)
{
err
:=
c
.
Send
(
pkt
)
err
:=
c
.
sendPkt
(
pkt
)
exc
.
Raiseif
(
err
)
exc
.
Raiseif
(
err
)
}
}
func
xrecv
(
c
*
Conn
)
*
PktBuf
{
func
xrecvPkt
(
c
interface
{
recvPkt
()
(
*
PktBuf
,
error
)
})
*
PktBuf
{
pkt
,
err
:=
c
.
Recv
()
pkt
,
err
:=
c
.
recvPkt
()
exc
.
Raiseif
(
err
)
return
pkt
}
func
xsendPkt
(
nl
*
NodeLink
,
pkt
*
PktBuf
)
{
err
:=
nl
.
sendPkt
(
pkt
)
exc
.
Raiseif
(
err
)
}
func
xrecvPkt
(
nl
*
NodeLink
)
*
PktBuf
{
pkt
,
err
:=
nl
.
recvPkt
()
exc
.
Raiseif
(
err
)
exc
.
Raiseif
(
err
)
return
pkt
return
pkt
}
}
...
@@ -134,7 +123,7 @@ func _mkpkt(connid uint32, msgcode uint16, payload []byte) *PktBuf {
...
@@ -134,7 +123,7 @@ func _mkpkt(connid uint32, msgcode uint16, payload []byte) *PktBuf {
}
}
func
mkpkt
(
msgcode
uint16
,
payload
[]
byte
)
*
PktBuf
{
func
mkpkt
(
msgcode
uint16
,
payload
[]
byte
)
*
PktBuf
{
// in Conn exchange connid is automatically set by Conn.
Send
// in Conn exchange connid is automatically set by Conn.
sendPkt
return
_mkpkt
(
0
,
msgcode
,
payload
)
return
_mkpkt
(
0
,
msgcode
,
payload
)
}
}
...
@@ -300,7 +289,7 @@ func TestNodeLink(t *testing.T) {
...
@@ -300,7 +289,7 @@ func TestNodeLink(t *testing.T) {
// Test connections on top of nodelink
// Test connections on top of nodelink
// Close vs
Recv
// Close vs
recvPkt
nl1
,
nl2
=
_nodeLinkPipe
(
0
,
linkNoRecvSend
)
nl1
,
nl2
=
_nodeLinkPipe
(
0
,
linkNoRecvSend
)
c
=
xnewconn
(
nl1
)
c
=
xnewconn
(
nl1
)
wg
=
WorkGroup
()
wg
=
WorkGroup
()
...
@@ -308,15 +297,15 @@ func TestNodeLink(t *testing.T) {
...
@@ -308,15 +297,15 @@ func TestNodeLink(t *testing.T) {
tdelay
()
tdelay
()
xclose
(
c
)
xclose
(
c
)
})
})
pkt
,
err
=
c
.
Recv
()
pkt
,
err
=
c
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
t
.
Fatalf
(
"Conn.
Recv
() after close: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
() after close: pkt = %v err = %v"
,
pkt
,
err
)
}
}
xwait
(
wg
)
xwait
(
wg
)
xclose
(
nl1
)
xclose
(
nl1
)
xclose
(
nl2
)
xclose
(
nl2
)
// Close vs
Send
// Close vs
sendPkt
nl1
,
nl2
=
_nodeLinkPipe
(
0
,
linkNoRecvSend
)
nl1
,
nl2
=
_nodeLinkPipe
(
0
,
linkNoRecvSend
)
c
=
xnewconn
(
nl1
)
c
=
xnewconn
(
nl1
)
wg
=
WorkGroup
()
wg
=
WorkGroup
()
...
@@ -325,27 +314,27 @@ func TestNodeLink(t *testing.T) {
...
@@ -325,27 +314,27 @@ func TestNodeLink(t *testing.T) {
xclose
(
c
)
xclose
(
c
)
})
})
pkt
=
&
PktBuf
{[]
byte
(
"data"
)}
pkt
=
&
PktBuf
{[]
byte
(
"data"
)}
err
=
c
.
Send
(
pkt
)
err
=
c
.
sendPkt
(
pkt
)
if
xconnError
(
err
)
!=
ErrClosedConn
{
if
xconnError
(
err
)
!=
ErrClosedConn
{
t
.
Fatalf
(
"Conn.
Send
() after close: err = %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
() after close: err = %v"
,
err
)
}
}
xwait
(
wg
)
xwait
(
wg
)
// NodeLink.Close vs Conn.
Send/Recv
// NodeLink.Close vs Conn.
sendPkt/recvPkt
c11
:=
xnewconn
(
nl1
)
c11
:=
xnewconn
(
nl1
)
c12
:=
xnewconn
(
nl1
)
c12
:=
xnewconn
(
nl1
)
wg
=
WorkGroup
()
wg
=
WorkGroup
()
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
pkt
,
err
:=
c11
.
Recv
()
pkt
,
err
:=
c11
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkClosed
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkClosed
)
{
exc
.
Raisef
(
"Conn.
Recv
() after NodeLink close: pkt = %v err = %v"
,
pkt
,
err
)
exc
.
Raisef
(
"Conn.
recvPkt
() after NodeLink close: pkt = %v err = %v"
,
pkt
,
err
)
}
}
})
})
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
pkt
:=
&
PktBuf
{[]
byte
(
"data"
)}
pkt
:=
&
PktBuf
{[]
byte
(
"data"
)}
err
:=
c12
.
Send
(
pkt
)
err
:=
c12
.
sendPkt
(
pkt
)
if
xconnError
(
err
)
!=
ErrLinkClosed
{
if
xconnError
(
err
)
!=
ErrLinkClosed
{
exc
.
Raisef
(
"Conn.
Send
() after NodeLink close: err = %v"
,
err
)
exc
.
Raisef
(
"Conn.
sendPkt
() after NodeLink close: err = %v"
,
err
)
}
}
})
})
tdelay
()
tdelay
()
...
@@ -355,7 +344,7 @@ func TestNodeLink(t *testing.T) {
...
@@ -355,7 +344,7 @@ func TestNodeLink(t *testing.T) {
xclose
(
c12
)
xclose
(
c12
)
xclose
(
nl2
)
xclose
(
nl2
)
// NodeLink.Close vs Conn.
Send/Recv
and Accept on another side
// NodeLink.Close vs Conn.
sendPkt/recvPkt
and Accept on another side
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
0
)
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
0
)
c21
:=
xnewconn
(
nl2
)
c21
:=
xnewconn
(
nl2
)
c22
:=
xnewconn
(
nl2
)
c22
:=
xnewconn
(
nl2
)
...
@@ -363,22 +352,22 @@ func TestNodeLink(t *testing.T) {
...
@@ -363,22 +352,22 @@ func TestNodeLink(t *testing.T) {
wg
=
WorkGroup
()
wg
=
WorkGroup
()
var
errRecv
error
var
errRecv
error
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
pkt
,
err
:=
c21
.
Recv
()
pkt
,
err
:=
c21
.
recvPkt
()
want1
:=
io
.
EOF
// if recvPkt wakes up due to peer close
want1
:=
io
.
EOF
// if recvPkt wakes up due to peer close
want2
:=
io
.
ErrClosedPipe
// if recvPkt wakes up due to sendPkt wakes up first and closes nl1
want2
:=
io
.
ErrClosedPipe
// if recvPkt wakes up due to sendPkt wakes up first and closes nl1
cerr
:=
xconnError
(
err
)
cerr
:=
xconnError
(
err
)
if
!
(
pkt
==
nil
&&
(
cerr
==
want1
||
cerr
==
want2
))
{
if
!
(
pkt
==
nil
&&
(
cerr
==
want1
||
cerr
==
want2
))
{
exc
.
Raisef
(
"Conn.
Recv
after peer NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
exc
.
Raisef
(
"Conn.
recvPkt
after peer NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
}
}
errRecv
=
cerr
errRecv
=
cerr
})
})
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
pkt
:=
&
PktBuf
{[]
byte
(
"data"
)}
pkt
:=
&
PktBuf
{[]
byte
(
"data"
)}
err
:=
c22
.
Send
(
pkt
)
err
:=
c22
.
sendPkt
(
pkt
)
want
:=
io
.
ErrClosedPipe
// always this in both due to peer close or recvPkt waking up and closing nl2
want
:=
io
.
ErrClosedPipe
// always this in both due to peer close or recvPkt waking up and closing nl2
if
xconnError
(
err
)
!=
want
{
if
xconnError
(
err
)
!=
want
{
exc
.
Raisef
(
"Conn.
Send
after peer NodeLink shutdown: %v"
,
err
)
exc
.
Raisef
(
"Conn.
sendPkt
after peer NodeLink shutdown: %v"
,
err
)
}
}
})
})
...
@@ -406,46 +395,46 @@ func TestNodeLink(t *testing.T) {
...
@@ -406,46 +395,46 @@ func TestNodeLink(t *testing.T) {
t
.
Fatalf
(
"Accept after NodeLink shutdown: conn = %v err = %v"
,
c
,
err
)
t
.
Fatalf
(
"Accept after NodeLink shutdown: conn = %v err = %v"
,
c
,
err
)
}
}
//
Recv/Send
on another Conn
//
recvPkt/sendPkt
on another Conn
pkt
,
err
=
c23
.
Recv
()
pkt
,
err
=
c23
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
errRecv
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
errRecv
)
{
t
.
Fatalf
(
"Conn.
Recv
2 after peer NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
2 after peer NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
}
}
err
=
c23
.
Send
(
&
PktBuf
{[]
byte
(
"data"
)})
err
=
c23
.
sendPkt
(
&
PktBuf
{[]
byte
(
"data"
)})
if
xconnError
(
err
)
!=
ErrLinkDown
{
if
xconnError
(
err
)
!=
ErrLinkDown
{
t
.
Fatalf
(
"Conn.
Send
2 after peer NodeLink shutdown: %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
2 after peer NodeLink shutdown: %v"
,
err
)
}
}
//
Recv/Send
error on second call
//
recvPkt/sendPkt
error on second call
pkt
,
err
=
c21
.
Recv
()
pkt
,
err
=
c21
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkDown
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkDown
)
{
t
.
Fatalf
(
"Conn.
Recv
after NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
after NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
}
}
err
=
c22
.
Send
(
&
PktBuf
{[]
byte
(
"data"
)})
err
=
c22
.
sendPkt
(
&
PktBuf
{[]
byte
(
"data"
)})
if
xconnError
(
err
)
!=
ErrLinkDown
{
if
xconnError
(
err
)
!=
ErrLinkDown
{
t
.
Fatalf
(
"Conn.
Send
after NodeLink shutdown: %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
after NodeLink shutdown: %v"
,
err
)
}
}
xclose
(
c23
)
xclose
(
c23
)
//
Recv/Send
on closed Conn but not closed NodeLink
//
recvPkt/sendPkt
on closed Conn but not closed NodeLink
pkt
,
err
=
c23
.
Recv
()
pkt
,
err
=
c23
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
t
.
Fatalf
(
"Conn.
Recv
after close but only stopped NodeLink: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
after close but only stopped NodeLink: pkt = %v err = %v"
,
pkt
,
err
)
}
}
err
=
c23
.
Send
(
&
PktBuf
{[]
byte
(
"data"
)})
err
=
c23
.
sendPkt
(
&
PktBuf
{[]
byte
(
"data"
)})
if
xconnError
(
err
)
!=
ErrClosedConn
{
if
xconnError
(
err
)
!=
ErrClosedConn
{
t
.
Fatalf
(
"Conn.
Send
after close but only stopped NodeLink: %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
after close but only stopped NodeLink: %v"
,
err
)
}
}
xclose
(
nl2
)
xclose
(
nl2
)
//
Recv/Send
NewConn/Accept error after NodeLink close
//
recvPkt/sendPkt
NewConn/Accept error after NodeLink close
pkt
,
err
=
c21
.
Recv
()
pkt
,
err
=
c21
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkClosed
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrLinkClosed
)
{
t
.
Fatalf
(
"Conn.
Recv
after NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
after NodeLink shutdown: pkt = %v err = %v"
,
pkt
,
err
)
}
}
err
=
c22
.
Send
(
&
PktBuf
{[]
byte
(
"data"
)})
err
=
c22
.
sendPkt
(
&
PktBuf
{[]
byte
(
"data"
)})
if
xconnError
(
err
)
!=
ErrLinkClosed
{
if
xconnError
(
err
)
!=
ErrLinkClosed
{
t
.
Fatalf
(
"Conn.
Send
after NodeLink shutdown: %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
after NodeLink shutdown: %v"
,
err
)
}
}
c
,
err
=
nl2
.
NewConn
()
c
,
err
=
nl2
.
NewConn
()
...
@@ -460,14 +449,14 @@ func TestNodeLink(t *testing.T) {
...
@@ -460,14 +449,14 @@ func TestNodeLink(t *testing.T) {
xclose
(
c21
)
xclose
(
c21
)
xclose
(
c22
)
xclose
(
c22
)
//
Recv/Send
error after Close & NodeLink shutdown
//
recvPkt/sendPkt
error after Close & NodeLink shutdown
pkt
,
err
=
c21
.
Recv
()
pkt
,
err
=
c21
.
recvPkt
()
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
if
!
(
pkt
==
nil
&&
xconnError
(
err
)
==
ErrClosedConn
)
{
t
.
Fatalf
(
"Conn.
Recv
after close and NodeLink close: pkt = %v err = %v"
,
pkt
,
err
)
t
.
Fatalf
(
"Conn.
recvPkt
after close and NodeLink close: pkt = %v err = %v"
,
pkt
,
err
)
}
}
err
=
c22
.
Send
(
&
PktBuf
{[]
byte
(
"data"
)})
err
=
c22
.
sendPkt
(
&
PktBuf
{[]
byte
(
"data"
)})
if
xconnError
(
err
)
!=
ErrClosedConn
{
if
xconnError
(
err
)
!=
ErrClosedConn
{
t
.
Fatalf
(
"Conn.
Send
after close and NodeLink close: %v"
,
err
)
t
.
Fatalf
(
"Conn.
sendPkt
after close and NodeLink close: %v"
,
err
)
}
}
...
@@ -477,25 +466,25 @@ func TestNodeLink(t *testing.T) {
...
@@ -477,25 +466,25 @@ func TestNodeLink(t *testing.T) {
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
c
:=
xaccept
(
nl2
)
c
:=
xaccept
(
nl2
)
pkt
:=
xrecv
(
c
)
pkt
:=
xrecv
Pkt
(
c
)
xverifyPkt
(
pkt
,
c
.
connId
,
33
,
[]
byte
(
"ping"
))
xverifyPkt
(
pkt
,
c
.
connId
,
33
,
[]
byte
(
"ping"
))
// change pkt a bit and send it back
// change pkt a bit and send it back
xsend
(
c
,
mkpkt
(
34
,
[]
byte
(
"pong"
)))
xsend
Pkt
(
c
,
mkpkt
(
34
,
[]
byte
(
"pong"
)))
// one more time
// one more time
pkt
=
xrecv
(
c
)
pkt
=
xrecv
Pkt
(
c
)
xverifyPkt
(
pkt
,
c
.
connId
,
35
,
[]
byte
(
"ping2"
))
xverifyPkt
(
pkt
,
c
.
connId
,
35
,
[]
byte
(
"ping2"
))
xsend
(
c
,
mkpkt
(
36
,
[]
byte
(
"pong2"
)))
xsend
Pkt
(
c
,
mkpkt
(
36
,
[]
byte
(
"pong2"
)))
xclose
(
c
)
xclose
(
c
)
})
})
c
=
xnewconn
(
nl1
)
c
=
xnewconn
(
nl1
)
xsend
(
c
,
mkpkt
(
33
,
[]
byte
(
"ping"
)))
xsend
Pkt
(
c
,
mkpkt
(
33
,
[]
byte
(
"ping"
)))
pkt
=
xrecv
(
c
)
pkt
=
xrecv
Pkt
(
c
)
xverifyPkt
(
pkt
,
c
.
connId
,
34
,
[]
byte
(
"pong"
))
xverifyPkt
(
pkt
,
c
.
connId
,
34
,
[]
byte
(
"pong"
))
xsend
(
c
,
mkpkt
(
35
,
[]
byte
(
"ping2"
)))
xsend
Pkt
(
c
,
mkpkt
(
35
,
[]
byte
(
"ping2"
)))
pkt
=
xrecv
(
c
)
pkt
=
xrecv
Pkt
(
c
)
xverifyPkt
(
pkt
,
c
.
connId
,
36
,
[]
byte
(
"pong2"
))
xverifyPkt
(
pkt
,
c
.
connId
,
36
,
[]
byte
(
"pong2"
))
xwait
(
wg
)
xwait
(
wg
)
...
@@ -520,13 +509,13 @@ func TestNodeLink(t *testing.T) {
...
@@ -520,13 +509,13 @@ func TestNodeLink(t *testing.T) {
c
:=
xaccept
(
nl2
)
c
:=
xaccept
(
nl2
)
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
pkt
:=
xrecv
(
c
)
pkt
:=
xrecv
Pkt
(
c
)
n
:=
ntoh16
(
pkt
.
Header
()
.
MsgCode
)
n
:=
ntoh16
(
pkt
.
Header
()
.
MsgCode
)
x
:=
replyOrder
[
n
]
x
:=
replyOrder
[
n
]
// wait before it is our turn & echo pkt back
// wait before it is our turn & echo pkt back
<-
x
.
start
<-
x
.
start
xsend
(
c
,
pkt
)
xsend
Pkt
(
c
,
pkt
)
xclose
(
c
)
xclose
(
c
)
...
@@ -540,12 +529,12 @@ func TestNodeLink(t *testing.T) {
...
@@ -540,12 +529,12 @@ func TestNodeLink(t *testing.T) {
c1
:=
xnewconn
(
nl1
)
c1
:=
xnewconn
(
nl1
)
c2
:=
xnewconn
(
nl1
)
c2
:=
xnewconn
(
nl1
)
xsend
(
c1
,
mkpkt
(
1
,
[]
byte
(
""
)))
xsend
Pkt
(
c1
,
mkpkt
(
1
,
[]
byte
(
""
)))
xsend
(
c2
,
mkpkt
(
2
,
[]
byte
(
""
)))
xsend
Pkt
(
c2
,
mkpkt
(
2
,
[]
byte
(
""
)))
// replies must be coming in reverse order
// replies must be coming in reverse order
xechoWait
:=
func
(
c
*
Conn
,
msgCode
uint16
)
{
xechoWait
:=
func
(
c
*
Conn
,
msgCode
uint16
)
{
pkt
:=
xrecv
(
c
)
pkt
:=
xrecv
Pkt
(
c
)
xverifyPkt
(
pkt
,
c
.
connId
,
msgCode
,
[]
byte
(
""
))
xverifyPkt
(
pkt
,
c
.
connId
,
msgCode
,
[]
byte
(
""
))
}
}
xechoWait
(
c2
,
2
)
xechoWait
(
c2
,
2
)
...
...
go/neo/pkt.go
View file @
c2a1b63a
...
@@ -26,6 +26,8 @@ import (
...
@@ -26,6 +26,8 @@ import (
// TODO organize rx buffers management (freelist etc)
// TODO organize rx buffers management (freelist etc)
// PktBuf is a buffer with full raw packet (header + data)
// PktBuf is a buffer with full raw packet (header + data)
//
// variables of type PktBuf are usually named "pkb" (packet buffer), similar to "skb" in Linux
type
PktBuf
struct
{
type
PktBuf
struct
{
Data
[]
byte
// whole packet data including all headers XXX -> Buf ?
Data
[]
byte
// whole packet data including all headers XXX -> Buf ?
}
}
...
@@ -61,7 +63,7 @@ func (pkt *PktBuf) String() string {
...
@@ -61,7 +63,7 @@ func (pkt *PktBuf) String() string {
s
:=
fmt
.
Sprintf
(
".%d"
,
ntoh32
(
h
.
ConnId
))
s
:=
fmt
.
Sprintf
(
".%d"
,
ntoh32
(
h
.
ConnId
))
msgCode
:=
ntoh16
(
h
.
MsgCode
)
msgCode
:=
ntoh16
(
h
.
MsgCode
)
msgType
:=
pkt
TypeRegistry
[
msgCode
]
msgType
:=
msg
TypeRegistry
[
msgCode
]
if
msgType
==
nil
{
if
msgType
==
nil
{
s
+=
fmt
.
Sprintf
(
" ? (%d)"
,
msgCode
)
s
+=
fmt
.
Sprintf
(
" ? (%d)"
,
msgCode
)
}
else
{
}
else
{
...
...
go/neo/proto-marshal.go
View file @
c2a1b63a
This diff is collapsed.
Click to expand it.
go/neo/proto.go
View file @
c2a1b63a
...
@@ -110,7 +110,7 @@ const (
...
@@ -110,7 +110,7 @@ const (
// node finishes to replicate it. It means a partition is moved from 1 node
// node finishes to replicate it. It means a partition is moved from 1 node
// to another.
// to another.
FEEDING
//short: F
FEEDING
//short: F
// Not really a state: only used in network
packet
s to tell storages to drop
// Not really a state: only used in network
message
s to tell storages to drop
// partitions.
// partitions.
DISCARDED
//short: D
DISCARDED
//short: D
// A check revealed that data differs from other replicas. Cell is neither
// A check revealed that data differs from other replicas. Cell is neither
...
@@ -136,24 +136,24 @@ type NodeUUID int32
...
@@ -136,24 +136,24 @@ type NodeUUID int32
// TODO NodeType -> base NodeUUID
// TODO NodeType -> base NodeUUID
// ErrDecodeOverflow is the error returned by NEO
Pkt
Decode when decoding hit buffer overflow
// ErrDecodeOverflow is the error returned by NEO
Msg
Decode when decoding hit buffer overflow
var
ErrDecodeOverflow
=
errors
.
New
(
"decode: bufer overflow"
)
var
ErrDecodeOverflow
=
errors
.
New
(
"decode: bufer overflow"
)
//
Pkt is the interface implemented by NEO packet
s to marshal/unmarshal them into/from wire format
//
Msg is the interface implemented by NEO message
s to marshal/unmarshal them into/from wire format
type
Pkt
interface
{
type
Msg
interface
{
// NEO
PktMsgCode returns message code needed to be used for particular packet
type
// NEO
MsgCode returns message code needed to be used for particular message
type
// on the wire
// on the wire
NEO
Pkt
MsgCode
()
uint16
NEOMsgCode
()
uint16
// NEO
PktEncodedLen returns how much space is needed to encode current state
// NEO
MsgEncodedLen returns how much space is needed to encode current message payload
NEO
Pkt
EncodedLen
()
int
NEO
Msg
EncodedLen
()
int
// NEO
PktEncode encodes current
state into buf.
// NEO
MsgEncode encodes current message
state into buf.
// len(buf) must be >= NEO
Pkt
EncodedLen()
// len(buf) must be >= NEO
Msg
EncodedLen()
NEO
Pkt
Encode
(
buf
[]
byte
)
NEO
Msg
Encode
(
buf
[]
byte
)
// NEO
PktDecode decodes data into current packet stat
e.
// NEO
MsgDecode decodes data into message in-plac
e.
NEO
Pkt
Decode
(
data
[]
byte
)
(
nread
int
,
err
error
)
NEO
Msg
Decode
(
data
[]
byte
)
(
nread
int
,
err
error
)
}
}
...
@@ -163,7 +163,7 @@ type Address struct {
...
@@ -163,7 +163,7 @@ type Address struct {
}
}
// NOTE if Host == "" -> Port not added to wire (see py.PAddress):
// NOTE if Host == "" -> Port not added to wire (see py.PAddress):
// func (a *Address) NEO
Pkt
Encode(b []byte) int {
// func (a *Address) NEO
Msg
Encode(b []byte) int {
// n := string_NEOEncode(a.Host, b[0:])
// n := string_NEOEncode(a.Host, b[0:])
// if a.Host != "" {
// if a.Host != "" {
// BigEndian.PutUint16(b[n:], a.Port)
// BigEndian.PutUint16(b[n:], a.Port)
...
@@ -263,7 +263,7 @@ type Ping struct {
...
@@ -263,7 +263,7 @@ type Ping struct {
type
CloseClient
struct
{
type
CloseClient
struct
{
}
}
// Request a node identification. This must be the first
packet
for any
// Request a node identification. This must be the first
message
for any
// connection. Any -> Any.
// connection. Any -> Any.
type
RequestIdentification
struct
{
type
RequestIdentification
struct
{
NodeType
NodeType
// XXX name
NodeType
NodeType
// XXX name
...
...
go/neo/proto_test.go
View file @
c2a1b63a
...
@@ -68,10 +68,10 @@ func TestPktHeader(t *testing.T) {
...
@@ -68,10 +68,10 @@ func TestPktHeader(t *testing.T) {
}
}
}
}
// test marshalling for one
packet
type
// test marshalling for one
message
type
func
test
PktMarshal
(
t
*
testing
.
T
,
pkt
Pkt
,
encoded
string
)
{
func
test
MsgMarshal
(
t
*
testing
.
T
,
msg
Msg
,
encoded
string
)
{
typ
:=
reflect
.
TypeOf
(
pkt
)
.
Elem
()
// type of *pkt
typ
:=
reflect
.
TypeOf
(
msg
)
.
Elem
()
// type of *msg
pkt2
:=
reflect
.
New
(
typ
)
.
Interface
()
.
(
Pkt
)
msg2
:=
reflect
.
New
(
typ
)
.
Interface
()
.
(
Msg
)
defer
func
()
{
defer
func
()
{
if
e
:=
recover
();
e
!=
nil
{
if
e
:=
recover
();
e
!=
nil
{
t
.
Errorf
(
"%v: panic ↓↓↓:"
,
typ
)
t
.
Errorf
(
"%v: panic ↓↓↓:"
,
typ
)
...
@@ -79,10 +79,10 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
...
@@ -79,10 +79,10 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
}
}
}()
}()
//
pkt
.encode() == expected
//
msg
.encode() == expected
msgCode
:=
pkt
.
NEOPkt
MsgCode
()
msgCode
:=
msg
.
NEO
MsgCode
()
n
:=
pkt
.
NEOPkt
EncodedLen
()
n
:=
msg
.
NEOMsg
EncodedLen
()
msgType
:=
pkt
TypeRegistry
[
msgCode
]
msgType
:=
msg
TypeRegistry
[
msgCode
]
if
msgType
!=
typ
{
if
msgType
!=
typ
{
t
.
Errorf
(
"%v: msgCode = %v which corresponds to %v"
,
typ
,
msgCode
,
msgType
)
t
.
Errorf
(
"%v: msgCode = %v which corresponds to %v"
,
typ
,
msgCode
,
msgType
)
}
}
...
@@ -91,7 +91,7 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
...
@@ -91,7 +91,7 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
}
}
buf
:=
make
([]
byte
,
n
)
buf
:=
make
([]
byte
,
n
)
pkt
.
NEOPkt
Encode
(
buf
)
msg
.
NEOMsg
Encode
(
buf
)
if
string
(
buf
)
!=
encoded
{
if
string
(
buf
)
!=
encoded
{
t
.
Errorf
(
"%v: encode result unexpected:"
,
typ
)
t
.
Errorf
(
"%v: encode result unexpected:"
,
typ
)
t
.
Errorf
(
"
\t
have: %s"
,
hexpkg
.
EncodeToString
(
buf
))
t
.
Errorf
(
"
\t
have: %s"
,
hexpkg
.
EncodeToString
(
buf
))
...
@@ -121,13 +121,13 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
...
@@ -121,13 +121,13 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
}
}
}()
}()
pkt
.
NEOPkt
Encode
(
buf
[
:
l
])
msg
.
NEOMsg
Encode
(
buf
[
:
l
])
}()
}()
}
}
//
pkt
.decode() == expected
//
msg
.decode() == expected
data
:=
[]
byte
(
encoded
+
"noise"
)
data
:=
[]
byte
(
encoded
+
"noise"
)
n
,
err
:=
pkt2
.
NEOPkt
Decode
(
data
)
n
,
err
:=
msg2
.
NEOMsg
Decode
(
data
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Errorf
(
"%v: decode error %v"
,
typ
,
err
)
t
.
Errorf
(
"%v: decode error %v"
,
typ
,
err
)
}
}
...
@@ -135,13 +135,13 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
...
@@ -135,13 +135,13 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
t
.
Errorf
(
"%v: nread = %v ; want %v"
,
typ
,
n
,
len
(
encoded
))
t
.
Errorf
(
"%v: nread = %v ; want %v"
,
typ
,
n
,
len
(
encoded
))
}
}
if
!
reflect
.
DeepEqual
(
pkt2
,
pkt
)
{
if
!
reflect
.
DeepEqual
(
msg2
,
msg
)
{
t
.
Errorf
(
"%v: decode result unexpected: %v ; want %v"
,
typ
,
pkt2
,
pkt
)
t
.
Errorf
(
"%v: decode result unexpected: %v ; want %v"
,
typ
,
msg2
,
msg
)
}
}
// decode must detect buffer overflow
// decode must detect buffer overflow
for
l
:=
len
(
encoded
)
-
1
;
l
>=
0
;
l
--
{
for
l
:=
len
(
encoded
)
-
1
;
l
>=
0
;
l
--
{
n
,
err
=
pkt2
.
NEOPkt
Decode
(
data
[
:
l
])
n
,
err
=
msg2
.
NEOMsg
Decode
(
data
[
:
l
])
if
!
(
n
==
0
&&
err
==
ErrDecodeOverflow
)
{
if
!
(
n
==
0
&&
err
==
ErrDecodeOverflow
)
{
t
.
Errorf
(
"%v: decode overflow not detected on [:%v]"
,
typ
,
l
)
t
.
Errorf
(
"%v: decode overflow not detected on [:%v]"
,
typ
,
l
)
}
}
...
@@ -149,10 +149,10 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
...
@@ -149,10 +149,10 @@ func testPktMarshal(t *testing.T, pkt Pkt, encoded string) {
}
}
}
}
// test encoding/decoding of
packet
s
// test encoding/decoding of
message
s
func
Test
Pkt
Marshal
(
t
*
testing
.
T
)
{
func
Test
Msg
Marshal
(
t
*
testing
.
T
)
{
var
testv
=
[]
struct
{
var
testv
=
[]
struct
{
pkt
Pkt
msg
Msg
encoded
string
// []byte
encoded
string
// []byte
}
{
}
{
// empty
// empty
...
@@ -259,25 +259,25 @@ func TestPktMarshal(t *testing.T) {
...
@@ -259,25 +259,25 @@ func TestPktMarshal(t *testing.T) {
}
}
for
_
,
tt
:=
range
testv
{
for
_
,
tt
:=
range
testv
{
test
PktMarshal
(
t
,
tt
.
pkt
,
tt
.
encoded
)
test
MsgMarshal
(
t
,
tt
.
msg
,
tt
.
encoded
)
}
}
}
}
// For all
packet types: same as testPkt
Marshal but zero-values only
// For all
message types: same as testMsg
Marshal but zero-values only
// this way we additionally lightly check encode / decode overflow behaviour for all types.
// this way we additionally lightly check encode / decode overflow behaviour for all types.
func
Test
Pkt
MarshalAllOverflowLightly
(
t
*
testing
.
T
)
{
func
Test
Msg
MarshalAllOverflowLightly
(
t
*
testing
.
T
)
{
for
_
,
typ
:=
range
pkt
TypeRegistry
{
for
_
,
typ
:=
range
msg
TypeRegistry
{
// zero-value for a type
// zero-value for a type
pkt
:=
reflect
.
New
(
typ
)
.
Interface
()
.
(
Pkt
)
msg
:=
reflect
.
New
(
typ
)
.
Interface
()
.
(
Msg
)
l
:=
pkt
.
NEOPkt
EncodedLen
()
l
:=
msg
.
NEOMsg
EncodedLen
()
zerol
:=
make
([]
byte
,
l
)
zerol
:=
make
([]
byte
,
l
)
// decoding will turn nil slice & map into empty allocated ones.
// decoding will turn nil slice & map into empty allocated ones.
// we need it so that reflect.DeepEqual works for
pkt
encode/decode comparison
// we need it so that reflect.DeepEqual works for
msg
encode/decode comparison
n
,
err
:=
pkt
.
NEOPkt
Decode
(
zerol
)
n
,
err
:=
msg
.
NEOMsg
Decode
(
zerol
)
if
!
(
n
==
l
&&
err
==
nil
)
{
if
!
(
n
==
l
&&
err
==
nil
)
{
t
.
Errorf
(
"%v: zero-decode unexpected: %v, %v ; want %v, nil"
,
typ
,
n
,
err
,
l
)
t
.
Errorf
(
"%v: zero-decode unexpected: %v, %v ; want %v, nil"
,
typ
,
n
,
err
,
l
)
}
}
test
PktMarshal
(
t
,
pkt
,
string
(
zerol
))
test
MsgMarshal
(
t
,
msg
,
string
(
zerol
))
}
}
}
}
go/neo/protogen.go
View file @
c2a1b63a
...
@@ -20,15 +20,15 @@
...
@@ -20,15 +20,15 @@
/*
/*
NEO. Protocol module. Code generator
NEO. Protocol module. Code generator
This program generates marshalling code for
packet
types defined in proto.go .
This program generates marshalling code for
message
types defined in proto.go .
For every type 4 methods are generated in accordance with neo.
Pkt
interface:
For every type 4 methods are generated in accordance with neo.
Msg
interface:
NEO
Pkt
MsgCode() uint16
NEOMsgCode() uint16
NEO
Pkt
EncodedLen() int
NEO
Msg
EncodedLen() int
NEO
Pkt
Encode(buf []byte)
NEO
Msg
Encode(buf []byte)
NEO
Pkt
Decode(data []byte) (nread int, err error)
NEO
Msg
Decode(data []byte) (nread int, err error)
List of
packet
types is obtained via searching through proto.go AST - looking
List of
message
types is obtained via searching through proto.go AST - looking
for appropriate struct declarations there.
for appropriate struct declarations there.
Code generation for a type is organized via recursively walking through type's
Code generation for a type is organized via recursively walking through type's
...
@@ -169,11 +169,11 @@ import (
...
@@ -169,11 +169,11 @@ import (
"../zodb"
"../zodb"
)`
)
)`
)
pktTypeRegistry
:=
map
[
int
]
string
{}
// pkt
Code -> typename
msgTypeRegistry
:=
map
[
int
]
string
{}
// msg
Code -> typename
// go over
packet
types declaration and generate marshal code for them
// go over
message
types declaration and generate marshal code for them
buf
.
emit
(
"//
packet
s marshalling
\n
"
)
buf
.
emit
(
"//
message
s marshalling
\n
"
)
pkt
Code
:=
0
msg
Code
:=
0
for
_
,
decl
:=
range
f
.
Decls
{
for
_
,
decl
:=
range
f
.
Decls
{
// we look for types (which can be only under GenDecl)
// we look for types (which can be only under GenDecl)
gendecl
,
ok
:=
decl
.
(
*
ast
.
GenDecl
)
gendecl
,
ok
:=
decl
.
(
*
ast
.
GenDecl
)
...
@@ -195,35 +195,35 @@ import (
...
@@ -195,35 +195,35 @@ import (
continue
continue
case
*
ast
.
StructType
:
case
*
ast
.
StructType
:
fmt
.
Fprintf
(
&
buf
,
"// %d. %s
\n\n
"
,
pkt
Code
,
typename
)
fmt
.
Fprintf
(
&
buf
,
"// %d. %s
\n\n
"
,
msg
Code
,
typename
)
buf
.
emit
(
"func (_ *%s) NEO
Pkt
MsgCode() uint16 {"
,
typename
)
buf
.
emit
(
"func (_ *%s) NEOMsgCode() uint16 {"
,
typename
)
buf
.
emit
(
"return %d"
,
pkt
Code
)
buf
.
emit
(
"return %d"
,
msg
Code
)
buf
.
emit
(
"}
\n
"
)
buf
.
emit
(
"}
\n
"
)
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
sizer
{}))
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
sizer
{}))
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
encoder
{}))
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
encoder
{}))
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
decoder
{}))
buf
.
WriteString
(
generateCodecCode
(
typespec
,
&
decoder
{}))
pktTypeRegistry
[
pkt
Code
]
=
typename
msgTypeRegistry
[
msg
Code
]
=
typename
pkt
Code
++
msg
Code
++
}
}
}
}
}
}
// now generate
packet
types registry
// now generate
message
types registry
buf
.
emit
(
"
\n
// registry of
packet
types"
)
buf
.
emit
(
"
\n
// registry of
message
types"
)
buf
.
emit
(
"var
pktTypeRegistry = map[uint16]reflect.Type {"
)
// XXX key -> Pkt
Code ?
buf
.
emit
(
"var
msgTypeRegistry = map[uint16]reflect.Type {"
)
// XXX key -> Msg
Code ?
// ordered by
pkt
Code
// ordered by
msg
Code
pkt
CodeV
:=
[]
int
{}
msg
CodeV
:=
[]
int
{}
for
pktCode
:=
range
pkt
TypeRegistry
{
for
msgCode
:=
range
msg
TypeRegistry
{
pktCodeV
=
append
(
pktCodeV
,
pkt
Code
)
msgCodeV
=
append
(
msgCodeV
,
msg
Code
)
}
}
sort
.
Ints
(
pkt
CodeV
)
sort
.
Ints
(
msg
CodeV
)
for
_
,
pktCode
:=
range
pkt
CodeV
{
for
_
,
msgCode
:=
range
msg
CodeV
{
buf
.
emit
(
"%v: reflect.TypeOf(%v{}),"
,
pktCode
,
pktTypeRegistry
[
pkt
Code
])
buf
.
emit
(
"%v: reflect.TypeOf(%v{}),"
,
msgCode
,
msgTypeRegistry
[
msg
Code
])
}
}
buf
.
emit
(
"}"
)
buf
.
emit
(
"}"
)
...
@@ -456,21 +456,21 @@ func (o *OverflowCheck) AddExpr(format string, a ...interface{}) {
...
@@ -456,21 +456,21 @@ func (o *OverflowCheck) AddExpr(format string, a ...interface{}) {
}
}
// sizer generates code to compute encoded size of a
packet
// sizer generates code to compute encoded size of a
message
//
//
// when type is recursively walked, for every case symbolic size is added appropriately.
// when type is recursively walked, for every case symbolic size is added appropriately.
// in case when it was needed to generate loops, runtime accumulator variable is additionally used.
// in case when it was needed to generate loops, runtime accumulator variable is additionally used.
// result is: symbolic size + (optionally) runtime accumulator.
// result is: symbolic size + (optionally) runtime accumulator.
type
sizer
struct
{
type
sizer
struct
{
commonCodeGen
commonCodeGen
size
SymSize
// currently accumulated
packet
size
size
SymSize
// currently accumulated size
}
}
// encoder generates code to encode a
packet
// encoder generates code to encode a
message
//
//
// when type is recursively walked, for every case code to update `data[n:]` is generated.
// when type is recursively walked, for every case code to update `data[n:]` is generated.
// no overflow checks are generated as by neo.
Pkt
interface provided data
// no overflow checks are generated as by neo.
Msg
interface provided data
// buffer should have at least payloadLen length returned by NEO
Pkt
EncodedInfo()
// buffer should have at least payloadLen length returned by NEO
Msg
EncodedInfo()
// (the size computed by sizer).
// (the size computed by sizer).
//
//
// the code emitted looks like:
// the code emitted looks like:
...
@@ -479,14 +479,14 @@ type sizer struct {
...
@@ -479,14 +479,14 @@ type sizer struct {
// encode<typ2>(data[n2:], path2)
// encode<typ2>(data[n2:], path2)
// ...
// ...
//
//
// TODO encode have to care in NEO
Pkt
Encode to emit preambule such that bound
// TODO encode have to care in NEO
Msg
Encode to emit preambule such that bound
// checking is performed only once (currenty compiler emits many of them)
// checking is performed only once (currenty compiler emits many of them)
type
encoder
struct
{
type
encoder
struct
{
commonCodeGen
commonCodeGen
n
int
// current write position in data
n
int
// current write position in data
}
}
// decoder generates code to decode a
packet
// decoder generates code to decode a
message
//
//
// when type is recursively walked, for every case code to decode next item from
// when type is recursively walked, for every case code to decode next item from
// `data[n:]` is generated.
// `data[n:]` is generated.
...
@@ -527,7 +527,7 @@ var _ CodeGenerator = (*decoder)(nil)
...
@@ -527,7 +527,7 @@ var _ CodeGenerator = (*decoder)(nil)
func
(
s
*
sizer
)
generatedCode
()
string
{
func
(
s
*
sizer
)
generatedCode
()
string
{
code
:=
Buffer
{}
code
:=
Buffer
{}
// prologue
// prologue
code
.
emit
(
"func (%s *%s) NEO
Pkt
EncodedLen() int {"
,
s
.
recvName
,
s
.
typeName
)
code
.
emit
(
"func (%s *%s) NEO
Msg
EncodedLen() int {"
,
s
.
recvName
,
s
.
typeName
)
if
s
.
varUsed
[
"size"
]
{
if
s
.
varUsed
[
"size"
]
{
code
.
emit
(
"var %s int"
,
s
.
var_
(
"size"
))
code
.
emit
(
"var %s int"
,
s
.
var_
(
"size"
))
}
}
...
@@ -548,7 +548,7 @@ func (s *sizer) generatedCode() string {
...
@@ -548,7 +548,7 @@ func (s *sizer) generatedCode() string {
func
(
e
*
encoder
)
generatedCode
()
string
{
func
(
e
*
encoder
)
generatedCode
()
string
{
code
:=
Buffer
{}
code
:=
Buffer
{}
// prologue
// prologue
code
.
emit
(
"func (%s *%s) NEO
Pkt
Encode(data []byte) {"
,
e
.
recvName
,
e
.
typeName
)
code
.
emit
(
"func (%s *%s) NEO
Msg
Encode(data []byte) {"
,
e
.
recvName
,
e
.
typeName
)
code
.
Write
(
e
.
buf
.
Bytes
())
code
.
Write
(
e
.
buf
.
Bytes
())
...
@@ -655,7 +655,7 @@ func (d *decoder) generatedCode() string {
...
@@ -655,7 +655,7 @@ func (d *decoder) generatedCode() string {
code
:=
Buffer
{}
code
:=
Buffer
{}
// prologue
// prologue
code
.
emit
(
"func (%s *%s) NEO
Pkt
Decode(data []byte) (int, error) {"
,
d
.
recvName
,
d
.
typeName
)
code
.
emit
(
"func (%s *%s) NEO
Msg
Decode(data []byte) (int, error) {"
,
d
.
recvName
,
d
.
typeName
)
if
d
.
varUsed
[
"nread"
]
{
if
d
.
varUsed
[
"nread"
]
{
code
.
emit
(
"var %v uint32"
,
d
.
var_
(
"nread"
))
code
.
emit
(
"var %v uint32"
,
d
.
var_
(
"nread"
))
}
}
...
...
go/neo/server/master.go
View file @
c2a1b63a
...
@@ -64,7 +64,7 @@ type Master struct {
...
@@ -64,7 +64,7 @@ type Master struct {
type
nodeCome
struct
{
type
nodeCome
struct
{
link
*
neo
.
NodeLink
link
*
neo
.
NodeLink
idReq
neo
.
RequestIdentification
// we received this identification request
idReq
neo
.
RequestIdentification
// we received this identification request
idResp
chan
neo
.
Pkt
// what we reply (AcceptIdentification | Error)
idResp
chan
neo
.
Msg
// what we reply (AcceptIdentification | Error)
}
}
// node disconnects
// node disconnects
...
@@ -701,7 +701,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
...
@@ -701,7 +701,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
}
}
// convey identification request to master
// convey identification request to master
idRespCh
:=
make
(
chan
neo
.
Pkt
)
idRespCh
:=
make
(
chan
neo
.
Msg
)
m
.
nodeCome
<-
nodeCome
{
link
,
idReq
,
idRespCh
}
m
.
nodeCome
<-
nodeCome
{
link
,
idReq
,
idRespCh
}
idResp
:=
<-
idRespCh
idResp
:=
<-
idRespCh
...
@@ -757,7 +757,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
...
@@ -757,7 +757,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
m
.
stateMu
.
Unlock
()
m
.
stateMu
.
Unlock
()
go
func
()
{
go
func
()
{
var
pkt
neo
.
Pkt
var
msg
neo
.
Msg
for
{
for
{
select
{
select
{
...
@@ -767,7 +767,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
...
@@ -767,7 +767,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
return
return
case
nodeUpdateV
:=
<-
nodeCh
:
case
nodeUpdateV
:=
<-
nodeCh
:
pkt
=
&
neo
.
NotifyNodeInformation
{
msg
=
&
neo
.
NotifyNodeInformation
{
IdTimestamp
:
math
.
NaN
(),
// XXX
IdTimestamp
:
math
.
NaN
(),
// XXX
NodeList
:
nodeUpdateV
,
NodeList
:
nodeUpdateV
,
}
}
...
@@ -776,7 +776,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
...
@@ -776,7 +776,7 @@ func (m *Master) ServeLink(ctx context.Context, link *neo.NodeLink) {
// changed = true
// changed = true
}
}
err
=
neo
.
EncodeAndSend
(
connNotify
,
pkt
)
err
=
neo
.
EncodeAndSend
(
connNotify
,
msg
)
if
err
!=
nil
{
if
err
!=
nil
{
// XXX err
// XXX err
}
}
...
...
go/neo/server/storage.go
View file @
c2a1b63a
...
@@ -277,7 +277,7 @@ func (stor *Storage) ServeClient(ctx context.Context, conn *neo.Conn) {
...
@@ -277,7 +277,7 @@ func (stor *Storage) ServeClient(ctx context.Context, conn *neo.Conn) {
xid
.
TidBefore
=
true
xid
.
TidBefore
=
true
}
}
var
reply
neo
.
Pkt
var
reply
neo
.
Msg
data
,
tid
,
err
:=
stor
.
zstor
.
Load
(
xid
)
data
,
tid
,
err
:=
stor
.
zstor
.
Load
(
xid
)
if
err
!=
nil
{
if
err
!=
nil
{
// TODO translate err to NEO protocol error codes
// TODO translate err to NEO protocol error codes
...
@@ -299,7 +299,7 @@ func (stor *Storage) ServeClient(ctx context.Context, conn *neo.Conn) {
...
@@ -299,7 +299,7 @@ func (stor *Storage) ServeClient(ctx context.Context, conn *neo.Conn) {
neo
.
EncodeAndSend
(
conn
,
reply
)
// XXX err
neo
.
EncodeAndSend
(
conn
,
reply
)
// XXX err
case
*
neo
.
LastTransaction
:
case
*
neo
.
LastTransaction
:
var
reply
neo
.
Pkt
var
reply
neo
.
Msg
lastTid
,
err
:=
stor
.
zstor
.
LastTid
()
lastTid
,
err
:=
stor
.
zstor
.
LastTid
()
if
err
!=
nil
{
if
err
!=
nil
{
...
...
go/neo/x_connection.go
View file @
c2a1b63a
...
@@ -10,9 +10,9 @@ import (
...
@@ -10,9 +10,9 @@ import (
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/go123/xerr"
)
)
// Recv
AndDecode receives packet from conn and decodes
it
// Recv
receives packet and decodes message from
it
func
RecvAndDecode
(
conn
*
Conn
)
(
Pkt
,
error
)
{
func
RecvAndDecode
(
conn
*
Conn
)
(
Msg
,
error
)
{
pkt
,
err
:=
conn
.
Recv
()
pkt
,
err
:=
conn
.
recvPkt
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -20,7 +20,7 @@ func RecvAndDecode(conn *Conn) (Pkt, error) {
...
@@ -20,7 +20,7 @@ func RecvAndDecode(conn *Conn) (Pkt, error) {
// decode packet
// decode packet
pkth
:=
pkt
.
Header
()
pkth
:=
pkt
.
Header
()
msgCode
:=
ntoh16
(
pkth
.
MsgCode
)
msgCode
:=
ntoh16
(
pkth
.
MsgCode
)
msgType
:=
pkt
TypeRegistry
[
msgCode
]
msgType
:=
msg
TypeRegistry
[
msgCode
]
if
msgType
==
nil
{
if
msgType
==
nil
{
err
=
fmt
.
Errorf
(
"invalid msgCode (%d)"
,
msgCode
)
err
=
fmt
.
Errorf
(
"invalid msgCode (%d)"
,
msgCode
)
// XXX -> ProtoError ?
// XXX -> ProtoError ?
...
@@ -28,47 +28,47 @@ func RecvAndDecode(conn *Conn) (Pkt, error) {
...
@@ -28,47 +28,47 @@ func RecvAndDecode(conn *Conn) (Pkt, error) {
}
}
// TODO use free-list for decoded packets + when possible decode in-place
// TODO use free-list for decoded packets + when possible decode in-place
pktObj
:=
reflect
.
New
(
msgType
)
.
Interface
()
.
(
Pkt
)
msg
:=
reflect
.
New
(
msgType
)
.
Interface
()
.
(
Msg
)
_
,
err
=
pktObj
.
NEOPkt
Decode
(
pkt
.
Payload
())
_
,
err
=
msg
.
NEOMsg
Decode
(
pkt
.
Payload
())
if
err
!=
nil
{
if
err
!=
nil
{
// XXX -> ProtoError ?
// XXX -> ProtoError ?
return
nil
,
&
ConnError
{
Conn
:
conn
,
Op
:
"decode"
,
Err
:
err
}
return
nil
,
&
ConnError
{
Conn
:
conn
,
Op
:
"decode"
,
Err
:
err
}
}
}
return
pktObj
,
nil
return
msg
,
nil
}
}
// EncodeAndSend encodes
pkt and sends it to conn
// EncodeAndSend encodes
message into packet and sends it
func
EncodeAndSend
(
conn
*
Conn
,
pkt
Pkt
)
error
{
func
EncodeAndSend
(
conn
*
Conn
,
msg
Msg
)
error
{
l
:=
pkt
.
NEOPkt
EncodedLen
()
l
:=
msg
.
NEOMsg
EncodedLen
()
buf
:=
PktBuf
{
make
([]
byte
,
PktHeadLen
+
l
)}
// XXX -> freelist
buf
:=
PktBuf
{
make
([]
byte
,
PktHeadLen
+
l
)}
// XXX -> freelist
h
:=
buf
.
Header
()
h
:=
buf
.
Header
()
// h.ConnId will be set by conn.Send
// h.ConnId will be set by conn.Send
h
.
MsgCode
=
hton16
(
pkt
.
NEOPkt
MsgCode
())
h
.
MsgCode
=
hton16
(
msg
.
NEO
MsgCode
())
h
.
MsgLen
=
hton32
(
uint32
(
l
))
// XXX casting: think again
h
.
MsgLen
=
hton32
(
uint32
(
l
))
// XXX casting: think again
pkt
.
NEOPkt
Encode
(
buf
.
Payload
())
msg
.
NEOMsg
Encode
(
buf
.
Payload
())
return
conn
.
Send
(
&
buf
)
// XXX why pointer?
return
conn
.
sendPkt
(
&
buf
)
// XXX why pointer?
}
}
// Ask does simple request/response protocol exchange
// Ask does simple request/response protocol exchange
// It expects the answer to be exactly of resp type and errors otherwise
// It expects the answer to be exactly of resp type and errors otherwise
func
Ask
(
conn
*
Conn
,
req
Pkt
,
resp
Pkt
)
error
{
func
Ask
(
conn
*
Conn
,
req
Msg
,
resp
Msg
)
error
{
err
:=
EncodeAndSend
(
conn
,
req
)
err
:=
EncodeAndSend
(
conn
,
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
err
=
Expect
(
conn
,
resp
)
err
=
Expect
(
conn
,
resp
)
// XXX +Error
return
err
return
err
}
}
// ProtoError is returned when there wa
a
a protocol error, like receiving
// ProtoError is returned when there wa
s
a protocol error, like receiving
// unexpected packet or packet with wrong header
// unexpected packet or packet with wrong header
//
XXX -> ConnError{Op: "decode"} ?
//
FIXME -> ConnError{Op: "decode"}
type
ProtoError
struct
{
type
ProtoError
struct
{
Conn
*
Conn
Conn
*
Conn
Err
error
Err
error
...
@@ -80,8 +80,8 @@ func (e *ProtoError) Error() string {
...
@@ -80,8 +80,8 @@ func (e *ProtoError) Error() string {
// Expect receives 1 packet and expects it to be exactly of msg type
// Expect receives 1 packet and expects it to be exactly of msg type
// XXX naming (-> Recv1 ?)
// XXX naming (-> Recv1 ?)
func
Expect
(
conn
*
Conn
,
msg
Pkt
)
(
err
error
)
{
func
Expect
(
conn
*
Conn
,
msg
Msg
)
(
err
error
)
{
pkt
,
err
:=
conn
.
Recv
()
pkt
,
err
:=
conn
.
recvPkt
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -92,11 +92,11 @@ func Expect(conn *Conn, msg Pkt) (err error) {
...
@@ -92,11 +92,11 @@ func Expect(conn *Conn, msg Pkt) (err error) {
pkth
:=
pkt
.
Header
()
pkth
:=
pkt
.
Header
()
msgCode
:=
ntoh16
(
pkth
.
MsgCode
)
msgCode
:=
ntoh16
(
pkth
.
MsgCode
)
if
msgCode
!=
msg
.
NEO
Pkt
MsgCode
()
{
if
msgCode
!=
msg
.
NEOMsgCode
()
{
// unexpected Error response
// unexpected Error response
if
msgCode
==
(
&
Error
{})
.
NEO
Pkt
MsgCode
()
{
if
msgCode
==
(
&
Error
{})
.
NEOMsgCode
()
{
errResp
:=
Error
{}
errResp
:=
Error
{}
_
,
err
=
errResp
.
NEO
Pkt
Decode
(
pkt
.
Payload
())
_
,
err
=
errResp
.
NEO
Msg
Decode
(
pkt
.
Payload
())
if
err
!=
nil
{
if
err
!=
nil
{
return
&
ProtoError
{
conn
,
err
}
return
&
ProtoError
{
conn
,
err
}
}
}
...
@@ -108,7 +108,7 @@ func Expect(conn *Conn, msg Pkt) (err error) {
...
@@ -108,7 +108,7 @@ func Expect(conn *Conn, msg Pkt) (err error) {
return
ErrDecode
(
&
errResp
)
// XXX err ctx vs ^^^ errcontextf ?
return
ErrDecode
(
&
errResp
)
// XXX err ctx vs ^^^ errcontextf ?
}
}
msgType
:=
pkt
TypeRegistry
[
msgCode
]
msgType
:=
msg
TypeRegistry
[
msgCode
]
if
msgType
==
nil
{
if
msgType
==
nil
{
return
&
ProtoError
{
conn
,
fmt
.
Errorf
(
"invalid msgCode (%d)"
,
msgCode
)}
return
&
ProtoError
{
conn
,
fmt
.
Errorf
(
"invalid msgCode (%d)"
,
msgCode
)}
}
}
...
@@ -116,7 +116,7 @@ func Expect(conn *Conn, msg Pkt) (err error) {
...
@@ -116,7 +116,7 @@ func Expect(conn *Conn, msg Pkt) (err error) {
return
&
ProtoError
{
conn
,
fmt
.
Errorf
(
"unexpected packet: %v"
,
msgType
)}
return
&
ProtoError
{
conn
,
fmt
.
Errorf
(
"unexpected packet: %v"
,
msgType
)}
}
}
_
,
err
=
msg
.
NEO
Pkt
Decode
(
pkt
.
Payload
())
_
,
err
=
msg
.
NEO
Msg
Decode
(
pkt
.
Payload
())
if
err
!=
nil
{
if
err
!=
nil
{
return
&
ProtoError
{
conn
,
err
}
return
&
ProtoError
{
conn
,
err
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment