From 7e7bc59fda106777e71f43f602f4515549ac5618 Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Tue, 5 Aug 2014 18:44:26 +0700 Subject: [PATCH] Bumped version number to 0.1.2 --- daemon.go | 278 +++++++++++++++++++++++++++-------------------------- darwin.go | 2 +- linux.go | 2 +- windows.go | 12 +-- 4 files changed, 148 insertions(+), 146 deletions(-) diff --git a/daemon.go b/daemon.go index fe94091..8681ffc 100644 --- a/daemon.go +++ b/daemon.go @@ -1,144 +1,146 @@ // Copyright 2014 Igor Dolzhikov. All rights reserved. -// Use of this source code is governed by a BSD-style +// Use of this source code is governed by // license that can be found in the LICENSE file. -// Package daemon 0.1.1 for use with Go (golang) services. -// -// Package daemon provides primitives for daemonization of golang services. -// This package is not provide implementation of user daemon, -// accordingly must have root rights to install/remove service. -// In the current implementation is only supported Linux and Mac Os X daemon. -// -// Example: -// -// //Example of the daemon with echo service -// package main -// -// import ( -// "fmt" -// "log" -// "net" -// "os" -// "os/signal" -// "syscall" -// -// "github.com/takama/daemon" -// ) -// -// const ( -// -// // name of the service, match with executable file name -// name = "myservice" -// description = "My Echo Service" -// -// // port which daemon should be listen -// port = ":9977" -// ) -// -// type Service struct { -// daemon.Daemon -// } -// -// func (service *Service) Manage() (string, error) { -// -// usage := "Usage: myservice install | remove | start | stop | status" -// -// // if received any kind of command, do it -// if len(os.Args) > 1 { -// command := os.Args[1] -// switch command { -// case "install": -// return service.Install() -// case "remove": -// return service.Remove() -// case "start": -// return service.Start() -// case "stop": -// return service.Stop() -// case "status": -// return service.Status() -// default: -// return usage, nil -// } -// } -// -// // Do something, call your goroutines, etc -// -// // Set up channel on which to send signal notifications. -// // We must use a buffered channel or risk missing the signal -// // if we're not ready to receive when the signal is sent. -// interrupt := make(chan os.Signal, 1) -// signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) -// -// // Set up listener for defined host and port -// listener, err := net.Listen("tcp", port) -// if err != nil { -// return "Possibly was a problem with the port binding", err -// } -// -// // set up channel on which to send accepted connections -// listen := make(chan net.Conn, 100) -// go acceptConnection(listener, listen) -// -// // loop work cycle with accept connections or interrupt -// // by system signal -// for { -// select { -// case conn := <-listen: -// go handleClient(conn) -// case killSignal := <-interrupt: -// log.Println("Got signal:", killSignal) -// log.Println("Stoping listening on ", listener.Addr()) -// listener.Close() -// if killSignal == os.Interrupt { -// return "Daemon was interruped by system signal", nil -// } -// return "Daemon was killed", nil -// } -// } -// -// // never happen, but need to complete code -// return usage, nil -// } -// -// // Accept a client connection and collect it in a channel -// func acceptConnection(listener net.Listener, listen chan<- net.Conn) { -// for { -// conn, err := listener.Accept() -// if err != nil { -// continue -// } -// listen <- conn -// } -// } -// -// func handleClient(client net.Conn) { -// for { -// buf := make([]byte, 4096) -// numbytes, err := client.Read(buf) -// if numbytes == 0 || err != nil { -// return -// } -// client.Write(buf) -// } -// } -// -// func main() { -// srv, err := daemon.New(name, description) -// if err != nil { -// fmt.Println("Error: ", err) -// os.Exit(1) -// } -// service := &Service{srv} -// status, err := service.Manage() -// if err != nil { -// fmt.Println(status, "\nError: ", err) -// os.Exit(1) -// } -// fmt.Println(status) -// } -// -// Go daemon +/* +Package daemon 0.1.2 for use with Go (golang) services. + +Package daemon provides primitives for daemonization of golang services. +This package is not provide implementation of user daemon, +accordingly must have root rights to install/remove service. +In the current implementation is only supported Linux and Mac Os X daemon. + +Example: + + //Example of the daemon with echo service + package main + + import ( + "fmt" + "log" + "net" + "os" + "os/signal" + "syscall" + + "github.com/takama/daemon" + ) + + const ( + + // name of the service, match with executable file name + name = "myservice" + description = "My Echo Service" + + // port which daemon should be listen + port = ":9977" + ) + + type Service struct { + daemon.Daemon + } + + func (service *Service) Manage() (string, error) { + + usage := "Usage: myservice install | remove | start | stop | status" + + // if received any kind of command, do it + if len(os.Args) > 1 { + command := os.Args[1] + switch command { + case "install": + return service.Install() + case "remove": + return service.Remove() + case "start": + return service.Start() + case "stop": + return service.Stop() + case "status": + return service.Status() + default: + return usage, nil + } + } + + // Do something, call your goroutines, etc + + // Set up channel on which to send signal notifications. + // We must use a buffered channel or risk missing the signal + // if we're not ready to receive when the signal is sent. + interrupt := make(chan os.Signal, 1) + signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) + + // Set up listener for defined host and port + listener, err := net.Listen("tcp", port) + if err != nil { + return "Possibly was a problem with the port binding", err + } + + // set up channel on which to send accepted connections + listen := make(chan net.Conn, 100) + go acceptConnection(listener, listen) + + // loop work cycle with accept connections or interrupt + // by system signal + for { + select { + case conn := <-listen: + go handleClient(conn) + case killSignal := <-interrupt: + log.Println("Got signal:", killSignal) + log.Println("Stoping listening on ", listener.Addr()) + listener.Close() + if killSignal == os.Interrupt { + return "Daemon was interruped by system signal", nil + } + return "Daemon was killed", nil + } + } + + // never happen, but need to complete code + return usage, nil + } + + // Accept a client connection and collect it in a channel + func acceptConnection(listener net.Listener, listen chan<- net.Conn) { + for { + conn, err := listener.Accept() + if err != nil { + continue + } + listen <- conn + } + } + + func handleClient(client net.Conn) { + for { + buf := make([]byte, 4096) + numbytes, err := client.Read(buf) + if numbytes == 0 || err != nil { + return + } + client.Write(buf) + } + } + + func main() { + srv, err := daemon.New(name, description) + if err != nil { + fmt.Println("Error: ", err) + os.Exit(1) + } + service := &Service{srv} + status, err := service.Manage() + if err != nil { + fmt.Println(status, "\nError: ", err) + os.Exit(1) + } + fmt.Println(status) + } + +Go daemon +*/ package daemon import ( diff --git a/darwin.go b/darwin.go index 8c396f0..c04b65a 100644 --- a/darwin.go +++ b/darwin.go @@ -1,5 +1,5 @@ // Copyright 2014 Igor Dolzhikov. All rights reserved. -// Use of this source code is governed by a BSD-style +// Use of this source code is governed by // license that can be found in the LICENSE file. // Package daemon darwin (mac os x) version diff --git a/linux.go b/linux.go index 60d63c8..89108a8 100644 --- a/linux.go +++ b/linux.go @@ -1,5 +1,5 @@ // Copyright 2014 Igor Dolzhikov. All rights reserved. -// Use of this source code is governed by a BSD-style +// Use of this source code is governed by // license that can be found in the LICENSE file. // Package daemon linux version diff --git a/windows.go b/windows.go index 2350b30..f6dbc9f 100644 --- a/windows.go +++ b/windows.go @@ -1,5 +1,5 @@ // Copyright 2014 Igor Dolzhikov. All rights reserved. -// Use of this source code is governed by a BSD-style +// Use of this source code is governed by // license that can be found in the LICENSE file. // Package daemon windows version @@ -24,32 +24,32 @@ func newDaemon(name, description string) (*WindowsRecord, error) { func (windows *WindowsRecord) Install() (string, error) { installAction := "Install " + windows.description + ":" - return installAction + failed, errors.New("windows daemon not supported") + return installAction + failed, errors.New("windows daemon is not supported") } // Remove the service func (windows *WindowsRecord) Remove() (string, error) { removeAction := "Removing " + windows.description + ":" - return removeAction + failed, errors.New("windows daemon not supported") + return removeAction + failed, errors.New("windows daemon is not supported") } // Start the service func (windows *WindowsRecord) Start() (string, error) { startAction := "Starting " + windows.description + ":" - return startAction + failed, errors.New("windows daemon not supported") + return startAction + failed, errors.New("windows daemon is not supported") } // Stop the service func (windows *WindowsRecord) Stop() (string, error) { stopAction := "Stopping " + windows.description + ":" - return stopAction + failed, errors.New("windows daemon not supported") + return stopAction + failed, errors.New("windows daemon is not supported") } // Status - Get service status func (windows *WindowsRecord) Status() (string, error) { - return "Status could not defined", errors.New("windows daemon not supported") + return "Status could not defined", errors.New("windows daemon is not supported") }