Skip to content

Instantly share code, notes, and snippets.

@arielsrv
Created October 17, 2022 15:00
Show Gist options
  • Save arielsrv/d5a44d8c930dde1b01b9ed25c9d51db9 to your computer and use it in GitHub Desktop.
Save arielsrv/d5a44d8c930dde1b01b9ed25c9d51db9 to your computer and use it in GitHub Desktop.
futures
package main
import (
"container/list"
"fmt"
"github.com/tjarratt/babble"
"sync"
"sync/atomic"
"unsafe"
)
func main() {
var f [20000]*FutureMessage
ForkJoin(func(c *Concurrent) {
for i := 0; i < len(f); i++ {
f[i] = c.Get()
}
})
for i := range f {
fmt.Println(f[i].Response().Value)
}
}
type Message struct {
Value string
}
type BlockingStruct struct {
babbler babble.Babbler
}
func NewExecutor() *BlockingStruct {
return &BlockingStruct{babbler: babble.NewBabbler()}
}
func (blockingStruct *BlockingStruct) GetMessage() *Message {
return &Message{Value: blockingStruct.babbler.Babble()}
}
var executor = NewExecutor()
type Concurrent struct {
list list.List
wg sync.WaitGroup
executor *BlockingStruct
}
func (c *Concurrent) Get() *FutureMessage {
fm := new(FutureMessage)
future := func() {
defer c.wg.Done()
message := c.executor.GetMessage()
atomic.StorePointer(&fm.pointer, unsafe.Pointer(message))
}
c.list.PushBack(future)
return fm
}
type FutureMessage struct {
pointer unsafe.Pointer
}
func (fm *FutureMessage) Response() *Message {
return (*Message)(fm.pointer)
}
func ForkJoin(f func(*Concurrent)) {
executor.ForkJoin(f)
}
func (blockingStruct *BlockingStruct) ForkJoin(f func(*Concurrent)) {
c := new(Concurrent)
c.executor = blockingStruct
f(c)
c.wg.Add(c.list.Len())
for node := c.list.Front(); node != nil; node = node.Next() {
go node.Value.(func())()
}
c.wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment