Example #1
0
func main() {
	// Daemonizing echo server application.
	switch isDaemon, err := daemon.Daemonize(); {
	case !isDaemon:
		return
	case err != nil:
		log.Fatalf("main(): could not start daemon, reason -> %s", err.Error())
	}
	// From now we are running in daemon process.

	// Listen on TCP port 2000 on all interfaces.
	l, err := net.Listen("tcp", ":2000")
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()
	for {
		// Wait for a connection.
		conn, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		// Handle the connection in a new goroutine.
		// The loop then returns to accepting, so that
		// multiple connections may be served concurrently.
		go func(c net.Conn) {
			// Echo all incoming data.
			io.Copy(c, c)
			// Shut down the connection.
			c.Close()
		}(conn)
	}
}
Example #2
0
func main() {
	// Daemonizing http server.
	switch isDaemon, err := daemon.Daemonize(); {
	case !isDaemon:
		return
	case err != nil:
		log.Fatalf("main(): could not start daemon, reason -> %s", err.Error())
	}
	// From now we are running in daemon process.

	// Starting listen tcp on 8888 port.
	listener, hasPrev, err := previousListener()
	if err != nil {
		if hasPrev {
			log.Fatalf(
				"main(): failed to resume listener, reason -> %s", err.Error(),
			)
		}
		if listener, err = net.Listen("tcp", ":8888"); err != nil {
			log.Fatalf("main(): failed to listen, reason -> %s", err.Error())
		}
	}
	httpServer := &http.Server{}

	// Listen OS signals in separate goroutine.
	go listenSignals(listener, httpServer)

	// Creating a simple one-page http server.
	PID := os.Getppid()
	waiter := new(sync.WaitGroup)
	http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		waiter.Add(1)
		fmt.Fprintf(w, "Hi! I am graceful http server! My PID is %d", PID)
		waiter.Done()
	})
	waiter.Add(1)
	go func() {
		if err := httpServer.Serve(listener); err != nil && !isErrClosing(err) {
			log.Fatalf(
				"main(): failed to serve listener, reason -> %s", err.Error(),
			)
		}
		waiter.Done()
	}()

	// If was started by "reload" option.
	if hasPrev {
		if err := syscall.Kill(PID, syscall.SIGUSR1); err != nil {
			log.Printf(
				"main(): failed to notify parent daemon procces, reason -> %s",
				err.Error(),
			)
		}
	}

	// Waiting all requests to be finished.
	waiter.Wait()
}
Example #3
0
func main() {
	// Daemonizing http server.
	switch isDaemon, err := daemon.Daemonize(); {
	case !isDaemon:
		return
	case err != nil:
		log.Fatalf("main(): could not start daemon, reason -> %s", err.Error())
	}
	// From now we are running in daemon process.

	// Imitating "heavy" initialization phase.
	time.Sleep(time.Second)

	// Creating "Hello, World!" HTTP server.
	http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		w.Write([]byte("Hello, World!"))
	})
	listener, err := net.Listen("tcp", ":8889")
	if err != nil {
		log.Fatalf(
			"main(): failed to listen on port :8889, reason -> %s", err.Error(),
		)
	}
	defer listener.Close()
	stoppedRunning := make(chan struct{})
	go func() {
		defer close(stoppedRunning)
		if err := http.Serve(listener, nil); err != nil && !isErrClosing(err) {
			log.Fatalf(
				"main(): failed to serve listener, reason -> %s", err.Error(),
			)
		}
	}()

	// Imitating more "heavy" initialization tasks.
	time.Sleep(time.Second)

	// Notifying parent process that we have started successfully.
	if err := syscall.Kill(os.Getppid(), syscall.SIGUSR1); err != nil {
		log.Fatalf(
			"main(): notifying parent proccess failed, reason -> %s",
			err.Error(),
		)
	}

	// Preventing main goroutine from closing while HTTP server is running.
	<-stoppedRunning
}