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
91be5cdd
Commit
91be5cdd
authored
Aug 31, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X everyone is listening from start; CloseAccept to disable listening - works
parent
0a27363b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
63 additions
and
41 deletions
+63
-41
go/neo/connection.go
go/neo/connection.go
+35
-29
go/neo/connection_test.go
go/neo/connection_test.go
+28
-12
No files found.
go/neo/connection.go
View file @
91be5cdd
...
@@ -104,9 +104,10 @@ type Conn struct {
...
@@ -104,9 +104,10 @@ type Conn struct {
errMsg
*
Error
// error message for peer if rx is down
errMsg
*
Error
// error message for peer if rx is down
// after Close Conn is kept for some time in link.connTab so peer could
// closing Conn is shutdown + some cleanup work to remove it from
// receive "connection closed" and then GC'ed
// link.connTab including arming timers etc. Let this work be spawned only once.
gcOnce
sync
.
Once
// (for Conn.Close to be valid called several times)
closeOnce
sync
.
Once
}
}
...
@@ -412,42 +413,45 @@ func (c *Conn) Close() error {
...
@@ -412,42 +413,45 @@ func (c *Conn) Close() error {
}
}
nl.connMu.Unlock()
nl.connMu.Unlock()
*/
*/
c
.
closeOnce
.
Do
(
func
()
{
atomic
.
StoreInt32
(
&
c
.
rxclosed
,
1
)
atomic
.
StoreInt32
(
&
c
.
txclosed
,
1
)
c
.
shutdown
()
atomic
.
StoreInt32
(
&
c
.
rxclosed
,
1
)
// adjust link.connTab
atomic
.
StoreInt32
(
&
c
.
txclosed
,
1
)
var
tmpclosed
*
Conn
c
.
shutdown
()
nl
.
connMu
.
Lock
()
if
nl
.
connTab
!=
nil
{
// adjust link.connTab
// connection was initiated by us - simply delete - we always
keep
:=
false
// know if a packet comes to such connection - it is closed.
nl
.
connMu
.
Lock
()
//
if
nl
.
connTab
!=
nil
{
// XXX checking vvv should be possible without connMu lock
// connection was initiated by us - simply delete - we always
if
c
.
connId
==
nl
.
nextConnId
%
2
{
// know if a packet comes to such connection - it is closed.
delete
(
nl
.
connTab
,
c
.
connId
)
//
// XXX checking vvv should be possible without connMu lock
if
c
.
connId
==
nl
.
nextConnId
%
2
{
delete
(
nl
.
connTab
,
c
.
connId
)
// connection was initiated by peer which we accepted.
// connection was initiated by peer which we accepted - put special
// it is already shutted down.
// "closed" connection into connTab entry for some time to reply
// keep connTab entry for it for some time to reply
// "connection closed" if another packet comes to it.
// "connection closed" if another packet comes to it.
//
}
else
{
// ( we cannot reuse same connection since after it is marked as
keep
=
true
// closed Send refuses to work )
}
else
{
// c implicitly goes away from connTab
tmpclosed
=
nl
.
newConn
(
c
.
connId
)
}
}
}
nl
.
connMu
.
Unlock
()
}
if
tmpclosed
!=
nil
{
nl
.
connMu
.
Unlock
(
)
tmpclosed
.
shutdownRX
(
errConnClosed
)
if
keep
{
c
.
gcOnce
.
Do
(
func
()
{
time
.
AfterFunc
(
connKeepClosed
,
func
()
{
time
.
AfterFunc
(
connKeepClosed
,
func
()
{
nl
.
connMu
.
Lock
()
nl
.
connMu
.
Lock
()
delete
(
nl
.
connTab
,
c
.
connId
)
delete
(
nl
.
connTab
,
c
.
connId
)
nl
.
connMu
.
Unlock
()
nl
.
connMu
.
Unlock
()
})
})
}
)
}
}
}
)
return
nil
return
nil
}
}
...
@@ -700,7 +704,9 @@ var errConnRefused = &Error{PROTOCOL_ERROR, "connection refused"}
...
@@ -700,7 +704,9 @@ var errConnRefused = &Error{PROTOCOL_ERROR, "connection refused"}
// replyNoConn sends error message to peer when a packet was sent to closed / nonexistent connection
// replyNoConn sends error message to peer when a packet was sent to closed / nonexistent connection
func
(
c
*
Conn
)
replyNoConn
()
{
func
(
c
*
Conn
)
replyNoConn
()
{
//fmt.Printf("%v: -> replyNoConn %v\n", c, c.errMsg)
c
.
Send
(
c
.
errMsg
)
// ignore errors
c
.
Send
(
c
.
errMsg
)
// ignore errors
//fmt.Printf("%v: replyNoConn(%v) -> %v\n", c, c.errMsg, err)
}
}
// ---- transmit ----
// ---- transmit ----
...
...
go/neo/connection_test.go
View file @
91be5cdd
...
@@ -168,8 +168,6 @@ func nodeLinkPipe() (nl1, nl2 *NodeLink) {
...
@@ -168,8 +168,6 @@ func nodeLinkPipe() (nl1, nl2 *NodeLink) {
func
TestNodeLink
(
t
*
testing
.
T
)
{
func
TestNodeLink
(
t
*
testing
.
T
)
{
// TODO catch exception -> add proper location from it -> t.Fatal (see git-backup)
// TODO catch exception -> add proper location from it -> t.Fatal (see git-backup)
println
(
"000"
)
// Close vs recvPkt
// Close vs recvPkt
nl1
,
nl2
:=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
nl1
,
nl2
:=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
wg
:=
&
xsync
.
WorkGroup
{}
wg
:=
&
xsync
.
WorkGroup
{}
...
@@ -184,8 +182,6 @@ func TestNodeLink(t *testing.T) {
...
@@ -184,8 +182,6 @@ func TestNodeLink(t *testing.T) {
xwait
(
wg
)
xwait
(
wg
)
xclose
(
nl2
)
xclose
(
nl2
)
println
(
"222"
)
// Close vs sendPkt
// Close vs sendPkt
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
wg
=
&
xsync
.
WorkGroup
{}
wg
=
&
xsync
.
WorkGroup
{}
...
@@ -208,12 +204,10 @@ func TestNodeLink(t *testing.T) {
...
@@ -208,12 +204,10 @@ func TestNodeLink(t *testing.T) {
tdelay
()
tdelay
()
xclose
(
nl2
)
xclose
(
nl2
)
})
})
println
(
"222 + 1"
)
c
,
err
:=
nl2
.
Accept
()
c
,
err
:=
nl2
.
Accept
()
if
!
(
c
==
nil
&&
xlinkError
(
err
)
==
ErrLinkClosed
)
{
if
!
(
c
==
nil
&&
xlinkError
(
err
)
==
ErrLinkClosed
)
{
t
.
Fatalf
(
"NodeLink.Accept() after close: conn = %v, err = %v"
,
c
,
err
)
t
.
Fatalf
(
"NodeLink.Accept() after close: conn = %v, err = %v"
,
c
,
err
)
}
}
println
(
"222 + 2"
)
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
tdelay
()
tdelay
()
nl1
.
CloseAccept
()
nl1
.
CloseAccept
()
...
@@ -229,12 +223,8 @@ func TestNodeLink(t *testing.T) {
...
@@ -229,12 +223,8 @@ func TestNodeLink(t *testing.T) {
if
!
(
c
==
nil
&&
xlinkError
(
err
)
==
ErrLinkNoListen
)
{
if
!
(
c
==
nil
&&
xlinkError
(
err
)
==
ErrLinkNoListen
)
{
t
.
Fatalf
(
"NodeLink.Accept() on non-listening node link: conn = %v, err = %v"
,
c
,
err
)
t
.
Fatalf
(
"NodeLink.Accept() on non-listening node link: conn = %v, err = %v"
,
c
,
err
)
}
}
println
(
"222 + 3"
)
xclose
(
nl1
)
xclose
(
nl1
)
println
(
"333"
)
// Close vs recvPkt on another side
// Close vs recvPkt on another side
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
nl1
,
nl2
=
_nodeLinkPipe
(
linkNoRecvSend
,
linkNoRecvSend
)
wg
=
&
xsync
.
WorkGroup
{}
wg
=
&
xsync
.
WorkGroup
{}
...
@@ -468,13 +458,12 @@ func TestNodeLink(t *testing.T) {
...
@@ -468,13 +458,12 @@ func TestNodeLink(t *testing.T) {
}
}
//println("\n---------------------\n")
saveKeepClosed
:=
connKeepClosed
saveKeepClosed
:=
connKeepClosed
connKeepClosed
=
10
*
time
.
Millisecond
connKeepClosed
=
10
*
time
.
Millisecond
// Conn accept + exchange
// Conn accept + exchange
nl1
,
nl2
=
nodeLinkPipe
()
nl1
,
nl2
=
nodeLinkPipe
()
nl1
.
CloseAccept
()
wg
=
&
xsync
.
WorkGroup
{}
wg
=
&
xsync
.
WorkGroup
{}
closed
:=
make
(
chan
int
)
closed
:=
make
(
chan
int
)
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
...
@@ -494,27 +483,42 @@ func TestNodeLink(t *testing.T) {
...
@@ -494,27 +483,42 @@ func TestNodeLink(t *testing.T) {
xclose
(
c
)
xclose
(
c
)
closed
<-
1
closed
<-
1
//println("X ααα")
// once again as ^^^ but finish only with CloseRecv
// once again as ^^^ but finish only with CloseRecv
c2
:=
xaccept
(
nl2
)
c2
:=
xaccept
(
nl2
)
//println("X ααα + 1")
pkt
=
xrecvPkt
(
c2
)
pkt
=
xrecvPkt
(
c2
)
//println("X ααα + 2")
xverifyPkt
(
pkt
,
c2
.
connId
,
41
,
[]
byte
(
"ping5"
))
xverifyPkt
(
pkt
,
c2
.
connId
,
41
,
[]
byte
(
"ping5"
))
xsendPkt
(
c2
,
mkpkt
(
42
,
[]
byte
(
"pong5"
)))
xsendPkt
(
c2
,
mkpkt
(
42
,
[]
byte
(
"pong5"
)))
//println("X βββ")
c2
.
CloseRecv
()
c2
.
CloseRecv
()
closed
<-
2
closed
<-
2
//println("X γγγ")
// "connection refused" when trying to connect to not-listening peer
// "connection refused" when trying to connect to not-listening peer
c
=
xnewconn
(
nl2
)
// XXX should get error here?
c
=
xnewconn
(
nl2
)
// XXX should get error here?
xsendPkt
(
c
,
mkpkt
(
38
,
[]
byte
(
"pong3"
)))
xsendPkt
(
c
,
mkpkt
(
38
,
[]
byte
(
"pong3"
)))
//println("X γγγ + 1")
pkt
=
xrecvPkt
(
c
)
pkt
=
xrecvPkt
(
c
)
//println("X γγγ + 2")
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
xsendPkt
(
c
,
mkpkt
(
40
,
[]
byte
(
"pong4"
)))
// once again
xsendPkt
(
c
,
mkpkt
(
40
,
[]
byte
(
"pong4"
)))
// once again
//println("X γγγ + 3")
pkt
=
xrecvPkt
(
c
)
pkt
=
xrecvPkt
(
c
)
//println("X γγγ + 4")
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
xverifyMsg
(
pkt
,
c
.
connId
,
errConnRefused
)
//println("X zzz")
xclose
(
c
)
xclose
(
c
)
})
})
//println("000")
c1
:=
xnewconn
(
nl1
)
c1
:=
xnewconn
(
nl1
)
xsendPkt
(
c1
,
mkpkt
(
33
,
[]
byte
(
"ping"
)))
xsendPkt
(
c1
,
mkpkt
(
33
,
[]
byte
(
"ping"
)))
pkt
=
xrecvPkt
(
c1
)
pkt
=
xrecvPkt
(
c1
)
...
@@ -523,16 +527,22 @@ func TestNodeLink(t *testing.T) {
...
@@ -523,16 +527,22 @@ func TestNodeLink(t *testing.T) {
pkt
=
xrecvPkt
(
c1
)
pkt
=
xrecvPkt
(
c1
)
xverifyPkt
(
pkt
,
c1
.
connId
,
36
,
[]
byte
(
"pong2"
))
xverifyPkt
(
pkt
,
c1
.
connId
,
36
,
[]
byte
(
"pong2"
))
//println("111")
// "connection closed" after peer closed its end
// "connection closed" after peer closed its end
<-
closed
<-
closed
//println("111 + closed")
xsendPkt
(
c1
,
mkpkt
(
37
,
[]
byte
(
"ping3"
)))
xsendPkt
(
c1
,
mkpkt
(
37
,
[]
byte
(
"ping3"
)))
//println("111 + 1")
pkt
=
xrecvPkt
(
c1
)
pkt
=
xrecvPkt
(
c1
)
//println("111 + 2")
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xsendPkt
(
c1
,
mkpkt
(
39
,
[]
byte
(
"ping4"
)))
// once again
xsendPkt
(
c1
,
mkpkt
(
39
,
[]
byte
(
"ping4"
)))
// once again
pkt
=
xrecvPkt
(
c1
)
pkt
=
xrecvPkt
(
c1
)
//println("111 + 4")
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
xverifyMsg
(
pkt
,
c1
.
connId
,
errConnClosed
)
// XXX also should get EOF on recv
// XXX also should get EOF on recv
//println("222")
// one more time but now peer does only .CloseRecv()
// one more time but now peer does only .CloseRecv()
c2
:=
xnewconn
(
nl1
)
c2
:=
xnewconn
(
nl1
)
xsendPkt
(
c2
,
mkpkt
(
41
,
[]
byte
(
"ping5"
)))
xsendPkt
(
c2
,
mkpkt
(
41
,
[]
byte
(
"ping5"
)))
...
@@ -543,7 +553,9 @@ func TestNodeLink(t *testing.T) {
...
@@ -543,7 +553,9 @@ func TestNodeLink(t *testing.T) {
pkt
=
xrecvPkt
(
c2
)
pkt
=
xrecvPkt
(
c2
)
xverifyMsg
(
pkt
,
c2
.
connId
,
errConnClosed
)
xverifyMsg
(
pkt
,
c2
.
connId
,
errConnClosed
)
//println("333 z")
xwait
(
wg
)
xwait
(
wg
)
//println("444")
// make sure entry for closed nl2.1 stays in nl2.connTab
// make sure entry for closed nl2.1 stays in nl2.connTab
nl2
.
connMu
.
Lock
()
nl2
.
connMu
.
Lock
()
...
@@ -560,12 +572,16 @@ func TestNodeLink(t *testing.T) {
...
@@ -560,12 +572,16 @@ func TestNodeLink(t *testing.T) {
}
}
nl2
.
connMu
.
Unlock
()
nl2
.
connMu
.
Unlock
()
//println("555")
xclose
(
c1
)
xclose
(
c1
)
xclose
(
c2
)
xclose
(
c2
)
xclose
(
nl1
)
xclose
(
nl1
)
xclose
(
nl2
)
xclose
(
nl2
)
connKeepClosed
=
saveKeepClosed
connKeepClosed
=
saveKeepClosed
//println("\nsss")
// test 2 channels with replies coming in reversed time order
// test 2 channels with replies coming in reversed time order
nl1
,
nl2
=
nodeLinkPipe
()
nl1
,
nl2
=
nodeLinkPipe
()
wg
=
&
xsync
.
WorkGroup
{}
wg
=
&
xsync
.
WorkGroup
{}
...
...
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