Finishing shutdown implementation
This commit is contained in:
parent
b11510ef9c
commit
ecbb599d48
1 changed files with 57 additions and 8 deletions
|
@ -14,6 +14,8 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/metonimie/simpleFTP/server/server/config"
|
"github.com/metonimie/simpleFTP/server/server/config"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -35,10 +37,15 @@ var uploadTimeout time.Duration
|
||||||
|
|
||||||
// Shutdown is the shutdown where SIGINT and SIGTERM is send too
|
// Shutdown is the shutdown where SIGINT and SIGTERM is send too
|
||||||
var Shutdown = make(chan os.Signal, 1)
|
var Shutdown = make(chan os.Signal, 1)
|
||||||
|
var ftpShutdown = make(chan struct{}, 1)
|
||||||
|
var uploadShutdown = make(chan struct{}, 1)
|
||||||
|
|
||||||
var uploadListener net.Listener
|
var uploadListener net.Listener
|
||||||
var ftpListener net.Listener
|
var ftpListener net.Listener
|
||||||
|
|
||||||
|
// All connected clients
|
||||||
|
var clients map[Client]bool
|
||||||
|
|
||||||
// Client interface provides the blueprints for the Client that is used by the server.
|
// Client interface provides the blueprints for the Client that is used by the server.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
Connection() net.Conn // Connection returns the connection stream.
|
Connection() net.Conn // Connection returns the connection stream.
|
||||||
|
@ -83,23 +90,43 @@ func shutdownHandler() {
|
||||||
select {
|
select {
|
||||||
case <-Shutdown:
|
case <-Shutdown:
|
||||||
log.Println("Shutdown signal received")
|
log.Println("Shutdown signal received")
|
||||||
if ftpListener != nil {
|
var wg sync.WaitGroup
|
||||||
ftpListener.Close()
|
wg.Add(1)
|
||||||
}
|
|
||||||
if uploadListener != nil {
|
go func() { // Disconnect all the clients.
|
||||||
uploadListener.Close()
|
for k := range clients {
|
||||||
}
|
k.Disconnect()
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
ShutdownFtpServer()
|
||||||
|
ShutdownUploadServer()
|
||||||
|
|
||||||
// FIXME: Find a way to close all clients before this
|
|
||||||
os.Exit(0)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ShutdownUploadServer() {
|
||||||
|
if uploadListener != nil {
|
||||||
|
uploadListener.Close()
|
||||||
|
uploadShutdown <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ShutdownFtpServer() {
|
||||||
|
if ftpListener != nil {
|
||||||
|
ftpListener.Close()
|
||||||
|
ftpShutdown <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
signal.Notify(Shutdown, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(Shutdown, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
clients = make(map[Client]bool)
|
||||||
go shutdownHandler()
|
go shutdownHandler()
|
||||||
|
|
||||||
config.InitializeConfiguration("config", ConfigPath)
|
config.InitializeConfiguration("config", ConfigPath)
|
||||||
|
@ -122,6 +149,7 @@ func HandleConnection(client Client) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Println(client.Connection().RemoteAddr(), "has connected.")
|
log.Println(client.Connection().RemoteAddr(), "has connected.")
|
||||||
|
clients[client] = true
|
||||||
|
|
||||||
// Process input
|
// Process input
|
||||||
input := bufio.NewScanner(client.Connection())
|
input := bufio.NewScanner(client.Connection())
|
||||||
|
@ -137,6 +165,7 @@ func HandleConnection(client Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client has left.
|
// Client has left.
|
||||||
|
delete(clients, client)
|
||||||
log.Println(client.Connection().RemoteAddr(), "has disconnected.")
|
log.Println(client.Connection().RemoteAddr(), "has disconnected.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +188,14 @@ func StartFtpServer() error {
|
||||||
log.Println("Ftp server running on:", Addr, "port", Port)
|
log.Println("Ftp server running on:", Addr, "port", Port)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// Handle shutdown
|
||||||
|
select {
|
||||||
|
case <-ftpShutdown:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
// move on
|
||||||
|
}
|
||||||
|
|
||||||
conn, err := ftpListener.Accept()
|
conn, err := ftpListener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
@ -182,6 +219,7 @@ func HandleUpload(conn net.Conn) {
|
||||||
// Upload directory
|
// Upload directory
|
||||||
client.Stack().Push(uploadDirectory)
|
client.Stack().Push(uploadDirectory)
|
||||||
client.SetConnection(conn)
|
client.SetConnection(conn)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
// Create the file on the disk and make sure that the filename is random.
|
// Create the file on the disk and make sure that the filename is random.
|
||||||
var filename = randSeq(10)
|
var filename = randSeq(10)
|
||||||
|
@ -195,6 +233,7 @@ func HandleUpload(conn net.Conn) {
|
||||||
// This channel will be used to store the uploadResult
|
// This channel will be used to store the uploadResult
|
||||||
c1 := make(chan error, 1)
|
c1 := make(chan error, 1)
|
||||||
log.Println(conn.RemoteAddr().String() + " is uploading something.")
|
log.Println(conn.RemoteAddr().String() + " is uploading something.")
|
||||||
|
clients[&client] = true
|
||||||
|
|
||||||
// Create a new Go routine for uploading
|
// Create a new Go routine for uploading
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -226,6 +265,8 @@ func HandleUpload(conn net.Conn) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(clients, &client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartUploadServer starts the uploading server
|
// StartUploadServer starts the uploading server
|
||||||
|
@ -260,6 +301,14 @@ func StartUploadServer() error {
|
||||||
log.Println("Upload server running on:", addr, "port", port)
|
log.Println("Upload server running on:", addr, "port", port)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// Handle shutdown
|
||||||
|
select {
|
||||||
|
case <-uploadShutdown:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
// move on
|
||||||
|
}
|
||||||
|
|
||||||
conn, err := uploadListener.Accept()
|
conn, err := uploadListener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
|
Loading…
Reference in a new issue