Category Archives: golang

Interview with Ken Thompson

(this comes from a DrDobbs’s post May 18, 2011 – the article disappeared from the site so I’m just saving it here)

The creator of UNIX discusses writing UNIX, the Go language, and collaborating with Dennis Ritchie

The Japan Prize, one of the highest honors awarded for outstanding contribution to science and technology, was awarded jointly this year to Ken Thompson and Dennis Ritchie for the creation of UNIX. The prize is normally given to the recipients at a lavish banquet in Tokyo attended by the emperor. However, due to the April earthquake and tsunami, the prizes this year were distributed at the honorees’ place of work. I was able to attend the ceremony for Ken Thompson, held at Google headquarters, where he currently works. After the ceremony, he consented to this exclusive interview.


DDJ: Congratulations on winning this prize.

KT: Thanks.

Developing UNIX

DDJ: You’ve received a lot of awards over the years for UNIX. At what point in UNIX’s development did it become clear it was going to be something much bigger than you’d anticipated?

KT: The actual magnitute, that no one could have guessed. I gather it’s still growing now. I thought it would be useful to essentially anybody like me because it was not built for someone else or some third party. That was a perjorative term then. It was written for Dennis and me and our group to do its work. And I think it would have been useful to anybody who did the kind of work that we did. And therefore, I always thought it was something really good that was going to take off.

Especially the language [C]. The language grew up with one of the rewritings of the system and, as such, it became perfect for writing systems. We would change it daily as we ran into trouble building UNIX out of the language and we’d modify it for our needs.

DDJ: A symbiosis of sorts…

KT: Yeah. It became the perfect language for what it was designed to do. I always thought the language and the system were widely applicable.

DDJ: In the presentation today, it mentioned that UNIX was open source. Was UNIX open source from the beginning?

KT: Well there was no such term as “open source” then.

DDJ: I was under the impression that UNIX really became open source with the Berkeley distribution.

KT: No, we charged $100, which was essentially the reproduction cost of the tape, and then send it out. And we distributed, oh, probably close to 100 copies to universities and others.

Go Language

DDJ: Skipping several decades of work, let’s speak about Go. I was just at the Google I/O Conference, where it was announced that Go will be supported on the Google App Engine. Does that presage a wider adoption of Go within Google, or is it still experimental?

KT: It’s expanding every day and not being forced down anybody’s throat. It’s hard to adopt it to a project inside of Google because of the learning curve. It’s brand new and there aren’t good manuals for it, except what’s on the Web. And then, of course, its label of being experimental, so people are a little afraid. In spite of that, it’s growing very fast inside of Google.

DDJ: In the presentation before the awarding of the Japan Prize today, you were quoted on the distinction between reasearch and development. [The former, Thompson stated, was directionless, whereas development had a specific goal in mind.] So in that context, is Go experimental?

KT: Yes. When the three of us [Thompson, Rob Pike, and Robert Griesemer] got started, it was pure research. The three of us got together and decided that we hated C++. [laughter]

DDJ: I think there’d be a lot of people who are with you on that.

KT: It’s too complex. And going back, if we’d thought of it, we’d have done an object-oriented version of C back in the old days.

DDJ: You’re saying you would have?

KT: Yes, but we were not evangelists of object orientation. [Returning to Go,] we started off with the idea that all three of us had to be talked into every feature in the language, so there was no extraneous garbage put into the language for any reason.

DDJ: It’s a lean language, indeed.

Collaboration with Dennis Ritchie

DDJ: Returning to UNIX, for a moment, when you and Dennis worked together, how did that collaboration operate? Were you working side by side?

KT: I did the first of two or three versions of UNIX all alone. And Dennis became an evangelist. Then there was a rewrite in a higher-level language that would come to be called C. He worked mostly on the language and on the I/O system, and I worked on all the rest of the operating system. That was for the PDP-11, which was serendipitous, because that was the computer that took over the academic community.

DDJ: Right.

KT: We collaborated every day. There was a lunch that we went to. And we’d talk over lunch. Then, at night, we each worked from our separate homes but we were in constant communication. In those days, we had mail and writ (pronounced ‘write’), and writ would pop up on your screen and say there was a message from so-and-so.

