Skip to content

Commit

Permalink
Merge branch 'hotfix-0.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
takama committed Aug 5, 2014
2 parents 5c31cfe + 7e7bc59 commit 646d1f2
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 146 deletions.
278 changes: 140 additions & 138 deletions daemon.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
2 changes: 1 addition & 1 deletion darwin.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion linux.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 6 additions & 6 deletions windows.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
}

0 comments on commit 646d1f2

Please sign in to comment.