How to apply separate Mutex on multiple variables in Golang? - go

I have multiple variables which I want to make mutually exclusive using this method
type var1WithMutex struct {
mu sync.Mutex
var1 int
}
func (v *var1) Set(value int) {
v.mu.Lock()
v.var1 = value
v.mu.Unlock()
}
func (v *var1) Get() (value int) {
v.mu.Lock()
value = v.var1
v.mu.Unlock()
return
}
Similarly there are hundreds of variable, like var1, var2, var3.... var100
How do i make all of them mutually exclusive without repeating this code?
Note that var1, var2, var3 etc are not part of an array and no way related to each other. var2 may be a int and var3 may be User{}

You could make different Mutex object for each type instead. Playground
type MutexInt struct {
sync.Mutex
v int
}
func (i *MutexInt) Get() int {
return i.v
}
func (i *MutexInt) Set(v int) {
i.v = v
}
and use it like this
func main() {
i := MutexInt{v: 0}
i.Lock()
i.Set(2)
fmt.Println(i.Get())
i.Unlock()
}

You can wrap your variables and use a shared mutex, if they all have the same interface (http://play.golang.org/p/xri2M-rtEY):
type Var interface {
Get() int
Set(n int)
}
func Sync(v Var, m *sync.RWMutex) Var {
return &syncedVar{
v: v,
m: m,
}
}
type syncedVar struct {
m *sync.RWMutex
v Var
}
func (v syncedVar) Get() int {
v.m.RLock()
defer v.m.RUnlock()
return v.v.Get()
}
func (v *syncedVar) Set(n int) {
v.m.Lock()
defer v.m.Unlock()
v.v.Set(n)
}

If your variables are primitive data types (int, float,..), use the sync.atomic package. Atomic operations do not need mutex.

Related

Add a cache to a go function as if it were a static member

Say I have an expensive function
func veryExpensiveFunction(int) int
and this function gets called a lot for the same number.
Is there a good way to allow this function to store previous results to use if the function gets called again that is perhaps even reusable for veryExpensiveFunction2?
Obviously, it would be possible to add an argument
func veryExpensiveFunctionCached(p int, cache map[int]int) int {
if val, ok := cache[p]; ok {
return val
}
result := veryExpensiveFunction(p)
cache[p] = result
return result
}
But now I have to create the cache somewhere, where I don't care about it. I would rather have it as a "static function member" if this were possible.
What is a good way to simulate a static member cache in go?
You can use closures; and let the closure manage the cache.
func InitExpensiveFuncWithCache() func(p int) int {
var cache = make(map[int]int)
return func(p int) int {
if ret, ok := cache[p]; ok {
fmt.Println("from cache")
return ret
}
// expensive computation
time.Sleep(1 * time.Second)
r := p * 2
cache[p] = r
return r
}
}
func main() {
ExpensiveFuncWithCache := InitExpensiveFuncWithCache()
fmt.Println(ExpensiveFuncWithCache(2))
fmt.Println(ExpensiveFuncWithCache(2))
}
output:
4
from cache
4
veryExpensiveFunctionCached := InitExpensiveFuncWithCache()
and use the wrapped function with your code.
You can try it here.
If you want it to be reusable, change the signature to InitExpensiveFuncWithCache(func(int) int) so it accept a function as a parameter. Wrap it in the closure, replacing the expensive computation part with it.
You need to be careful about synchronization if this cache will be used in http handlers. In Go standard lib, each http request is processed in a dedicated goroutine and at this moment we are at the domain of concurrency and race conditions. I would suggest a RWMutex to ensure data consistency.
As for the cache injection, you may inject it at a function where you create the http handler.
Here it is a prototype
type Cache struct {
store map[int]int
mux sync.RWMutex
}
func NewCache() *Cache {
return &Cache{make(map[int]int), sync.RWMutex{}}
}
func (c *Cache) Set(id, value int) {
c.mux.Lock()
c.store[id] = id
c.mux.Unlock()
}
func (c *Cache) Get(id int) (int, error) {
c.mux.RLock()
v, ok := c.store[id]
c.mux.RUnlock()
if !ok {
return -1, errors.New("a value with given key not found")
}
return v, nil
}
func handleComplexOperation(c *Cache) http.HandlerFunc {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request){
})
}
The Go standard library uses the following style for providing "static" functions (e.g. flag.CommandLine) but which leverage underlying state:
// "static" function is just a wrapper
func Lookup(p int) int { return expCache.Lookup(p) }
var expCache = NewCache()
func newCache() *CacheExpensive { return &CacheExpensive{cache: make(map[int]int)} }
type CacheExpensive struct {
l sync.RWMutex // lock for concurrent access
cache map[int]int
}
func (c *CacheExpensive) Lookup(p int) int { /*...*/ }
this design pattern not only allows for simple one-time use, but also allows for segregated usage:
var (
userX = NewCache()
userY = NewCache()
)
userX.Lookup(12)
userY.Lookup(42)