DDJ: So, IM essentially.

KT: Yes, IM. There was no doubt about that! And we discussed things from home with writ. We worked very well together and didn’t collaborate a lot except to decide who was going to do what. Then we’d run and very independently do separate things. Rarely did we ever work on the same thing.

DDJ: Was there any concept of looking at each other’s code or doing code reviews?

KT: [Shaking head] We were all pretty good coders.

DDJ: I suspect you probably were! [Laughter]

SCM

DDJ: Did you use any kind of source code management product when working together?

KT: No, those products really came later; after UNIX. We had something like it, which we called “the code motel” because you could check your code in but you couldn’t check it out! So, really, no we didn’t.

DDJ: I bet you use SCM today in your work on Go.

KT: Oh, yes, Google makes us do that!

Golang ElasticSearch for beginners

(You may not be familiar with what elasticsearch is : for a good introduction checkout this post from Igor Kopanev)
Extracting data from ElasticSearch in golang is not a simple task. First of all you might not be the one who wrote data into it so these are some commands to find out how is data structured in your ES server :

List all your indexes

$ curl https://<your-server>/_aliases?pretty=true
{  
  "billingdata" : {
    "aliases" : { }
  },
  "checkpoints" : {
    "aliases" : { }
  }
}

Your indexes data structures can be queried with :

curl https://<your-server>/<index_name> 


Now that I had an idea of how data was structured I started looking at the ES official library ( https://github.com/elastic/go-elasticsearch/ ) to find out that it is probably not used that much directly. This a code example to execute a query :

  // Build the request body.
  var buf bytes.Buffer
  query := map[string]interface{}{
    "query": map[string]interface{}{
      "match": map[string]interface{}{
        "title": "test",
      },
    },
  }
  if err := json.NewEncoder(&buf).Encode(query); err != nil {
    log.Fatalf("Error encoding query: %s", err)
  }
  // Perform the search request.
  res, err = es.Search(
    es.Search.WithContext(context.Background()),
    es.Search.WithIndex("billingdata"),
    es.Search.WithBody(&buf),
    es.Search.WithTrackTotalHits(true),
    es.Search.WithPretty(),
  )

Then (God bless Oliver Eilhard) I ray of light came in through my window and I found this package : https://godoc.org/github.com/olivere/elastic that makes everything much more simple :

	searchResult, err := es6.Search().
		Index("billingdata").
		// Query(timerangeQuery). // if you need to filter
		Pretty(true).
		Do(context.Background()) // execute

Much better. If you need a time range query :

// sdate,edate are time.Time	
timerangeQuery := elastic.NewBoolQuery().
		Filter(elastic.NewRangeQuery("@timestamp").
		From(sdate).
		To(edate))

Or maybe you need to query by time range and field value :

companyQuery = elastic.NewTermQuery("company_id", CompanyId)
// combine queries :
CombinedQuery = elastic.NewBoolQuery()
CombinedQuery = CombinedQuery.Must(timerangeQuery).Must(companyQuery)

// now search using Query(CombinedQuery)

Setting up your ES Client is pretty easy :

	// Create a custom HTTP client to setup timeouts and TLS config
	// esHTTPClient := &http.Client{
	// 	Timeout: time.Second * 10,
	// 	Transport: &http.Transport{
	// 		Dial: (&net.Dialer{
	// 			Timeout: 5 * time.Second,
	// 		}).Dial,
	// 		TLSHandshakeTimeout: 5 * time.Second,
	// 		TLSClientConfig: &tls.Config{
	// 			InsecureSkipVerify: true,
	// 		},
	// 	},
	// }

	// Create a client
	client, err := elastic.NewClient(
		// elastic.SetHttpClient(esHTTPClient),
		elastic.SetSniff(false),
		elastic.SetURL("http://localhost:9200"))

You can also aggregate data easily, sum, avergage. I’ll come up with more examples as soon as I have some working code.

Val Sassina

October reading list

“simplicity, or the art of maximizing the work not done” : I really like this sentence, from Marco Cecconi https://sklivvz.com/posts/consider-using-simple-models-instead. Kind of summarizes my thoughts around simplicity in software, removing accidental complexity, over engineering code, get rid of complex and slow learning curve tools and languages. Thanks to Orfware for reference to Marco.

CORS : https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Golang elasticsearch API : kudos to Oliver Eilhard for his package! https://godoc.org/github.com/olivere/elastic

September reading list

Nice article on gRPC in a js client, Envoy and go gRPC server https://medium.com/swlh/building-a-realtime-dashboard-with-reactjs-go-grpc-and-envoy-7be155dfabfb

https://blog.codinghorror.com/tending-your-software-garden/

https://blog.codinghorror.com/bridges-software-engineering-and-god/

https://signalvnoise.com/posts/591-brainstorm-the-software-garden

https://blog.codinghorror.com/the-big-ball-of-mud-and-other-architectural-disasters/

Benchmarking golang code

Let’s say that you want to know if EncodeToString is faster than fmt.Sprintf : you will need to compare the speed of this method

func Md5Encode(str string) string {
	md5HashInBytes := md5.Sum([]byte(str))
	md5HashInString := hex.EncodeToString(md5HashInBytes[:])
	return md5HashInString
}

with this other one

func Md5EncodeFmt(str string) string {
	md5HashInBytes := md5.Sum([]byte(str))
	md5HashInString := fmt.Sprintf("%x", md5HashInBytes)
	return md5HashInString
}

Go provides benchmarking features in the testing package which is pretty usefull :

func BenchmarkMd5EncodeFmt(b *testing.B) {
	// run the md5Encode function b.N times
	for n := 0; n < b.N; n++ {
		Md5EncodeFmt("aldfhasdl la fasdfeo8ekldjh asdkj fh lksdjfhwoieuxnroiAUN;laiDJ;ANIfub;OEIRBUF;OEfuN;ALFJ;AL")
	}
}

func BenchmarkMd5Encode(b *testing.B) {
	// run the md5Encode function b.N times
	for n := 0; n < b.N; n++ {
		Md5Encode("aldfhasdl la fasdfeo8ekldjh asdkj fh lksdjfhwoieuxnroiAUN;laiDJ;ANIfub;OEIRBUF;OEfuN;ALFJ;AL")
	}
}

Run

$ go test -bench=.
goos: linux
goarch: amd64
BenchmarkMd5EncodeFmt-8   	 1894791	       625 ns/op
BenchmarkMd5Encode-8      	 3068509	       363 ns/op
PASS
ok  	_/home/paul/LazyInit/bench	3.342s

Run 3 times the benchmarks :

$ go test -count 3 -bench=. 
goos: linux
goarch: amd64
BenchmarkMd5EncodeFmt-8   	 1882105	       627 ns/op
BenchmarkMd5EncodeFmt-8   	 1918942	       624 ns/op
BenchmarkMd5EncodeFmt-8   	 1902894	       625 ns/op
BenchmarkMd5Encode-8      	 3139585	       386 ns/op
BenchmarkMd5Encode-8      	 2937154	       397 ns/op
BenchmarkMd5Encode-8      	 3009801	       380 ns/op
PASS
ok  	_/home/paul/LazyInit/bench	10.217s

EncodeToString() makes your method almost twice faster !

In the case you need to isolate the code that will be measured from some init/fixture code you can use ResetTimer() and StopTimer() to accurately isolate what you want to measure :

func BenchmarkMd5EncodeFmt(b *testing.B) {
	// Some init code
	initRandomBenchStrings()
	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		Md5EncodeFmt(getRandomstrings())
	}
	b.StopTimer()
	// some final code
}

If the function you’re measuring is very slow you might want to increase to maximum time of excecution of the benchmark (default is 1 s) with -benchtime=20s

Recap

  • without any benchmarks : go test .
  • with benchmarks (time) : go test -bench .
  • with benchmarks (time and memory) : go test -bench . -benchmem

The argument following -bench is a regular expression. All benchmark functions whose names match are executed. The . in the previous examples isn’t the current directory but a pattern matching all tests. To run a specific benchmark, use the regexp : -bench Suite (means everything containing Suite).

(thanks to https://github.com/samonzeweb/profilinggo )