Vlad Didenko | 20 May 2013 07:06
Gravatar

Applied reflection - an exercise.

As there is much talk /re generics, types, reflection and such in Go, I went through an exercise of making a very small library, which is in some sense is type-aware, yet is generic (as in common sense) in it's usage.


First and foremost, huge thanks to Ian Lance Taylor for the help during the Go office hours at Google I/O!!! Won't be able to do it without your help. Assignability of "chan interface{}" to "interface{}" was largely confusing initially.

The library's goal is to create a "fan out" channel facility with the following parameters (in no particular order):

1. All API (payload AND metadata) should be implemented in channels - no function calls. 

2. The library should be usable as a part of error routing in an application.

3. One in-flow channel, unlimited out-flow channels.

4. Buffering fully controlled by a user.

5. Zero-configuration routing - data automatically forwarded to those out-flow channels which can accept it, skipped for other channels.

6. The facility can be garbage-collected.

7. The facility should not block on mis-behaving consumers regardless of their buffer.

The repository for my "answer" for the exercise  is at https://github.com/didenko/pumps

Even if it was more of reflect package comprehension exercise, I have tried to produce the least code possible, as for production. There are a couple questions still lingering, which I can not yet answer. Before asking them, ehre is how the FanOut works:

* user specifies the in-flow buffer size in the factory function MakeFanOut(bufsize int)
* subscription happens by sending to Outs channel a channel to which forward values.
* post values by sending them into the Post channel.
* prevent future subscriptions by sending nil to the Outs channel
* shutdown the facility by sending nil to the Post channel

So here is the list of questions and concerns I have:

1. The two exposed channels accept nil as a control message. How does it correspond to common usage in Go?

2. Users' channels are closed on the facility shutdown. Given those supposed to be narrowly-typed (mostly) channels and not used anywhere else, seems to be a good idea. Or is it? Should I just leave users' channels alone?

3. Sending to user channels at dedicated goroutines is not guarded against non-reading consumers, potentially causing proliferation of idle goroutines. How would you suggest cleaning those up, if at all?

4. What else I miss?

As a general feeling about the reflection package,  I ended up with a much simpler code than expected, which is great. Dealing with "interface{}"-typed channels was not obvious - it would be awesome someone more knowledgeable than myself to expand on it in The Laws of Reflection post - which is a must read by the way.

Cheers!
Vlad

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Tobia | 19 May 2013 20:05
Picon

Variable declaration inside loop

Hi


I was playing around with closures and I noticed something curious.

First, the obvious behavior. This prints five 5, as expected*:

for i := 0; i < 5; i++ {
go func() {
time.Sleep(time.Millisecond)
fmt.Println(i)
}()
}
time.Sleep(2 * time.Millisecond)

http://play.golang.org/p/WlCESYk7UP

(* There is only one "i" variable in memory, the closure merely captures it. By the time the five goroutines stop sleeping, the single "i" already contains 5.)

This prints the numbers from 0 to 4 (in unpredictable order), again as expected:

for i := 0; i < 5; i++ {
go func(x int) {
time.Sleep(time.Millisecond)
fmt.Println(x)
}(i)
}
time.Sleep(2 * time.Millisecond)

http://play.golang.org/p/Hsf9yib9Cc

But the following surprised me. I expected it to "fail" (print five 5), instead it prints from 0 to 4:

for i := 0; i < 5; i++ {
x := i
go func() {
time.Sleep(time.Millisecond)
fmt.Println(x)
}()
}
time.Sleep(2 * time.Millisecond)

http://play.golang.org/p/CE6q9Bs9xi

Why does a single (lexical) variable declaration cause many memory allocations? Would it always do so, or is this a case of the compiler being "smart" and noticing that the variable is being captured? More importantly, is this specified in the reference docs? Can it be relied upon?

-Tobia

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
ajstarks | 19 May 2013 23:13
Picon
Gravatar

Installing Debian and Go 1.1 on the Beaglebone Black

A recipe in twelve steps:  https://gist.github.com/ajstarks/093581ac1fbc355f8402



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
minux | 19 May 2013 19:05
Picon

Darwin/ARM (a.k.a. iOS) port of Go 1.1 tarball available!

Hi Gophers,


    I just built Darwin/ARM port [1] of Go 1.1 and uploaded to bitbucket:
It should support all ARMv7 iDevices with at least 256MiB of memory
(for example, all iPads).

    To use it, just follow the normal binary install instructions at

