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
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
neoppod
Commits
d38c5c77
Commit
d38c5c77
authored
Sep 13, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
9fa79958
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
20 deletions
+72
-20
go/neo/connection.go
go/neo/connection.go
+23
-14
go/neo/connection_test.go
go/neo/connection_test.go
+49
-6
No files found.
go/neo/connection.go
View file @
d38c5c77
...
...
@@ -99,13 +99,8 @@ type Conn struct {
rxqActive
int32
// atomic: 1 while serveRecv is doing `rxq <- ...`
rxdownFlag
int32
// atomic: 1 when RX is marked no longer operational
// !light only
rxdown
chan
struct
{}
// ready when RX is marked no longer operational
rxdownOnce
sync
.
Once
// ----//---- XXX review
rxclosed
int32
// whether CloseRecv was called
rxerrOnce
sync
.
Once
// rx error is reported only once - then it is link down or closed
errMsg
*
Error
// error message for peer if rx is down
rxerrOnce
sync
.
Once
// rx error is reported only once - then it is link down or closed XXX !light?
errMsg
*
Error
// error message for peer if rx is down XXX try to do without it
txerr
chan
error
// transmit results for this Conn go back here
...
...
@@ -113,6 +108,21 @@ type Conn struct {
txdownOnce
sync
.
Once
// tx shutdown may be called by both Close and nodelink.shutdown
txclosed
int32
// whether CloseSend was called
// there are two modes a Conn could be used:
// - full mode - where full Conn functionality is working, and
// - light mode - where only subset functionality is working
//
// the light mode is used to implement Recv1 & friends - there any
// connection is used max to send and/or receive only 1 packet and then
// has to be reused for efficiency ideally without reallocating anything.
//
// everything below is used during !light mode only.
rxdown
chan
struct
{}
// ready when RX is marked no longer operational
rxdownOnce
sync
.
Once
// ----//---- XXX review
rxclosed
int32
// whether CloseRecv was called
// closing Conn is shutdown + some cleanup work to remove it from
// link.connTab including arming timers etc. Let this work be spawned only once.
// (for Conn.Close to be valid called several times)
...
...
@@ -340,15 +350,14 @@ func (c *Conn) shutdownTX() {
// shutdownRX marks .rxq as no loner operational and interrupts Recv.
func
(
c
*
Conn
)
shutdownRX
(
errMsg
*
Error
)
{
c
.
rxdownOnce
.
Do
(
func
()
{
c
.
errMsg
=
errMsg
close
(
c
.
rxdown
)
// wakeup Conn.Recv
c
.
downRX
()
c
.
downRX
(
errMsg
)
})
}
// downRX marks .rxq as no longer operational
func
(
c
*
Conn
)
downRX
()
{
// downRX marks .rxq as no longer operational.
func
(
c
*
Conn
)
downRX
(
errMsg
*
Error
)
{
c
.
errMsg
=
errMsg
atomic
.
StoreInt32
(
&
c
.
rxdownFlag
,
1
)
// dequeue all packets already queued in c.rxq
...
...
@@ -1365,10 +1374,10 @@ func (link *NodeLink) Recv1() (Request, error) {
return
Request
{},
err
}
// noone will be reading from conn anymore -
shutdown rx
so that if
// noone will be reading from conn anymore -
mark rx down
so that if
// peer sends any another packet with same .ConnID serveRecv does not
// deadlock trying to put it to conn.rxq.
conn
.
CloseRecv
(
)
conn
.
downRX
(
errConnClosed
)
return
Request
{
Msg
:
msg
,
conn
:
conn
},
nil
}
...
...
go/neo/connection_test.go
View file @
d38c5c77
...
...
@@ -25,6 +25,7 @@ import (
"context"
"io"
"net"
"reflect"
"testing"
"time"
...
...
@@ -133,7 +134,7 @@ func xverifyPkt(pkt *PktBuf, connid uint32, msgcode uint16, payload []byte) {
}
// Verify PktBuf to match expected message
func
xverifyMsg
(
pkt
*
PktBuf
,
connid
uint32
,
msg
Msg
)
{
func
xverify
Pkt
Msg
(
pkt
*
PktBuf
,
connid
uint32
,
msg
Msg
)
{
data
:=
make
([]
byte
,
msg
.
neoMsgEncodedLen
())
msg
.
neoMsgEncode
(
data
)
xverifyPkt
(
pkt
,
connid
,
msg
.
neoMsgCode
(),
data
)
...
...
@@ -522,12 +523,12 @@ func TestNodeLink(t *testing.T) {
//println("X γγγ + 1")
pkt
=
xrecvPkt
(
c
)
//println("X γγγ + 2")
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
xverify
Pkt
Msg
(
pkt
,
c
.
connId
,
errConnRefused
)
xsendPkt
(
c
,
mkpkt
(
40
,
[]
byte
(
"pong4"
)))
// once again
//println("X γγγ + 3")
pkt
=
xrecvPkt
(
c
)
//println("X γγγ + 4")
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
xverify
Pkt
Msg
(
pkt
,
c
.
connId
,
errConnRefused
)
//println("X zzz")
...
...
@@ -553,11 +554,11 @@ func TestNodeLink(t *testing.T) {
//println("111 + 1")
pkt
=
xrecvPkt
(
c1
)
//println("111 + 2")
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xverify
Pkt
Msg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xsendPkt
(
c1
,
mkpkt
(
39
,
[]
byte
(
"ping4"
)))
// once again
pkt
=
xrecvPkt
(
c1
)
//println("111 + 4")
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xverify
Pkt
Msg
(
pkt
,
c1
.
connId
,
errConnClosed
)
// XXX also should get EOF on recv
//println("222")
...
...
@@ -569,7 +570,7 @@ func TestNodeLink(t *testing.T) {
<-
closed
xsendPkt
(
c2
,
mkpkt
(
41
,
[]
byte
(
"ping6"
)))
pkt
=
xrecvPkt
(
c2
)
xverifyMsg
(
pkt
,
c2
.
connId
,
errConnClosed
)
xverify
Pkt
Msg
(
pkt
,
c2
.
connId
,
errConnClosed
)
//println("333 z")
xwait
(
wg
)
...
...
@@ -734,6 +735,48 @@ func TestHandshake(t *testing.T) {
}
// ---- recv1 mode ----
func
xSend
(
c
*
Conn
,
msg
Msg
)
{
err
:=
c
.
Send
(
msg
)
exc
.
Raiseif
(
err
)
}
func
xRecv
(
c
*
Conn
)
Msg
{
msg
,
err
:=
c
.
Recv
()
exc
.
Raiseif
(
err
)
return
msg
}
func
xRecv1
(
l
*
NodeLink
)
Request
{
req
,
err
:=
l
.
Recv1
()
exc
.
Raiseif
(
err
)
return
req
}
func
xverifyMsg
(
msg1
,
msg2
Msg
)
{
if
!
reflect
.
DeepEqual
(
msg1
,
msg2
)
{
exc
.
Raisef
(
"messages differ:
\n
%s"
,
pretty
.
Compare
(
msg1
,
msg2
))
}
}
func
TestRecv1Mode
(
t
*
testing
.
T
)
{
// Recv1: further packets with same connid are rejected with "connection closed"
nl1
,
nl2
:=
nodeLinkPipe
()
wg
:=
&
xsync
.
WorkGroup
{}
wg
.
Gox
(
func
()
{
c
:=
xnewconn
(
nl2
)
xSend
(
c
,
&
Ping
{})
xSend
(
c
,
&
Ping
{})
msg
:=
xRecv
(
c
)
xverifyMsg
(
msg
,
errConnClosed
)
})
_
=
xRecv1
(
nl1
)
xwait
(
wg
)
}
// ---- benchmarks ----
// rtt over chan - for comparision as base
...
...
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