Is there anything wrong with using methods as goroutines this way?
Do I need a mutex on data if Work() method only reads?
Is there a better pattern I can use to implement this kind of service.
type Worker struct {
data string
}
func (w *Worker) fetchData() {
for {
// sleep for defined period of time
// fetch the data
w.data = fetched_data
}
}
func (w *Worker) Work() {
go w.fetchData()
for {
// do some work that reads w.data
}
}
func main() {
worker := Worker{"data"}
worker.Work()
}
Related
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)
How to implement an abstract class in Go? As Go doesn't allow us to have fields in interfaces, that would be a stateless object. So, in other words, is it possible to have some kind of default implementation for a method in Go?
Consider an example:
type Daemon interface {
start(time.Duration)
doWork()
}
func (daemon *Daemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
daemon.doWork()
}
}()
}
type ConcreteDaemonA struct { foo int }
type ConcreteDaemonB struct { bar int }
func (daemon *ConcreteDaemonA) doWork() {
daemon.foo++
fmt.Println("A: ", daemon.foo)
}
func (daemon *ConcreteDaemonB) doWork() {
daemon.bar--
fmt.Println("B: ", daemon.bar)
}
func main() {
dA := new(ConcreteDaemonA)
dB := new(ConcreteDaemonB)
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
time.Sleep(100 * time.Second)
}
This won't compile as it's not possible to use interface as a receiver.
In fact, I have already answered my question (see the answer below). However, is it an idiomatic way to implement such logic? Are there any reasons not to have a default implementation besides language's simplicity?
The other answers provide an alternative to your problem, however they proposed solution without using abstract classes/struct, and I guess if you were interested in using abstract class like solution, here is very precise solution to your problem:
Go plaground
package main
import (
"fmt"
"time"
)
type Daemon interface {
start(time.Duration)
doWork()
}
type AbstractDaemon struct {
Daemon
}
func (a *AbstractDaemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
a.doWork()
}
}()
}
type ConcreteDaemonA struct {
*AbstractDaemon
foo int
}
func newConcreteDaemonA() *ConcreteDaemonA {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonA{a, 0}
a.Daemon = r
return r
}
type ConcreteDaemonB struct {
*AbstractDaemon
bar int
}
func newConcreteDaemonB() *ConcreteDaemonB {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonB{a, 0}
a.Daemon = r
return r
}
func (a *ConcreteDaemonA) doWork() {
a.foo++
fmt.Println("A: ", a.foo)
}
func (b *ConcreteDaemonB) doWork() {
b.bar--
fmt.Println("B: ", b.bar)
}
func main() {
var dA Daemon = newConcreteDaemonA()
var dB Daemon = newConcreteDaemonB()
dA.start(1 * time.Second)
dB.start(5 * time.Second)
time.Sleep(100 * time.Second)
}
If this is still not obvious how to use abstract classes/multi-inheritance in go-lang here is the post with comprehensive details. Abstract Classes In Go
If you want to provide a "default" implementation (for Daemon.start()), that is not the characteristic of an interface (at least not in Go). That is a characteristic of a concrete (non-interface) type.
So Daemon in your case should be a concrete type, conveniently a struct since you want it to have fields. And the task to be done can be either a value of an interface type, or in a simple case just a function value (a simple case means it would only have one method).
With interface type
Try the complete app on the Go Playground.
type Task interface {
doWork()
}
type Daemon struct {
task Task
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task.doWork() periodically
go func() {
for {
<-ticker.C
d.task.doWork()
}
}()
}
type MyTask struct{}
func (m MyTask) doWork() {
fmt.Println("Doing my work")
}
func main() {
d := Daemon{task: MyTask{}}
d.start(time.Millisecond*300)
time.Sleep(time.Second * 2)
}
With a function value
In this simple case this one is shorter. Try it on the Go Playground.
type Daemon struct {
task func()
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task() periodically
go func() {
for {
<-ticker.C
d.task()
}
}()
}
func main() {
d := Daemon{task: func() {
fmt.Println("Doing my work")
}}
d.start(time.Millisecond * 300)
time.Sleep(time.Second * 2)
}
An easy solution is to move daemon *Daemon to the argument list (thus removing start(...) from the interface):
type Daemon interface {
// start(time.Duration)
doWork()
}
func start(daemon Daemon, duration time.Duration) { ... }
func main() {
...
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
...
}
You can implement abstract class in go.
The definition:
type abstractObject interface{
print()
}
type object struct{
a int
abstractObject
}
Now object is an abstract class, like java's.
You can inherit it and use its members:
type concreteObject struct{
*object
}
(o *concreteObject) print() {
fmt.Println(o.a)
}
func newConcreteObject(o *object) {
obj := &concreteObject{object: o}
o.abstractObject = obj // all magics are in this statement.
}
And use the object with concreteObject's methods:
o := &object{}
newConcereteObject(o)
o.print()
And cast abstract object to concrete object:
concObj := o.abstractObject.(*concreteObject)
Just like other OOP languages.
The solution by Max Malysh would work in some cases if you don't need a factory. However the solution given by Adrian Witas could cause cyclic dependencies issues.
This is the way I achieved implementing an abstract class the easy way respecting cyclic dependencies and good factory patterns.
Let us assume we have the following package structure for our component
component
base
types.go
abstract.go
impl1
impl.go
impl2
impl.go
types.go
factory.go
Define the definition of the component, in this example it will be defined here:
component/types.go
package component
type IComponent interface{
B() int
A() int
Sum() int
Average() int
}
Now let's assume we want to create an abstract class that implements Sum and Average only, but in this abstract implementation we would like to have access to use the values returned by the implemented A and B
To achieve this, we should define another interface for the abstract members of the abstract implementation
component/base/types.go
package base
type IAbstractComponentMembers {
A() int
B() int
}
And then we can proceed to implement the abstract "class"
component/base/abstract.go
package base
type AbstractComponent struct {
IAbstractComponentsMember
}
func (a *AbstractComponent) Sum() int {
return a.A() + a.B()
}
func (a *AbstractComponent) Average() int {
return a.Sum() / 2
}
And now we proceed to the implementations
component/impl1/impl.go // Asume something similar for impl2
package impl1
type ComponentImpl1 struct {
base.AbstractComponent
}
func (c *ComponentImpl1) A() int {
return 2
}
func (c *ComponentImpl1) A() int {
return 4
}
// Here is how we would build this component
func New() *ComponentImpl1 {
impl1 := &ComponentImpl1{}
abs:=&base.AbstractComponent{
IAbstractComponentsMember: impl1,
}
impl1.AbstractComponent = abs
return impl1
}
The reason we use a separate interface for this instead of using Adrian Witas example, is because if we use the same interface in this case, if we import the base package in impl* to use the abstract "class" and also we import the impl* packages in the components package, so the factory can register them, we'll find a circular reference.
So we could have a factory implementation like this
component/factory.go
package component
// Default component implementation to use
const defaultName = "impl1"
var instance *Factory
type Factory struct {
// Map of constructors for the components
ctors map[string]func() IComponent
}
func (f *factory) New() IComponent {
ret, _ := f.Create(defaultName)
return ret
}
func (f *factory) Create(name string) (IComponent, error) {
ctor, ok := f.ctors[name]
if !ok {
return nil, errors.New("component not found")
}
return ctor(), nil
}
func (f *factory) Register(name string, constructor func() IComponent) {
f.ctors[name] = constructor
}
func Factory() *Factory {
if instance == nil {
instance = &factory{ctors: map[string]func() IComponent{}}
}
return instance
}
// Here we register the implementations in the factory
func init() {
Factory().Register("impl1", func() IComponent { return impl1.New() })
Factory().Register("impl2", func() IComponent { return impl2.New() })
}
The functionality of abstract class has below requirements
1. It should not be possible to create direct instance of abstract class
2. It should provide default fields and methods.
A combination of interface and struct can be used to fulfill above two requirements. For example we can see below
package main
import "fmt"
//Abstract Interface
type iAlpha interface {
work()
common(iAlpha)
}
//Abstract Concrete Type
type alpha struct {
name string
}
func (a *alpha) common(i iAlpha) {
fmt.Println("common called")
i.work()
}
//Implementing Type
type beta struct {
alpha
}
func (b *beta) work() {
fmt.Println("work called")
fmt.Printf("Name is %s\n", b.name)
}
func main() {
a := alpha{name: "test"}
b := &beta{alpha: a}
b.common(b)
}
Output:
common called
work called
Name is test
One important point to mention here is that all default method should have iAlpha as first argument, and if default method needs to call any unimplemented method they they will call on this interface. This is same as we did in common method above - i.work().
Source: https://golangbyexample.com/go-abstract-class/
Suppose I have the following struct:
package manager
type Manager struct {
strings []string
}
func (m *Manager) AddString(s string) {
m.strings = append(m.strings, s)
}
func (m *Manager) RemoveString(s string) {
for i, str := range m.strings {
if str == s {
m.strings = append(m.strings[:i], m.strings[i+1:]...)
}
}
}
This pattern is not thread safe, so the following test fails due to some race condition (array index out of bounds):
func TestManagerConcurrently(t *testing.T) {
m := &manager.Manager{}
wg := sync.WaitGroup{}
for i:=0; i<100; i++ {
wg.Add(1)
go func () {
m.AddString("a")
m.AddString("b")
m.AddString("c")
m.RemoveString("b")
wg.Done()
} ()
}
wg.Wait()
fmt.Println(m)
}
I'm new to Go, and from googling around I suppose I should use channels (?). So one way to make this concurrent would be like this:
type ManagerA struct {
Manager
addStringChan chan string
removeStringChan chan string
}
func NewManagerA() *ManagerA {
ma := &ManagerA{
addStringChan: make(chan string),
removeStringChan: make(chan string),
}
go func () {
for {
select {
case msg := <-ma.addStringChan:
ma.AddString(msg)
case msg := <-ma.removeStringChan:
ma.RemoveString(msg)
}
}
}()
return ma
}
func (m* ManagerA) AddStringA(s string) {
m.addStringChan <- s
}
func (m* ManagerA) RemoveStringA(s string) {
m.removeStringChan <- s
}
I would like to expose an API similar to the non-concurrent example, hence AddStringA, RemoveStringA.
This seems to work as expected concurrently (although I guess the inner goroutine should also exit at some point). My problem with this is that there is a lot of extra boilerplate:
need to define & initialize channels
define inner goroutine loop with select
map functions to channel calls
It seems a bit much to me. Is there a way to simplify this (refactor / syntax / library)?
I think the best way to implement this would be to use a Mutex instead? But is it still possible to simplify this sort of boilerplate?
Using a mutex would be perfectly idiomatic like this:
type Manager struct {
mu sync.Mutex
strings []string
}
func (m *Manager) AddString(s string) {
m.mu.Lock()
m.strings = append(m.strings, s)
m.mu.Unlock()
}
func (m *Manager) RemoveString(s string) {
m.mu.Lock()
for i, str := range m.strings {
if str == s {
m.strings = append(m.strings[:i], m.strings[i+1:]...)
}
}
m.mu.Unlock()
}
You could do this with channels, but as you noted it is a lot of extra work for not much gain. Just use a mutex is my advice!
If you simply need to make the access to the struct thread-safe, use mutex:
type Manager struct {
sync.Mutex
data []string
}
func (m *Manager) AddString(s string) {
m.Lock()
m.strings = append(m.strings, s)
m.Unlock()
}
1) How does golang solve visibility issue?
2) Is there any issues with below code?
package main
type Service struct {
stop bool
}
func (s *Service) Run() {
for !s.stop {
//Some logic
}
}
func (s *Service) Stop() {
s.stop = true
}
func main() {
s := &Service{}
go s.Run()
//Some logic
s.Stop()
}
I recommend to use context.WithCancel to stop goroutines in this case.
This question appears to be a duplicate of Can embedded methods access "parent" fields?, but it is not in the sense that I know that there is no way to access the "parent" fields; I am just looking for suggestions on another way to do this, because I like the idea of the Pausable struct.
I am trying to make a convenience struct that enables other structs to receive some pausing/unpausing methods.
Imagine the following:
Pausable struct
type Pausable struct {
isPaused bool
}
func (p *Pausable) Pause() {
p.isPaused = true
}
func (p *Pausable) Unpause() {
p.isPaused = false
}
Struct that composes with Pausable
Now on my other struct I want to overwrite the Unpause() method, so that besides changing the value of p.isPaused some other stuff happens as well.
type Mystruct struct {
Pausable // Composition
}
func (s *Mystruct) Unpause() {
s.Unpause()
// Do other stuff
}
Problem
The problem becomes this. I want to add an PauseUntil() method to the Pausable struct, so that it becomes
type Pausable struct {
isPaused bool
}
func (p *Pausable) Pause() {
p.isPaused = true
}
func (p *Pausable) Unpause() {
p.isPaused = false
}
func (p *Pausable) PauseUntil(dur time.Duration) {
p.Pause()
go func() {
time.Sleep(dur)
p.Unpause()
}()
}
When the timeout runs out, however, Unpause() is called on Pausable, and not on Mystruct. What would be a clever way around this?
You could make PauseUntil a function that operates on a Pauser interface.
E.g.
type Pauser interface {
Pause()
Unpause()
}
func PauseUntil(p Pauser) {
p.Pause()
go func() {
time.Sleep(dur)
p.Unpause()
}()
}
Then you should be able to pass your myStruct to that function:
ms := new(myStruct)
PauseUntil(ms)