Throttling Go routines

Source: https://stackoverflow.com/questions/15715605/multiple-goroutines-listening-on-one-channel#15721380

Yes, it’s complicated, But there are a couple of rules of thumb that should make things feel much more straightforward.

  • prefer using formal arguments for the channels you pass to go-routines instead of accessing channels in global scope. You can get more compiler checking this way, and better modularity too.
  • avoid both reading and writing on the same channel in a particular go-routine (including the ‘main’ one). Otherwise, deadlock is a much greater risk.

Here’s an alternative version of your program, applying these two guidelines. This case demonstrates many writers & one reader on a channel:

c := make(chan string)

for i := 1; i <= 5; i++ {
    go func(i int, co chan<- string) {
        for j := 1; j <= 5; j++ {
            co <- fmt.Sprintf("hi from %d.%d", i, j)
        }
    }(i, c)
}

for i := 1; i <= 25; i++ {
    fmt.Println(<-c)
}

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

It creates the five go-routines writing to a single channel, each one writing five times. The main go-routine reads all twenty five messages – you may notice that the order they appear in is often not sequential (i.e. the concurrency is evident).

This example demonstrates a feature of Go channels: it is possible to have multiple writers sharing one channel; Go will interleave the messages automatically.

The same applies for one writer and multiple readers on one channel, as seen in the second example here:

c := make(chan int)
var w sync.WaitGroup
w.Add(5)

for i := 1; i <= 5; i++ {
    go func(i int, ci <-chan int) {
        j := 1
        for v := range ci {
            time.Sleep(time.Millisecond)
            fmt.Printf("%d.%d got %d\n", i, j, v)
            j += 1
        }
        w.Done()
    }(i, c)
}

for i := 1; i <= 25; i++ {
    c <- i
}
close(c)
w.Wait()

This second example includes a wait imposed on the main goroutine, which would otherwise exit promptly and cause the other five goroutines to be terminated early (thanks to olov for this correction).

In both examples, no buffering was needed. It is generally a good principle to view buffering as a performance enhancer only. If your program does not deadlock without buffers, it won’t deadlock with buffers either (but the converse is not always true). So, as another rule of thumb, start without buffering then add it later as needed.

===
Another explanation: https://nanxiao.me/en/use-sync-waitgroup-in-golang/

Go routines exec throttling: https://stackoverflow.com/questions/18405023/how-would-you-define-a-pool-of-goroutines-to-be-executed-at-once-in-golang

Sends and Receives are blocking by default: https://golangbot.com/channels/

Golang – What is channel buffer size?

Source: https://stackoverflow.com/questions/11943841/golang-what-is-channel-buffer-size

The buffer size is the number of elements that can be sent to the channel without the send blocking. By default, a channel has a buffer size of 0 (you get this with make(chan int)). This means that every single send will block until another goroutine receives from the channel. A channel of buffer size 1 can hold 1 element until sending blocks, so you’d get

c := make(chan int, 1)
c <- 1 // doesn't block
c <- 2 // blocks until another goroutine receives from the channel

Variable captured by func literal

Source: https://stackoverflow.com/questions/40326723/go-vet-range-variable-captured-by-func-literal-when-using-go-routine-inside-of-f#40326812

it’s a common mistake for new comers in Go, and yes the var currentProcess changes for each loop, so your goroutines will use the last process in the slice l.processes, all you have to do is pass the variable as a parameter to the anonymous function, like this:

func (l *Loader) StartAsynchronous() []LoaderProcess {

    for ix := range l.processes {

        go func(currentProcess *LoaderProcess) {

            cmd := exec.Command(currentProcess.Command, currentProcess.Arguments...)
            log.LogMessage("Asynchronously executing LoaderProcess: %+v", currentProcess)

            output, err := cmd.CombinedOutput()
            if err != nil {
                log.LogMessage("LoaderProcess exited with error status: %+v\n %v", currentProcess, err.Error())
            } else {
                log.LogMessage("LoaderProcess exited successfully: %+v", currentProcess)
                currentProcess.Log.LogMessage(string(output))
            }

            time.Sleep(time.Second * TIME_BETWEEN_SUCCESSIVE_ITERATIONS)

        }(&l.processes[ix]) // passing the current process using index

    }

    return l.processes
}

Another example : http://oyvindsk.com/writing/common-golang-mistakes-1

Go features

Source: http://qr.ae/TUpzWs

  1. In Go a type definition is neither pointer nor value, it’s just a type.
  2. Go doesn’t have classes
  3. Go doesn’t have inheritance, it has interfaces for polymorphism and some sugar for automatic delegation (“struct embedding”).
  4. Simple build system. Want to compile for linux arm from your MacBook? GOOS=linux GOARCH=arm go build.
  5. Implicit interfaces.
  6. Great standard library. Go’s standard library covers JSON, Templating, HTTP (production grade), testing, benchmarking, etc, etc.
  7. Standard formatting.
  8. Documentation for free.

Deploying Go apps to Heroku

1. Make sure the app is running fine locally.

2. Install dep, with the project in $GOPATH/src/<user>/<project>, run dep init inside the project directory, dep ensure to generate the vendor files

3. Download and install Heroku CLI, run heroku login to login and heroku create to create the app, then heroku buildpacks:set heroku/go to set the build environment (ref: https://devcenter.heroku.com/articles/buildpacks)

4. Edit Gopkg.toml to include metadata.heroku section

[meatadata.heroku]
root-package="github.com/<user>/<project>"
go-version = "1.0"
build = [.]
ensure="false"

5. Configure semaphoreci.com to load the git repo from Github.com and deploy to Heroku, all continuous build, test and integration.

Web Assembly and Go: A look to the future

Source: https://brianketelsen.com/web-assembly-and-go-a-look-to-the-future/

When I look at modern web development I shudder; the ecosystem is so confusing for someone who has been out of touch as long as I have. Node, webpack, yarn, npm, frameworks, UMD, AMD, arghhh!

When Web Assembly(wasm) support landed in Go recently, I knew that the time was ripe for some experimentation.

I’ve decided that Web Assembly is the future of web development. It enables any language that can compile to wasm to be a “frontend” language.