mirror of
https://github.com/renorris/openfsd
synced 2026-04-18 00:45:33 +08:00
tweak semantics for listener, add documentation
This commit is contained in:
26
main.go
26
main.go
@@ -45,15 +45,20 @@ const TableCreateStatement = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
func StartFSDServer(fsdCtx context.Context) {
|
func StartFSDServer(fsdCtx context.Context) {
|
||||||
|
// Attempt to resolve the previously-configured listen address
|
||||||
addr, err := net.ResolveTCPAddr("tcp4", SC.FsdListenAddr)
|
addr, err := net.ResolveTCPAddr("tcp4", SC.FsdListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error resolving address: " + err.Error())
|
log.Fatal("Error resolving address: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to open a listener on that address
|
||||||
listener, err := net.ListenTCP("tcp4", addr)
|
listener, err := net.ListenTCP("tcp4", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error listening: " + err.Error())
|
log.Fatal("Error listening: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defer listener close
|
||||||
|
// This will force the listener goroutine to encounter an error and promptly close itself
|
||||||
defer func() {
|
defer func() {
|
||||||
closeErr := listener.Close()
|
closeErr := listener.Close()
|
||||||
if closeErr != nil {
|
if closeErr != nil {
|
||||||
@@ -61,29 +66,36 @@ func StartFSDServer(fsdCtx context.Context) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Listener goroutine
|
// Listen on a separate goroutine
|
||||||
inConnections := make(chan *net.TCPConn)
|
// connChan shall be closed when the listener closes (due to an error or surrounding context closed)
|
||||||
go func(outConnections chan<- *net.TCPConn) {
|
connChan := make(chan *net.TCPConn)
|
||||||
defer close(outConnections)
|
go func(connChan chan<- *net.TCPConn) {
|
||||||
|
// Guarantee that connChan will be closed when we return
|
||||||
|
defer close(connChan)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// Wait for a connection on the listener
|
||||||
conn, listenerErr := listener.AcceptTCP()
|
conn, listenerErr := listener.AcceptTCP()
|
||||||
if listenerErr != nil {
|
if listenerErr != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for a consumer on connChan, OR return if the context cancels.
|
||||||
select {
|
select {
|
||||||
case outConnections <- conn:
|
case connChan <- conn:
|
||||||
case <-fsdCtx.Done():
|
case <-fsdCtx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(inConnections)
|
}(connChan)
|
||||||
|
|
||||||
log.Println("FSD listening")
|
log.Println("FSD listening")
|
||||||
|
|
||||||
|
// Poll from connChan, check if the channel is healthy
|
||||||
|
// Also poll from our context, check if we need to return
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case conn, ok := <-inConnections:
|
case conn, ok := <-connChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user