summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2012-04-11 13:39:34 +0200
committerYorhel <git@yorhel.nl>2012-04-11 13:39:34 +0200
commitb5fa905ea22d4d166760fe82f8912c145579d05d (patch)
tree5d0e9ebcdd42819a559478914e8bc2c85ab9b3db
parent62f4d5b3bda688a7099a99b9d84b76b831f5ead8 (diff)
hub: Async disconnect
-rw-r--r--src/globster/hub/hub.go34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/globster/hub/hub.go b/src/globster/hub/hub.go
index da032e5..810e758 100644
--- a/src/globster/hub/hub.go
+++ b/src/globster/hub/hub.go
@@ -7,7 +7,7 @@ import (
"time"
)
-// TODO: Do the connect() and write()s in a separate goroutine.
+// TODO: Do write()s in a separate goroutine.
type hub struct {
name string
@@ -70,30 +70,36 @@ func (s *hub) Tconnect(addr string) {
}()
}
+// Sending 'disconnect' will immediately put the hub into disconnected state,
+// but the actual disconnect from the hub may take a while. The "Disconnected"
+// notification is sent immediately, but the return path is only closed after
+// the disconnect has been completed.
func (s *hub) Tdisconnect(m *tanja.Message, r ...tanja.Element) {
- // If we're in the connecting state, set connCh to nil so we won't be
- // getting its result. In case the connection was successful, make sure to
- // immediately disconnect again.
+ s.ses.Sendt(false, append(tanja.Tup("hub", s.name, "Disconnected"), r...))
+
if s.connCh != nil {
+ // If we're in the connecting state, set connCh to nil so we won't be
+ // getting its result. In case the connection was successful, make sure
+ // to immediately disconnect again.
go func(ch <-chan interface{}) {
if c, ok := (<-ch).(net.Conn); ok {
c.Close()
}
}(s.connCh)
s.connCh = nil
- s.ses.Sendt(false, append(tanja.Tup("hub", s.name, "Disconnected"), r...))
- }
+ m.Close()
- // If we're connected, properly disconnect. (TODO: async?)
- if s.conn != nil {
- s.conn.Close()
+ } else if s.conn != nil {
+ // If we're connected, close the connection.
+ go func(c net.Conn) {
+ c.Close()
+ m.Close()
+ }(s.conn)
s.conn = nil
- s.ses.Sendt(false, append(tanja.Tup("hub", s.name, "Disconnected"), r...))
- }
- // Only close the return-path after disconnect, to allow users to wait for
- // successful disconnect.
- m.Close()
+ } else {
+ m.Close()
+ }
}
func (s *hub) connected(r interface{}) {