# as root
rm -r /usr/local/go
tar -C /usr/local -xzf go1.1.darwin-arm.tar.gz

    I sincerely hope that iDevices owners will enjoy this and please report
bugs to the issue tracker at https://bitbucket.org/minux/goios/issues/new.
Btw, it still doesn't support cgo, and I'm working on cmd/5l support at the
moment (it's in branch ios-cgo).

[1] http://bitbucket.org/minux/goios, branch ios for development version,
and branch ios-go1.1 for Go 1.1.

Best regards,
minux

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Brendan Tracey | 19 May 2013 18:57
Picon

Thoughts on fireside chat

If any of you haven't seen, the fireside chat is up https://www.youtube.com/watch?v=p9VUCp98ay4 . Here are some thoughts I had while watching it


It was commented that profiling tools are very good, which helped bring speed increases: Except for OSX, at least the last time I tried. Is there a chance that this will be fixed anytime soon?

Dependency management: I know this issue has been making the rounds for a while, and I agree with the Go team that people should be aware what they're doing when they use go get. That said, I know what I'm getting into when I download "some random person's github", but I'm not sure what the best practices are with it. A lot of the code I write is for my own uses, as opposed to for production, but at the same time, sometimes I do like to give code to collaborators. Not having a version control specification has positives, one of which is that it makes it easy to gain features and performance from the github package as it is worked on. On the other hand, if the github writer isn't as particular about backward compatibility as I thought, the github code might change in a backward incompatible way. If I'm not continually updating my local copy, I might not realize this change. I am hoping to get advice on best practices in dealing with these issues.

What would you take out?
Ampersand a struct: This feels so natural to me. What else would you do?
The number of ways to declare a variable is too high: What would you take out? I can see that new and struct literals are highly overlapping.
Colon equals for overwrite: Totally agreed. I avoid overwriting variable names. However, could someone point me to a use case where it's well done? I'd be interested in seeing the positive use cases.
Named result parameters: Please keep these in. They are really useful in remembering the order of outputs when you're returning several things. func([]input) (float64, float64) is less clear than func([]input) (sum float64, prod float64)
Variable reused in a for loop being confusing, especially for closures: I'm not sure what this means. Could you give an example of a proper and improper closure with it?

Facilitating concurrency across network: I agree, though I personally would like to see a focus on cluster / supercomputer stuff (I realize that I'm in the minority with that), though I imagine there is significant overlap between the two . It would be awesome if it could be nearly as easy as shared memory. Go circuit kind of looks like it, though I haven't had a chance to really play with it to see if that's true.

Lots of speedups from developments to the runtime and scheduler, and a lot more to come: What kinds of things should we expect to see? Any idea on how much more performance that will bring? Another blanket 40%? Just improvements for multi-core? As I begin to push Go, one of the questions I will get is about the computation speed, and in my world, that's mostly number crunching. Will I have to say "It's not quite as fast as C/C++, but it's way better for safety, compile time, ease of coding, GC, etc.", or will I be able to say "It's as fast as C++ and it's way better, etc."

Source transformation tools: There are some specific packages that involve re-writting source code would be very useful, and were such tools to exist well in Go it would make selling the language easier for me. If I wanted to learn how to write these packages, is reading the go fmt source the best way to learn how to do source transformation, or are there better ways?

Writing the go compiler/runtime in go: A good reason is that all of us here write Go. If the compiler and runtime are written in Go it becomes a lot easier for the community to read and understand what's going on. It would also make it easier for the community to submit patches and improvements (not sure how much that would actually happen). 

Our go compiler is better than the C compiler: Did that mean that there is a go compiler written in Go that the team has, or just that compiling Go code is better than compiling C code?

Thanks for the discussion time.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
clkimcomputerorg | 19 May 2013 17:56
Picon

how to "drop" a request using httputil.ReverseProxy type

Trying to implement a simple reverse proxy to filter out requests with certain xff header values, or to forward it on to the intended server after updating the request header.

Was able to take advantage of the httputil.ReverseProxy type to update request header that has certain xff header values -- after reading a blog that showed the coding idiom for overriding the function defined in ReverseProxy.Director, along the lines of:

shrp := httputil.NewSingleHostReverseProxy(url)
director := shrp.Director
shrp.Director = func(req *http.Request) {
   [do processing of req to check xff header and update other header]
   director(req)
}

The overriden ReverseProxy.Director function is able to test the xff header value in the request (and then to update other header as appropriate). But when this overriden ReverseProxy.Director function sees a request that should be filtered out, I've not been able to figure out how to do filtering from within the function. Filtering here could be either causing the request to be silently dropped/ignored, or to return a 404 status. Is it architecturally possible using the httputil library, or would I need another approach? (A brute force way to illustrate the idea is to set the request to nil within the overriden ReverseProxy.Director function, which 'works' but, obviously, causes Go to panic...)

Thanks.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Jan Mercl | 19 May 2013 18:20
Picon

[ANN] bufs

Package bufs[1] implements a simple buffer cache. It's perhaps also an
example of the power of profiling.

  [1]: http://godoc.org/github.com/cznic/bufs

-j

--

-- 
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@...
For more options, visit https://groups.google.com/groups/opt_out.

Favicon

C-sources with Go 1.1 under certain conditions not compiled

Dear everyone,

after installing Go 1.1 the attempt to compile with "go install" the part of a package, that is appended,
on a machine with an AMD FX(tm)-6300 Six-Core Processor with OpenSUSE 12.3 in 32-bit-mode
with gcc (SUSE Linux) 4.7.2 20130108 [gcc-4_7-branch revision 195012] fails with the following result:

  /usr/local/go/pkg/tool/linux_386/8c: unknown flag -FVw

With 1.0.3 everything worked, and now, with 1.1, things also work on several other machines
(also openSUSE 12.3, same status of actualization, 32-bit, same gcc).

As far as I have understood some doc, the flags should be "-F -V -w" - but how do I achieve that?
Or do I miss something else?

Greetings, Christian

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Attachment (framebuffer.go): application/octet-stream, 1476 bytes
Péter Szilágyi | 19 May 2013 13:18
Picon
Gravatar

Google IO - Advanced Concurrency (nitpicking / philosophical question)

Hi,

  The following will be nitpicking, but still, I'm curious :)

  Just for the reference if somebody didn't see it I'm talking about this video, in particular, this code segment. The goal here was to make sure that all go-routines attached to an entity terminate before Close finishes, a concept that can be nicely verified by doing a forced stack unwind (i.e. panic) after close.

  Whilst this is nice indeed, there's one tiny race condition :P, after you send the error/nil into the errc channel, both threads are allowed to proceed. One racing to terminate, the other to dump the stack, thus sometimes you'll get a clean stack and sometimes the "killed" thread will still linger not having been scheduled.

  So, is there a way to really wait till all "requested" threads really terminate? I'm guessing not, but it's a nice philosophical question :)

Cheers,
  Peter

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Matt LeVeck | 19 May 2013 07:17
Picon
Gravatar

Confused about Advanced Concurrency Patterns Talk example

Sorry, I'd paste the code, but I haven't found a link.  I'm referring to the first example in this Google I/O 2013 talk Advanced Concurrency Patterns:

http://www.youtube.com/watch?v=QDDwwePbDtw

It's not clear to me why ping always seems to grab the Ball pointer first.  It's actually not clear to me why ping and pong can't both simultaneously grab and update the Ball's counter, or regrab the ball after they re-send it down the pipe that they are listening on.

Clearly, my understanding of channels and how they work is pretty lacking.  Can someone help me out, and explain?
Thanks,
Matt

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 
ajstarks | 19 May 2013 03:52
Picon
Gravatar

[ANN] Visualizing Go Benchmarks

Benchviz [1] is a tool that makes visualizations from the output of $GOROOT/misc/benchcmp.

The tool is designed to clearly show speedups and regressions, and their trends.

Here are the benchviz options:

Usage of benchviz:
  -bh=20: bar height
  -col=false: show data in a single column
  -h=768: width
  -left=100: left margin
  -line=false: show lines between entries
  -rcolor="red": regression color
  -scolor="green": speedup color
  -style="bar": show barchart style
  -title="": title
  -top=50: top
  -vp=512: visualization point
  -vw=300: visual area width
  -w=1024: height

and sample output [2]

Typical usage:

benchcmp old new | benchviz > bench.svg  # generate the visualization. Open bench.svg in your browser

You can install it like this:

go get github.com/ajstarks/svgo/benchviz
go install github.com/ajstarks/svgo/benchviz


[1] http://mindchunk.blogspot.com/2013/05/visualizing-go-benchmarks-with-benchviz.html
[2] http://www.flickr.com/photos/ajstarks/8752200224/

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Gmane