Type that describes any go function

I want to write a function that partially applies a function to an argument, like this:
func partial(f AnyFuncType, arg interface{}) AnyFuncType {
return func(args ...interface{}) interface{} {
return f(arg, args)
}
}
type AnyFuncType func(args ...interface{}) interface{}
But that doesn't work even with the simplest function like that
func sum(a int, b int) int {
return a + b
}
func main() {
addToFive := partial(sum, 5)
}
because I get
./prog.go:16:23: cannot use sum (type func(int, int) int) as type AnyFuncType in argument to partial
compilation error. Now, I know that I could use interface{}, but is there a way to specify a more precise type for f that would work with any function?
You are trying to treat interface{} as a generic type, but interface{} is not a generic type and go will not match the signature of a function that takes interface{} as the signature of a function that takes a concrete type.
The problem is, subtyping in GO works only for interaces. Since AnyFuncType is not an interface, this won't work.
Use interface{} to represent a function of any type. There is not a more precise type that works with any function.
Use the reflect package to implement partial.
func partial(f interface{}, arg interface{}) interface{} {
v := reflect.ValueOf(f)
t := v.Type()
var in []reflect.Type
for i := 1; i < t.NumIn(); i++ {
in = append(in, t.In(i))
}
var out []reflect.Type
for i := 0; i < t.NumOut(); i++ {
out = append(out, t.Out(i))
}
var va reflect.Value
if arg != nil {
va = reflect.ValueOf(arg)
} else {
// Support `nil` as partial argument.
va = reflect.Zero(t.In(0))
}
return reflect.MakeFunc(reflect.FuncOf(in, out, t.IsVariadic()),
func(args []reflect.Value) []reflect.Value {
return v.Call(append([]reflect.Value{va}, args...))
}).Interface()
}
Use it like this:
addToFive := partial(sum, 5).(func(int) int)
fmt.Println(addToFive(1))
Run it on the playground.
I recommend using a closure to create partials instead of the partial function in this answer. The closure is more efficient and avoids tricky reflect code.
addToFive := func(x int) int { return sum(5, x) }
fmt.Println(addToFive(1))

Reflect on list of interfaces

I have read several examples/questions about reflection in Go, but I'm still unable to understand what I'm supposed to do with my list of interfaces.
Below is a stripped down version of the real use case.
I have several types complying with a given interface:
type Foo interface {
Value() int
}
type bar struct {
value int
}
func (b bar) Value() int {
return b.value
}
type baz struct{}
func (b baz) Value() int {
return 42
}
I have a list of such guys
type Foos []Foo
var foos = Foos{
bar{},
baz{},
}
and I would like to traverse this list by changing the value of the members that have a value field.
for k := range foos {
change(&foos[k])
}
But I'm unable to find the right path
func change(g *Foo) {
t := reflect.TypeOf(g).Elem()
fmt.Printf("t: Kind %v, %#v\n", t.Kind(), t)
v := reflect.ValueOf(g).Elem()
fmt.Printf("v: Kind %v, %#v, %v\n", v.Kind(), v, v.CanAddr())
if f, ok := t.FieldByName("value"); ok {
fmt.Printf("f: %#v, OK: %v\n", f, ok)
vf := v.FieldByName("value")
fmt.Printf("vf: %#v: %v\n", vf, vf.CanAddr())
vf.SetInt(51)
}
}
As you can see, I'm not sure how to glue together the TypeOf and ValueOf bits...
The full example is on Go Playground.
There are a couple of issues here. First, it's not possible to set an unexported field. Here's a change to make the field exported:
type Foo interface {
// Rename Value to GetValue to avoid clash with Value field in bar
GetValue() int
}
type bar struct {
// export the field by capitalizing the name
Value int
}
func (b bar) GetValue() int {
return b.Value
}
type baz struct{}
func (b baz) GetValue() int {
return 42
}
The next issue is a bar interface value is not addressable. To fix this, use a *bar in the slice instead instead of a bar:
func (b *bar) GetValue() int {
return b.Value
}
...
var foos = Foos{
&bar{},
baz{},
}
With these changes, we can write the function to set the value:
func change(g Foo) {
v := reflect.ValueOf(g)
// Return if not a pointer to a struct.
if v.Kind() != reflect.Ptr {
return
}
v = v.Elem()
if v.Kind() != reflect.Struct {
return
}
// Set the field Value if found.
v = v.FieldByName("Value")
if !v.IsValid() {
return
}
v.SetInt(31)
}
Run it on the playground
The above answers the question, but it may not be the best solution to the actual problem. A better solution may be to define a setter interface:
type ValueSetter interface {
SetValue(i int)
}
func (b *bar) Value() int {
return b.value
}
func (b *bar) SetValue(i int) {
b.value = i
}
func change(g Foo) {
if vs, ok := g.(ValueSetter); ok {
vs.SetValue(31)
}
}
Run it on the playground
Please don't use your current approach. It has several drawbacks.
It's confusing (as you've discovered)
It's slow. Reflection is always slow.
It's inflexible. Your loop, not the type itself, must understand the capabilities of each type implementation.
Instead, just expand your interface to include a setter method--possibly an optional setter method. Then you can loop through the items and set the value for those that support it. Example:
// FooSetter is an optional interface which allows a Foo to set its value.
type FooSetter interface {
SetValue(int)
}
// SetValue implements the optional FooSetter interface for type bar.
func (b *bar) SetValue(v int) {
b.value = v
}
Then make your loop look like this:
for _, v := range foos {
if setter, ok := v.(FooSetter); ok {
setter.SetValue(51)
}
}
Now when you (or a third party user of your library) adds a type Baz that satisfies the FooSetter interface, you don't have to modify your loop at all.

