canonical pattern for transactional library state manipulation In golang I am finding that there is a definite pressure in the language itself and built-in libraries to do things in a canonical way.  Please can someone critically look at these two ways I am considering using to provide transactional synchronisation of state manipulation within a library and provide me with some feedback.

All state manipulation functions of the library (i.e. all but a couple helper functions) would use this pattern and there would be over a dozen non-trivial functions that require transactional operation.  Method 1 is what I would usually have done in C# but the official golang blog almost seems to be implying this is an anti-pattern.

Method 1 - C# lock pattern https://play.golang.org/p/XS14fM_XUg

gobyexample.com/mutexes

package main

import (
    "fmt"
    "sync"
)

type ILibraryState interface {
    DoSomething(arg int) error
}

type LibraryState struct {
    lock *sync.Mutex
    // Some private state
}

func (l *LibraryState) DoSomething(arg int) error {
    // Do some arg check

    // Transactional synchronisation
    l.lock.Lock()
    defer l.lock.Unlock()

    // Do something
    fmt.Println("Hello, playground")
    return nil;
}

func NewLibrary() ILibraryState {
    lib := LibraryState{}
    lib.lock = &amp;sync.Mutex{}
    return &amp;lib
}

func main() {
    l := NewLibrary()
    l.DoSomething(5)
}


Method 2 - Hidden goroutine and single command queue https://play.golang.org/p/3vWQJDswJm


http://gobyexample.com/stateful-goroutines 
http://blog.golang.org/share-memory-by-communicating
http://blog.golang.org/advanced-go-concurrency-patterns




package main

import (
    "fmt"
)

type ILibraryState interface {
    DoSomething(arg int) error
}

type LibraryState struct {
    command  chan (interface{})
    response chan (interface{})
    // Some private state
}

type commandDoSomething struct {
    arg int
}

func (l *LibraryState) DoSomething(arg int) error {
    // Do some arg check

    // Perform operation transactionally
    l.command &lt;- commandDoSomething{arg}
    res := &lt;-l.response
    if res == nil {
        return nil
    }
    return res.(error)
}

func (l *LibraryState) reallyDoSomething(arg int) {
    // Do something
    fmt.Println("Hello, playground")
    var err error = nil
    l.response &lt;- err
}

func (l *LibraryState) processCommands() {
    for {
        switch c := (&lt;-l.command).(type) {

        case commandDoSomething:
            l.reallyDoSomething(c.arg)
        }
    }
}

func NewLibrary() ILibraryState {
    lib := LibraryState{}
    lib.command = make(chan (interface{}))
    lib.response = make(chan (interface{}))
    go lib.processCommands()
    return &amp;lib
}

func main() {
    l := NewLibrary()
    l.DoSomething(5)
}
Go does have a strong opinion on the use of mutexes vs. channels. In fact, the sync package states: "Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication." (See https://golang.org/pkg/sync/ )

This opinion clearly implies your first implementation is suboptimal. I agree, so I'm not going to even review that implementation.

The second implementation is more intriguing, it uses channels, but it's got issues.... and it's not a "canonical" example of what I would expect with a "communication" implementation for concurrency in Go.

The "Stateful" go-routine is one which only that single go-routine accesses, or modifies the state. All interaction with the state is done by communicating with that routine, and communication happens through channels.

You have one channel to communicate the request for accessing the state, and another for returning the response. This is a problem... The request channel command is OK, but the response channel is broken. If you have multiple concurrent commands issued, you won't be able to send the right response to the right command, and things will get mixed up.

The solution to this is to dedicate a channel for each command to get the responses on. Add the channel to the commandDoSomething struct, so that your code looks something like:

func (l *LibraryState) DoSomething(arg int) error {

    // dedicated response channel for communication (of error type, not interface{})
    resp := make(chan error, 1)

    // Perform operation transactionally
    l.command &lt;- commandDoSomething{arg, resp}
    res := &lt;-response
    return res
}


Now your state handler would look like:

func (l *LibraryState) reallyDoSomething(arg int, respondto chan&lt;- error) {

    defer close(respondto)

    // Do something
    fmt.Println("Hello, playground")
    var err error = nil
    respondto &lt;- err
}


and be called like:

for {
    switch c := (&lt;-l.command).(type) {

    case commandDoSomething:
        l.reallyDoSomething(c.arg, c.respondto)
    }
}


Note that you can remove the l.response channel completely.

Edit: Note that by dedicating a response channel for each command, you can do things like return the actual channel from the DoSomething function, like:

func (l *LibraryState) DoSomething(arg int) &lt;-chan error {

    // dedicated response channel for communication (of error type, not interface{})
    resp := make(chan error, 1)

    // Perform operation transactionally
    l.command &lt;- commandDoSomething{arg, resp}
    return resp
}


and as a consequence, "clients" can call the DoSomething method and then potentially do other work while the state is changing, and get the possible error condition later... like:

resp := DoSomething(input)
//... work on other activities
if err := &lt;-resp; err != nil {
    // handle error - perhaps undo some previous optimistic code....
}