Theme:
Golang as a Java Dev
My recent experience's with golang for creating small services
as a replacement for existing Java services at Semantico.
<-
George 'Malcolm' MacRorie
A little background info
  • "Java Web Developer" for Semantico
  • Mostly develop in XSLT and XQuery
  • Have recently been piloting a new role as a maintenance developer
Looking at Golang
"It's a fast, statically typed, compiled language that feels like a dynamically typed, 
interpreted language."

"Its concurrency mechanisms make it easy to write programs that 

get the most out of multicore and networked machines, 

while its novel type system enables flexible and modular program construction."

Similarities between Golang and Java
Main Method (+ curly brackets)
public static void main(string[] args) {}
func main() {}
Objects + Class (Struct) Definitions
public class Main {}
type Main struct {}
Interfaces
public interface Service {}
type Service interface {}
For (+ each) loops
for (int i=0; i < 10; i++) {}
for i := 0; i < 10; i++ {}
for (int i:collection) {}
for _, v := range collection {}
new Main();
new(Main)
Differences between Golang and Java
Accessors
public, private, protected
Exported(), notExported()
Hierarchical Inheritance 
public Foo extends Bar {}
Ownership
Class Foo {
  void Bar() {}
}

type Foo struct{}
func (f *Foo) Bar() {}

Where you place your types (+ argument sugar)
public String foo (int bar) {}
func foo(bar int) string {}
func foo(a, b int) string {}
func foo(bar int) (string, error) {}
func foo(bar int) (s string) {}
While Loops
while(true) {}
N/A
for {}
A glimpse at our architecture
/
Which backend service?
Service A
Service B
Webapp
What we wanted...
New Webapp
Request
We needed a service!
/
Which backend service?
Service A
Service B
Webapp
New Service
or
The solution ...
New Webapp
Request
  • We're Java Developers
  • We have a similar implementation packaged into all of our sites
  • We have the infrastructure in place to deploy java services
  • It compiles easily and quickly into a command line tool
  • It's standard libraries come with lots of webby goodness
  • It mixes interesting programming paradigms (Functional + OO)
  • Lot's of developers are talking about it! (and we want in)
Golang http libs
http.Handle("/foo", fooHandler)

http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})

log.Fatal(http.ListenAndServe(":8080", nil))
s := &http.Server{
	Addr:           ":8080",
	Handler:        myHandler,
	ReadTimeout:    10 * time.Second,
	WriteTimeout:   10 * time.Second,
	MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;



public class Main {


    public static void main(String[] args) {

        ExecutorService executor = Executors.newFixedThreadPool(2);

        int[] vals = new int[]{7, 2, 8, -9, 4, 0};


        int[] first = Arrays.copyOfRange(vals, 0, (int)Math.floor(vals.length/2));

        int[] second = Arrays.copyOfRange(vals, (int)Math.floor(vals.length/2), vals.length);


        ArrayList<Integer> results = new ArrayList<Integer>(2);


        executor.execute(new Sum(first, results));

        executor.execute(new Sum(second, results));


        executor.shutdown();        

        try {

            if (executor.awaitTermination(2l, TimeUnit.MINUTES)) {

                System.out.println(String.format("%d, %d, %d", new Integer(results.get(0)), new Integer(results.get(1)), new Integer(results.get(0) + results.get(1))));

            }

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

class Sum implements Runnable {

    

    final int[] toSum;

    final List<Integer> results;

    

    public Sum(int[] toSum, List<Integer> results) {

        this.toSum = toSum;

        this.results = results;

    }

    

    @Override

    public void run() {

        int accum = 0;

        for(int i:toSum) {

            accum += i;

        }

        results.add(new Integer(accum));

    }

}

Java Concurrency Example
package main

import "fmt"

func sum(a []int, c chan int) {
    sum := 0
    for _, v := range a {
        sum += v
    }
    c <- sum // send sum to c
}

func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c // receive from c

    fmt.Println(x, y, x+y)
}
Summing the contents of an int array (slice) using goroutines
Quick Benchmark
time javac Main.java
javac Main.java  1.12s user 0.07s system 168% cpu 0.706 total
time go build
go build  0.17s user 0.08s system 61% cpu 0.409 total
time java Main
Java Main  0.10s user 0.03s system 88% cpu 0.150 total
time summer
Without setting GOMAXPROCS
summer  0.00s user 0.00s system 41% cpu 0.014 total
Setting GOMAXPROCS to 2
summer  0.00s user 0.00s system 80% cpu 0.007 total
Current Location Service Java Implementation
14 class files
471 lines of code
We have 2 implementations!
Cassandra Implementation
10 class files
424 lines of code
Postgres Implementation
7 go files
298 lines of code
The Golang implementation
  • Works with both Cassandra
and Postgres location providers.

  • Has scope to work with other 
provider services.

  • Configurable using a YAML file.

  • Implements a http handler to serve
Yammer style metrics, useful for our
load balancers.

  • Operates using a polling service, 
which fails gracefully by providing
either a default or the last successful 
request to the service provider.
Out of the box solutions
Command line flag argument parsing
Http reverse proxy handling
Channel based time libraries
Fantastic 3rd party libraries
Cassandra
Postgres
Summary
  • 3 days to develop
  • Fun to write
  • Easy to understand compile time errors
  • I had to manage my pointers
  • I've run out of projects to write in Golang
Upsides
Downsides
Extra Stuff...
Want to learn some go?
Need some more convincing?
Twitter: @GeorgeMacr
Github: GeorgeMac