THRIFT-2012 Modernizing Go

Patch: Travis Cline
diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am
index 6ca82ed..72901a5 100755
--- a/tutorial/Makefile.am
+++ b/tutorial/Makefile.am
@@ -54,6 +54,10 @@
 #SUBDIRS += hs
 endif
 
+if WITH_GO
+SUBDIRS += go
+endif
+
 #
 # generate html for ThriftTest.thrift
 #
diff --git a/tutorial/go/Make.deps b/tutorial/go/Make.deps
deleted file mode 100644
index e4c2b20..0000000
--- a/tutorial/go/Make.deps
+++ /dev/null
@@ -1,135 +0,0 @@
-src.install: fmt.install net.install os.install strconv.install thrift.install
-archive/tar.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/archive/tar.a
-archive/zip.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/archive/zip.a
-asn1.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/asn1.a
-big.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/big.a
-bufio.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/bufio.a
-bytes.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/bytes.a
-cmath.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/cmath.a
-compress/flate.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/flate.a
-compress/gzip.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/gzip.a
-compress/zlib.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/zlib.a
-container/heap.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/heap.a
-container/list.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/list.a
-container/ring.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/ring.a
-container/vector.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/vector.a
-crypto.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto.a
-crypto/aes.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/aes.a
-crypto/block.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/block.a
-crypto/blowfish.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/blowfish.a
-crypto/cast5.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/cast5.a
-crypto/cipher.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/cipher.a
-crypto/dsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/dsa.a
-crypto/elliptic.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/elliptic.a
-crypto/hmac.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/hmac.a
-crypto/md4.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/md4.a
-crypto/md5.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/md5.a
-crypto/ocsp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/ocsp.a
-crypto/rand.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rand.a
-crypto/rc4.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rc4.a
-crypto/ripemd160.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/ripemd160.a
-crypto/rsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rsa.a
-crypto/sha1.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha1.a
-crypto/sha256.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha256.a
-crypto/sha512.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha512.a
-crypto/subtle.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/subtle.a
-crypto/tls.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/tls.a
-crypto/twofish.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/twofish.a
-crypto/x509.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/x509.a
-crypto/xtea.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/xtea.a
-debug/dwarf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/dwarf.a
-debug/macho.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/macho.a
-debug/elf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/elf.a
-debug/gosym.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/gosym.a
-debug/pe.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/pe.a
-debug/proc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/proc.a
-ebnf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/ebnf.a
-encoding/ascii85.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/ascii85.a
-encoding/base32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/base32.a
-encoding/base64.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/base64.a
-encoding/binary.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/binary.a
-encoding/git85.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/git85.a
-encoding/hex.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/hex.a
-encoding/line.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/line.a
-encoding/pem.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/pem.a
-exec.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exec.a
-exp/datafmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/datafmt.a
-exp/draw.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/draw.a
-exp/draw/x11.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/draw/x11.a
-exp/eval.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/eval.a
-expvar.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/expvar.a
-flag.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/flag.a
-fmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/fmt.a
-go/ast.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/ast.a
-go/doc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/doc.a
-go/parser.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/parser.a
-go/printer.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/printer.a
-go/scanner.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/scanner.a
-go/token.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/token.a
-go/typechecker.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/typechecker.a
-gob.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/gob.a
-hash.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash.a
-hash/adler32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/adler32.a
-hash/crc32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/crc32.a
-hash/crc64.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/crc64.a
-html.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/html.a
-http.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http.a
-http/pprof.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/pprof.a
-image.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image.a
-image/jpeg.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/jpeg.a
-image/png.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/png.a
-index/suffixarray.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/index/suffixarray.a
-io.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/io.a
-io/ioutil.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/io/ioutil.a
-json.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/json.a
-log.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/log.a
-math.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/math.a
-mime.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/mime.a
-mime/multipart.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/mime/multipart.a
-net.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net.a
-net/dict.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net/dict.a
-net/textproto.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net/textproto.a
-netchan.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/netchan.a
-os.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/os.a
-os/signal.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/os/signal.a
-patch.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/patch.a
-path.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/path.a
-rand.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rand.a
-reflect.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/reflect.a
-regexp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/regexp.a
-rpc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rpc.a
-rpc/jsonrpc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rpc/jsonrpc.a
-runtime.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime.a
-runtime/cgo.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/cgo.a
-runtime/debug.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/debug.a
-runtime/pprof.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/pprof.a
-scanner.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/scanner.a
-smtp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/smtp.a
-sort.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/sort.a
-strconv.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/strconv.a
-strings.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/strings.a
-sync.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/sync.a
-syscall.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/syscall.a
-syslog.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/syslog.a
-tabwriter.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/tabwriter.a
-template.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/template.a
-testing.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing.a
-testing/iotest.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/iotest.a
-testing/quick.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/quick.a
-testing/script.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/script.a
-time.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/time.a
-try.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/try.a
-unicode.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/unicode.a
-utf16.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/utf16.a
-utf8.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/utf8.a
-websocket.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/websocket.a
-xml.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/xml.a
-../cmd/cgo.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/cgo.a
-../cmd/ebnflint.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/ebnflint.a
-../cmd/godoc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/godoc.a
-../cmd/gofmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gofmt.a
-../cmd/goinstall.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/goinstall.a
-../cmd/govet.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/govet.a
-../cmd/goyacc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/goyacc.a
-../cmd/hgpatch.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/hgpatch.a
-thrift.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/thrift.a
diff --git a/tutorial/go/Makefile b/tutorial/go/Makefile
deleted file mode 100644
index 50c5dfe..0000000
--- a/tutorial/go/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include $(GOROOT)/src/Make.inc
-
-all: Make.deps install
-
-TARG=thriftlib/tutorialcalculator
-
-DIRS=\
-  src/\
-
-GOFILES=\
-
-
-clean.dirs: $(addsuffix .clean, $(DIRS))
-install.dirs: $(addsuffix .install, $(DIRS))
-test.dirs: $(addsuffix .test, $(DIRS))
-
-
-%.clean:
-	+cd $* && $(MAKE) clean
-
-%.install:
-	+cd $* && $(MAKE) install
-
-%.test:
-	+cd $* && $(MAKE) test
-
-
-
-Make.deps:
-	./deps.bash
-
-deps:
-	./deps.bash
-
-clean: clean.dirs
-
-install: install.dirs
-
-test:	test.dirs
-
diff --git a/tutorial/go/Makefile.am b/tutorial/go/Makefile.am
new file mode 100644
index 0000000..2c2b8be
--- /dev/null
+++ b/tutorial/go/Makefile.am
@@ -0,0 +1,51 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift
+	$(THRIFT) --gen go -r $<
+
+all-local: gen-go/tutorial/calculator.go
+
+
+check: src/git.apache.org/thrift.git/lib/go/thrift
+	$(THRIFT) -r --gen go $(top_srcdir)/tutorial/tutorial.thrift
+	cp -r gen-go/* src/
+	GOPATH=`pwd` go build ./...
+	GOPATH=`pwd` go build -o go-tutorial src/*.go
+	GOPATH=`pwd` go build -o calculator-remote src/tutorial/calculator-remote/calculator-remote.go
+
+src/git.apache.org/thrift.git/lib/go/thrift:
+	mkdir -p src/git.apache.org/thrift.git/lib/go
+	ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/git.apache.org/thrift.git/lib/go/thrift
+
+tutorialserver: all
+	GOPATH=`pwd` go run src/*.go -server=true
+
+tutorialclient: all
+	GOPATH=`pwd` go run src/*.go -client=true
+
+clean-local:
+	$(RM) -r gen-*
+
+EXTRA_DIST = \
+	client.py \
+	handler.py \
+	server.py
diff --git a/tutorial/go/deps.bash b/tutorial/go/deps.bash
deleted file mode 100644
index aec6ec2..0000000
--- a/tutorial/go/deps.bash
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-OUT="Make.deps"
-TMP="Make.deps.tmp"
-
-if [ -f $OUT ] && ! [ -w $OUT ]; then
-	echo "$0: $OUT is read-only; aborting." 1>&2
-	exit 1
-fi
-
-# Get list of directories from Makefile
-dirs=$(sed '1,/^DIRS=/d; /^$/,$d; s/\\//g' Makefile)
-dirs2=$(sed '1,/^DIRS=/d; /^$/,$d; s/\\//g' $GOROOT/src/pkg/Makefile)
-dirs3="thrift"
-dirpat=$(echo $dirs $dirs2 $dirs3 | sed 's/ /|/g; s/.*/^(&)$/')
-
-for dir in $dirs; do (
-	cd $dir || exit 1
-
-	sources=$(sed -n 's/\.go\\/.go/p' Makefile)
-	sources=$(ls $sources 2> /dev/null)  # remove .s, .c, etc.
-
-	deps=$(
-		sed -n '/^import.*"/p; /^import[ \t]*(/,/^)/p' $sources /dev/null |
-		cut -d '"' -f2 |
-		egrep "$dirpat" |
-		grep -v "^$dir\$" |
-		sed 's/$/.install/' |
-		sort -u
-	)
-
-	echo $dir.install: $deps
-) done > $TMP
-
-for dir in $dirs2; do (
-  echo $dir.install: \${GOROOT}/pkg/\${GOOS}_\${GOARCH}/${dir}.a
-) done >> $TMP
-for dir in $dirs3; do (
-  echo $dir.install: \${GOROOT}/pkg/\${GOOS}_\${GOARCH}/${dir}.a
-) done >> $TMP
-
-mv $TMP $OUT
diff --git a/tutorial/go/src/CalculatorHandler.go b/tutorial/go/src/CalculatorHandler.go
deleted file mode 100644
index 9eb2838..0000000
--- a/tutorial/go/src/CalculatorHandler.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package main;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import (
-  "fmt"
-  "os"
-  "strconv"
-  "thriftlib/tutorial"
-  "thriftlib/shared"
-)
-
-type CalculatorHandler struct {
-  log map[int]*shared.SharedStruct
-}
-
-func NewCalculatorHandler() *CalculatorHandler {
-  return &CalculatorHandler{log:make(map[int]*shared.SharedStruct)}
-}
-
-func (p *CalculatorHandler) Ping() (err os.Error) {
-  fmt.Print("ping()\n")
-  return nil
-}
-
-func (p *CalculatorHandler) Add(num1 int32, num2 int32) (retval17 int32, err os.Error) {
-  fmt.Print("add(", num1, ",", num2, ")\n")
-  return num1 + num2, nil
-}
-
-func (p *CalculatorHandler) Calculate(logid int32, w *tutorial.Work) (val int32, ouch *tutorial.InvalidOperation, err os.Error) {
-  fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
-  switch(w.Op) {
-  case tutorial.ADD:
-    val = w.Num1 + w.Num2
-    break
-  case tutorial.SUBTRACT:
-    val = w.Num1 - w.Num2
-    break
-  case tutorial.MULTIPLY:
-    val = w.Num1 * w.Num2
-    break
-  case tutorial.DIVIDE:
-    if w.Num2 == 0 {
-      ouch = tutorial.NewInvalidOperation()
-      ouch.What = int32(w.Op)
-      ouch.Why = "Cannot divide by 0"
-      return
-    }
-    val = w.Num1 / w.Num2
-    break
-  default:
-    ouch = tutorial.NewInvalidOperation()
-    ouch.What = int32(w.Op)
-    ouch.Why = "Unknown operation"
-    return
-  }
-  entry := shared.NewSharedStruct()
-  entry.Key = logid
-  entry.Value = strconv.Itoa(int(val))
-  k := int(logid)
-  /*
-  oldvalue, exists := p.log[k]
-  if exists {
-    fmt.Print("Replacing ", oldvalue, " with ", entry, " for key ", k, "\n")
-  } else {
-    fmt.Print("Adding ", entry, " for key ", k, "\n")
-  }
-  */
-  p.log[k] = entry, true
-  return val, ouch, err
-}
-
-func (p *CalculatorHandler) GetStruct(key int32) (*shared.SharedStruct, os.Error) {
-  fmt.Print("getStruct(", key, ")\n")
-  v, _ := p.log[int(key)]
-  return v, nil
-}
-
-func (p *CalculatorHandler) Zip() (err os.Error) {
-  fmt.Print("zip()\n")
-  return nil
-}
-
diff --git a/tutorial/go/src/GoClient.go b/tutorial/go/src/GoClient.go
deleted file mode 100644
index 9440530..0000000
--- a/tutorial/go/src/GoClient.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package main;
-
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-import (
-  "fmt"
-  "net"
-  "os"
-  "thrift"
-  "thriftlib/tutorial"
-)
-
-func Perform(client *tutorial.CalculatorClient) (err os.Error) {
-  client.Ping()
-  fmt.Print("ping()\n")
-  
-  sum, _ := client.Add(1, 1)
-  fmt.Print("1+1=", sum, "\n")
-  
-  work := tutorial.NewWork()
-  work.Op = tutorial.DIVIDE
-  work.Num1 = 1
-  work.Num2 = 0
-  quotient, ouch, err := client.Calculate(1, work)
-  if err != nil {
-    fmt.Print("Error during operation: ", err.String(), "\n")
-    return err
-  } else if ouch != nil {
-    fmt.Print("Invalid operation: ", ouch.String(), "\n")
-  } else {
-    fmt.Print("Whoa we can divide by 0 with new value: ", quotient, "\n")
-  }
-  
-  work.Op = tutorial.SUBTRACT
-  work.Num1 = 15
-  work.Num2 = 10
-  diff, ouch, err := client.Calculate(1, work)
-  if err != nil {
-    fmt.Print("Error during operation: ", err.String(), "\n")
-    return err
-  } else if ouch != nil {
-    fmt.Print("Invalid operation: ", ouch.String(), "\n")
-  } else {
-    fmt.Print("15-10=", diff, "\n")
-  }
-  
-  log, err := client.GetStruct(1)
-  if err != nil {
-    fmt.Print("Unable to get struct: ", err.String(), "\n")
-    return err
-  } else {
-    fmt.Print("Check log: ", log.Value, "\n")
-  }
-  return err
-}
-
-
-func RunClient(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory) os.Error {
-  addr, err := net.ResolveTCPAddr("localhost:9090")
-  if err != nil {
-    fmt.Print("Error resolving address: ", err.String(), "\n")
-    return err
-  }
-  transport := thrift.NewTSocketAddr(addr)
-  if err = transport.Open(); err != nil {
-    fmt.Print("Error opening connection for protocol ", addr.Network(), " to ", addr.String(), ": ", err.String(), "\n")
-    return err
-  }
-  useTransport := transportFactory.GetTransport(transport)
-  client := tutorial.NewCalculatorClientFactory(useTransport, protocolFactory)
-  Perform(client)
-  return transport.Close()
-}
diff --git a/tutorial/go/src/GoServer.go b/tutorial/go/src/GoServer.go
deleted file mode 100644
index f70a2a9..0000000
--- a/tutorial/go/src/GoServer.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package main;
-
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-import (
-  "fmt"
-  "net"
-  "thrift"
-  "thriftlib/tutorial"
-)
-
-
-type GoServer struct {
-  handler tutorial.ICalculator
-  processor *tutorial.CalculatorProcessor
-}
-
-func NewGoServer() *GoServer {
-  handler := NewCalculatorHandler()
-  processor := tutorial.NewCalculatorProcessor(handler)
-  return &GoServer{handler:handler, processor:processor}
-}
-
-func Simple(processor *tutorial.CalculatorProcessor, transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, ch chan int) {
-  addr, err := net.ResolveTCPAddr("localhost:9090")
-  if err != nil {
-    fmt.Print("Error resolving address: ", err.String(), "\n")
-    return
-  }
-  serverTransport, err := thrift.NewTServerSocketAddr(addr)
-  if err != nil {
-    fmt.Print("Error creating server socket: ", err.String(), "\n")
-    return
-  }
-  server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory)
-  // Use this for a multithreaded server
-  // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
-  
-  fmt.Print("Starting the simple server... on ", addr, "\n")
-  for {
-    err = server.Serve()
-    if err != nil {
-      fmt.Print("Error during simple server: ", err.String(), "\n")
-      return
-    }
-  }
-  fmt.Print("Done with the simple server\n")
-  ch <- 1
-}
-
-func Secure(processor *tutorial.CalculatorProcessor) {
-  addr, _ := net.ResolveTCPAddr("localhost:9091")
-  serverTransport, _ := thrift.NewTNonblockingServerSocketAddr(addr)
-  server := thrift.NewTSimpleServer2(processor, serverTransport)
-  fmt.Print("Starting the secure server... on ", addr, "\n")
-  server.Serve()
-  fmt.Print("Done with the secure server\n")
-}
-
-func RunServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory) {
-  server := NewGoServer()
-  ch := make(chan int)
-  go Simple(server.processor, transportFactory, protocolFactory, ch)
-  //go Secure(server.processor)
-  _ = <- ch
-}
diff --git a/tutorial/go/src/Makefile b/tutorial/go/src/Makefile
deleted file mode 100644
index 87acbca..0000000
--- a/tutorial/go/src/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include $(GOROOT)/src/Make.inc
-
-all: install
-
-TARG=TutorialServerClient
-
-DIRS=\
-
-GOFILES=\
-  CalculatorHandler.go\
-  GoClient.go\
-  GoServer.go\
-  main.go
-
--include ../Make.deps
-
-include $(GOROOT)/src/Make.cmd
-
diff --git a/tutorial/go/src/client.go b/tutorial/go/src/client.go
new file mode 100644
index 0000000..114de19
--- /dev/null
+++ b/tutorial/go/src/client.go
@@ -0,0 +1,85 @@
+package main
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+	"fmt"
+	"git.apache.org/thrift.git/lib/go/thrift"
+	"tutorial"
+)
+
+func handleClient(client *tutorial.CalculatorClient) (err error) {
+	client.Ping()
+	fmt.Println("ping()")
+
+	sum, _ := client.Add(1, 1)
+	fmt.Print("1+1=", sum, "\n")
+
+	work := tutorial.NewWork()
+	work.Op = tutorial.Operation_DIVIDE
+	work.Num1 = 1
+	work.Num2 = 0
+	quotient, ouch, err := client.Calculate(1, work)
+	if err != nil {
+		fmt.Println("Error during operation:", err)
+		return err
+	} else if ouch != nil {
+		fmt.Println("Invalid operation:", ouch)
+	} else {
+		fmt.Println("Whoa we can divide by 0 with new value:", quotient)
+	}
+
+	work.Op = tutorial.Operation_SUBTRACT
+	work.Num1 = 15
+	work.Num2 = 10
+	diff, ouch, err := client.Calculate(1, work)
+	if err != nil {
+		fmt.Println("Error during operation:", err)
+		return err
+	} else if ouch != nil {
+		fmt.Println("Invalid operation:", ouch)
+	} else {
+		fmt.Print("15-10=", diff, "\n")
+	}
+
+	log, err := client.GetStruct(1)
+	if err != nil {
+		fmt.Println("Unable to get struct:", err)
+		return err
+	} else {
+		fmt.Println("Check log:", log.Value)
+	}
+	return err
+}
+
+func runClient(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory) error {
+	var transport thrift.TTransport
+	transport, err := thrift.NewTSocket("localhost:9090")
+	if err != nil {
+		fmt.Println("Error opening socket:", err)
+		return err
+	}
+	transport = transportFactory.GetTransport(transport)
+	defer transport.Close()
+	if err := transport.Open(); err != nil {
+		return err
+	}
+	return handleClient(tutorial.NewCalculatorClientFactory(transport, protocolFactory))
+}
diff --git a/tutorial/go/src/handler.go b/tutorial/go/src/handler.go
new file mode 100644
index 0000000..3d4c18c
--- /dev/null
+++ b/tutorial/go/src/handler.go
@@ -0,0 +1,99 @@
+package main
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+	"fmt"
+	"shared"
+	"strconv"
+	"tutorial"
+)
+
+type CalculatorHandler struct {
+	log map[int]*shared.SharedStruct
+}
+
+func NewCalculatorHandler() *CalculatorHandler {
+	return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)}
+}
+
+func (p *CalculatorHandler) Ping() (err error) {
+	fmt.Print("ping()\n")
+	return nil
+}
+
+func (p *CalculatorHandler) Add(num1 int32, num2 int32) (retval17 int32, err error) {
+	fmt.Print("add(", num1, ",", num2, ")\n")
+	return num1 + num2, nil
+}
+
+func (p *CalculatorHandler) Calculate(logid int32, w *tutorial.Work) (val int32, ouch *tutorial.InvalidOperation, err error) {
+	fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
+	switch w.Op {
+	case tutorial.Operation_ADD:
+		val = w.Num1 + w.Num2
+		break
+	case tutorial.Operation_SUBTRACT:
+		val = w.Num1 - w.Num2
+		break
+	case tutorial.Operation_MULTIPLY:
+		val = w.Num1 * w.Num2
+		break
+	case tutorial.Operation_DIVIDE:
+		if w.Num2 == 0 {
+			ouch = tutorial.NewInvalidOperation()
+			ouch.What = int32(w.Op)
+			ouch.Why = "Cannot divide by 0"
+			return
+		}
+		val = w.Num1 / w.Num2
+		break
+	default:
+		ouch = tutorial.NewInvalidOperation()
+		ouch.What = int32(w.Op)
+		ouch.Why = "Unknown operation"
+		return
+	}
+	entry := shared.NewSharedStruct()
+	entry.Key = logid
+	entry.Value = strconv.Itoa(int(val))
+	k := int(logid)
+	/*
+	   oldvalue, exists := p.log[k]
+	   if exists {
+	     fmt.Print("Replacing ", oldvalue, " with ", entry, " for key ", k, "\n")
+	   } else {
+	     fmt.Print("Adding ", entry, " for key ", k, "\n")
+	   }
+	*/
+	p.log[k] = entry
+	return val, ouch, err
+}
+
+func (p *CalculatorHandler) GetStruct(key int32) (*shared.SharedStruct, error) {
+	fmt.Print("getStruct(", key, ")\n")
+	v, _ := p.log[int(key)]
+	return v, nil
+}
+
+func (p *CalculatorHandler) Zip() (err error) {
+	fmt.Print("zip()\n")
+	return nil
+}
diff --git a/tutorial/go/src/main.go b/tutorial/go/src/main.go
index 30b5d52..4b9576e 100644
--- a/tutorial/go/src/main.go
+++ b/tutorial/go/src/main.go
@@ -1,5 +1,4 @@
-package main;
-
+package main
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -20,67 +19,54 @@
  * under the License.
  */
 
