summaryrefslogtreecommitdiffhomepage
path: root/src/go/unit/unit.go
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2017-12-13 18:12:13 +0300
committerMax Romanov <max.romanov@nginx.com>2017-12-13 18:12:13 +0300
commit799cff5f3e226d8a82a767714c59815939a989dd (patch)
treea844660aba1423de68726f55a83cdbe6a7d49d82 /src/go/unit/unit.go
parentb680e944d65d56e92919287247bd47e13ad030e9 (diff)
downloadunit-799cff5f3e226d8a82a767714c59815939a989dd.tar.gz
unit-799cff5f3e226d8a82a767714c59815939a989dd.tar.bz2
Introducing Unit version check in Go package.
To communicate with the Go program, Unit setup environment variable named NXT_GO_PORTS with value contains Unit version, stream id to confirm application is started, and Unit ports information. Go Unit package parses this string and compares runtime version with compile time version. In case of parse error or version mismatch, ListenAndServe() returns with the error.
Diffstat (limited to 'src/go/unit/unit.go')
-rw-r--r--src/go/unit/unit.go61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/go/unit/unit.go b/src/go/unit/unit.go
index 82a54ecc..77be7612 100644
--- a/src/go/unit/unit.go
+++ b/src/go/unit/unit.go
@@ -11,6 +11,7 @@ package unit
import "C"
import (
+ "errors"
"fmt"
"net/http"
"os"
@@ -65,31 +66,53 @@ func ListenAndServe(addr string, handler http.Handler) error {
var read_port *port
go_ports_env := os.Getenv("NXT_GO_PORTS")
+ if go_ports_env == "" {
+ return http.ListenAndServe(addr, handler)
+ }
+
+ nxt_go_debug("NXT_GO_PORTS=%s", go_ports_env)
ports := strings.Split(go_ports_env, ";")
pid := os.Getpid()
- for _, port_str := range ports {
- if len(port_str) <= 0 {
- continue
- }
+ if len(ports) != 4 {
+ return errors.New("Invalid NXT_GO_PORTS format")
+ }
+
+ nxt_go_debug("version=%s", ports[0])
+
+ builtin_version := C.GoString(C.nxt_go_version())
+
+ if ports[0] != builtin_version {
+ return fmt.Errorf("Versions mismatch: Unit %s, while application is built with %s",
+ ports[0], builtin_version)
+ }
+
+ stream, stream_err := strconv.Atoi(ports[1])
+ if stream_err != nil {
+ return stream_err
+ }
+
+ read_port = nil
+ for _, port_str := range ports[2:] {
attrs := strings.Split(port_str, ",")
+ if len(attrs) != 5 {
+ return fmt.Errorf("Invalid port format: unexpected port attributes number %d, while 5 expected",
+ len(attrs))
+ }
+
var attrsN [5]int
var err error
for i, attr := range attrs {
attrsN[i], err = strconv.Atoi(attr)
if err != nil {
- fmt.Printf("err %s\n", err)
- break
+ return fmt.Errorf("Invalid port format: number attribute expected at %d position instead of '%s'",
+ i, attr);
}
}
- if err != nil {
- continue
- }
-
p := new_port(attrsN[0], attrsN[1], attrsN[2], attrsN[3], attrsN[4])
if attrsN[0] == pid {
@@ -97,17 +120,17 @@ func ListenAndServe(addr string, handler http.Handler) error {
}
}
- if read_port != nil {
- C.nxt_go_ready()
+ if read_port == nil {
+ return errors.New("Application read port not found");
+ }
- for !nxt_go_quit {
- err := read_port.read(handler)
- if err != nil {
- return err
- }
+ C.nxt_go_ready(C.uint32_t(stream))
+
+ for !nxt_go_quit {
+ err := read_port.read(handler)
+ if err != nil {
+ return err
}
- } else {
- return http.ListenAndServe(addr, handler)
}
return nil