...

Source file src/github.com/sassoftware/relic/internal/activation/notify_unix.go

Documentation: github.com/sassoftware/relic/internal/activation

     1  // Copyright © SAS Institute Inc.
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  //     http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  //
    14  // +build !windows
    15  
    16  package activation
    17  
    18  import (
    19  	"fmt"
    20  	"net"
    21  	"os"
    22  	"strconv"
    23  	"syscall"
    24  )
    25  
    26  // DaemonReady signals to a parent init system or daemon manager that the
    27  // daemon is finished starting up. Use after all listening sockets have been
    28  // opened.
    29  func DaemonReady() (err error) {
    30  	if name := os.Getenv("NOTIFY_SOCKET"); name != "" {
    31  		// systemd
    32  		if err2 := writePath(name, "unixgram", "READY=1"); err2 != nil {
    33  			err = err2
    34  		}
    35  	}
    36  	if fdstr := os.Getenv("NOTIFY_FD"); fdstr != "" {
    37  		// github.com/pusher/crank
    38  		if err2 := writeFd(fdstr, "READY=1"); err2 != nil {
    39  			err = err2
    40  		}
    41  	}
    42  	if fdstr := os.Getenv("EINHORN_SOCK_FD"); fdstr != "" {
    43  		// einhorn -g
    44  		if err2 := writeFd(fdstr, einhornReadyStr()); err2 != nil {
    45  			err = err2
    46  		}
    47  	} else if name := os.Getenv("EINHORN_SOCK_PATH"); name != "" {
    48  		// github.com/stripe/einhorn
    49  		if err2 := writePath(name, "unix", einhornReadyStr()); err2 != nil {
    50  			err = err2
    51  		}
    52  	}
    53  	return
    54  }
    55  
    56  // write a string to the unix socket at the named path
    57  func writePath(path, netType, message string) error {
    58  	sockAddr := &net.UnixAddr{Name: path, Net: netType}
    59  	conn, err := net.DialUnix(netType, nil, sockAddr)
    60  	if err != nil {
    61  		return err
    62  	}
    63  	defer conn.Close()
    64  	_, err = conn.Write([]byte(message))
    65  	return err
    66  }
    67  
    68  // write a string to a numeric file descriptor
    69  func writeFd(fdstr, message string) error {
    70  	fd, err := strconv.Atoi(fdstr)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	_, err = syscall.Write(fd, []byte(message))
    75  	return err
    76  }
    77  
    78  func einhornReadyStr() string {
    79  	return fmt.Sprintf(`{"command":"worker:ack", "pid":%d}`+"\n", os.Getpid())
    80  }
    81  

View as plain text