-
 import (
-  "flag"
-  "fmt"
-  "os"
-  "thrift"
+	"flag"
+	"fmt"
+	"git.apache.org/thrift.git/lib/go/thrift"
+	"os"
 )
 
 func Usage() {
-  fmt.Fprint(os.Stderr, "Usage of ", os.Args[0], " <--server | --client>:\n")
-  flag.PrintDefaults()
-  fmt.Fprint(os.Stderr, "\n")
-  os.Exit(0)
+	fmt.Fprint(os.Stderr, "Usage of ", os.Args[0], ":\n")
+	flag.PrintDefaults()
+	fmt.Fprint(os.Stderr, "\n")
 }
 
 func main() {
-  flag.Usage = Usage
-  var client bool
-  var server bool
-  var protocol string
-  var framed bool
-  var useHttp bool
-  var help bool
-  
-  flag.BoolVar(&client, "client", false, "Run client")
-  flag.BoolVar(&server, "server", false, "Run server")
-  flag.StringVar(&protocol, "P", "binary", "Specify the protocol (binary, compact, simplejson)")
-  flag.BoolVar(&framed, "framed", false, "Use framed transport")
-  flag.BoolVar(&useHttp, "http", false, "Use http")
-  flag.BoolVar(&help, "help", false, "See usage string")
-  flag.Parse()
-  if help || (client && server) || !(client || server) {
-    fmt.Print("flag.NArg() == ", flag.NArg(), "\n")
-    flag.Usage()
-  }
-  var protocolFactory thrift.TProtocolFactory
-  switch protocol {
-  case "compact":
-    protocolFactory = thrift.NewTCompactProtocolFactory()
-  case "simplejson":
-    protocolFactory = thrift.NewTSimpleJSONProtocolFactory()
-  case "json":
-    protocolFactory = thrift.NewTJSONProtocolFactory()
-  case "binary", "":
-    protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
-  default:
-    fmt.Fprint(os.Stderr, "Invalid protocol specified", protocol, "\n")
-    Usage()
-    os.Exit(1)
-  }
-  transportFactory := thrift.NewTTransportFactory()
-  if framed {
-    transportFactory = thrift.NewTFramedTransportFactory(transportFactory)
-  }
-  
-  if(client) {
-    RunClient(transportFactory, protocolFactory)
-  } else if(server) {
-    RunServer(transportFactory, protocolFactory)
-  } else {
-    flag.Usage()
-  }
-  os.Exit(0)
+	flag.Usage = Usage
+	server := flag.Bool("server", false, "Run server")
+	protocol := flag.String("P", "binary", "Specify the protocol (binary, compact, simplejson)")
+	framed := flag.Bool("framed", false, "Use framed transport")
+
+	flag.Parse()
+
+	var protocolFactory thrift.TProtocolFactory
+	switch *protocol {
+	case "compact":
+		protocolFactory = thrift.NewTCompactProtocolFactory()
+	case "simplejson":
+		protocolFactory = thrift.NewTSimpleJSONProtocolFactory()
+	case "json":
+		protocolFactory = thrift.NewTJSONProtocolFactory()
+	case "binary", "":
+		protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
+	default:
+		fmt.Fprint(os.Stderr, "Invalid protocol specified", protocol, "\n")
+		Usage()
+		os.Exit(1)
+	}
+	transportFactory := thrift.NewTTransportFactory()
+	if *framed {
+		transportFactory = thrift.NewTFramedTransportFactory(transportFactory)
+	}
+
+	if *server {
+		if err := runServer(transportFactory, protocolFactory); err != nil {
+			fmt.Println("error running server:", err)
+		}
+	} else {
+		if err := runClient(transportFactory, protocolFactory); err != nil {
+			fmt.Println("error running client:", err)
+		}
+	}
 }
diff --git a/tutorial/go/src/server.go b/tutorial/go/src/server.go
new file mode 100644
index 0000000..929e223
--- /dev/null
+++ b/tutorial/go/src/server.go
@@ -0,0 +1,39 @@
+package main
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+	"fmt"
+	"git.apache.org/thrift.git/lib/go/thrift"
+	"tutorial"
+)
+
+func runServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory) error {
+	transport, err := thrift.NewTServerSocket("localhost:9090")
+	if err != nil {
+		return err
+	}
+	handler := NewCalculatorHandler()
+	processor := tutorial.NewCalculatorProcessor(handler)
+	server := thrift.NewTSimpleServer4(processor, transport, transportFactory, protocolFactory)
+
+	fmt.Println("Starting the simple server... on ", transport.Addr())
+	return server.Serve()
+}