Golang a map of functions with a receiver

Is there anyway to make a map of function pointers, but functions that take recievers? I know how to do it with regular functions:
package main
func someFunc(x int) int {
return x
}
func main() {
m := make(map[string]func(int)int, 0)
m["1"] = someFunc
print(m["1"](56))
}
But can you do that with functions that take recievers? Something like this (though I've tried this and it doesn't work):
package main
type someStruct struct {
x int
}
func (s someStruct) someFunc() int {
return s.x
}
func main() {
m := make(map[string](someStruct)func()int, 0)
s := someStruct{56}
m["1"] = someFunc
print(s.m["1"]())
}
An obvious work around is to just pass the struct as a parameter, but that's a little dirtier than I would have liked
You can do that using Method Expressions:
https://golang.org/ref/spec#Method_expressions
The call is a bit different, since the method expression takes the receiver as the first argument.
Here's your example modified:
package main
type someStruct struct {
x int
}
func (s someStruct) someFunc() int {
return s.x
}
func main() {
m := make(map[string]func(someStruct)int, 0)
s := someStruct{56}
m["1"] = (someStruct).someFunc
print(m["1"](s))
}
And here's a Go playground for you to test it:
https://play.golang.org/p/PLi5A9of-U

Generic method to iterate over collection (slice) of structs

I have following code in Go:
type Foo struct { Id int }
type Bar struct { Id int }
func getIdsFoo(foos []Foo) {
ids = make([]int, len(foos))
// iterate and get all ids to ids array
}
func getIdsBar(bars []Bar) {
ids = make([]int, len(bars))
// iterate and get all ids to ids array
}
Is there a clever way to create a function getIds([]Idable) that can take any struct that have method GetId() implemented?
type Identifiable interface {
GetId() int
}
func GatherIds(ys []Identifiable) []int {
xs := make([]int, 0, len(ys))
for _, i := range ys {
xs = append(xs, i.GetId())
}
return xs
}
sort uses a design patter that might help you.
Create a function that works on an slice-like interface. Then create new types based off of a slice of your concrete types.
Hopefully, the code is more clear than my description. http://play.golang.org/p/TL6yxZZUWT
type IdGetter interface {
GetId(i int) int
Len() int
}
func GetIds(ig IdGetter) []int {
ids := make([]int, ig.Len())
for i := range ids {
ids[i] = ig.GetId(i)
}
return ids
}
type Foo struct{ Id int }
type Bar struct{ Id int }
type FooIdGetter []Foo
func (f FooIdGetter) GetId(i int) int {
return f[i].Id
}
func (f FooIdGetter) Len() int {
return len(f)
}
type BarIdGetter []Bar
func (b BarIdGetter) GetId(i int) int {
return b[i].Id
}
func (b BarIdGetter) Len() int {
return len(b)
}
func main() {
var f = []Foo{{5}, {6}, {7}}
var b = []Bar{{10}, {11}, {12}}
fmt.Println("foo ids:", GetIds(FooIdGetter(f)))
fmt.Println("bar ids:", GetIds(BarIdGetter(b)))
}
There is still a bit more boilerplate than is pleasant, (Go generics... someday). It's greatest advantage is that new methods do not need to be added to Foo, Bar, or any future type you may need to work with.

Resources